summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-22 23:12:33 +0000
committerjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-22 23:12:33 +0000
commitcfe5c1375a0dafe47ffb4b9223d33253fc01e8fa (patch)
tree15e23a948bbec2ee6b20d9a95645a477279e7bf9
parentddf8a4b03ca007cc55ead2000aa6b54d0319cd56 (diff)
downloadchromium_src-cfe5c1375a0dafe47ffb4b9223d33253fc01e8fa.zip
chromium_src-cfe5c1375a0dafe47ffb4b9223d33253fc01e8fa.tar.gz
chromium_src-cfe5c1375a0dafe47ffb4b9223d33253fc01e8fa.tar.bz2
Porting the app launcher to Windows, and adding an experimental flag
so the app launcher shows when you open a new tab. Also removing the graying-out of the browser when the app launcher is showng for now, as it is not clear how to make it cross-platform. BUG=None TEST=Start Chrome with --app-launcher-new-tab. Opening a new tab should bring the app launcher (still a prototype at this point). Review URL: http://codereview.chromium.org/1145001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42280 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.cc8
-rw-r--r--chrome/browser/chromeos/app_launcher.cc495
-rw-r--r--chrome/browser/chromeos/frame/browser_view.cc8
-rw-r--r--chrome/browser/chromeos/frame/browser_view.h6
-rw-r--r--chrome/browser/views/app_launcher.cc520
-rw-r--r--chrome/browser/views/app_launcher.h (renamed from chrome/browser/chromeos/app_launcher.h)153
-rw-r--r--chrome/browser/views/info_bubble.cc2
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc18
-rw-r--r--chrome/browser/views/tabs/tab_strip.h7
-rwxr-xr-xchrome/chrome_browser.gypi6
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
12 files changed, 595 insertions, 632 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index f2779af..d384107 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -98,6 +98,7 @@
#include "chrome/browser/task_manager.h"
#include "chrome/browser/user_data_manager.h"
#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/app_launcher.h"
#include "chrome/browser/views/location_bar_view.h"
#endif // OS_WIN
@@ -1028,6 +1029,13 @@ void Browser::CloseWindow() {
void Browser::NewTab() {
UserMetrics::RecordAction("NewTab", profile_);
+#if defined(OS_WIN)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAppLauncherForNewTab)) {
+ AppLauncher::Show(this);
+ return;
+ }
+#endif
if (type() == TYPE_NORMAL) {
AddBlankTab(true);
} else {
diff --git a/chrome/browser/chromeos/app_launcher.cc b/chrome/browser/chromeos/app_launcher.cc
deleted file mode 100644
index d3e3fef..0000000
--- a/chrome/browser/chromeos/app_launcher.cc
+++ /dev/null
@@ -1,495 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/app_launcher.h"
-
-#include <string>
-#include <vector>
-
-#include "app/gfx/canvas.h"
-#include "app/resource_bundle.h"
-#include "base/command_line.h"
-#include "base/message_loop.h"
-#include "base/string_util.h"
-#include "chrome/browser/autocomplete/autocomplete_edit.h"
-#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_window.h"
-#include "chrome/browser/bubble_positioner.h"
-#include "chrome/browser/chromeos/frame/browser_view.h"
-#include "chrome/browser/chromeos/status/status_area_view.h"
-#include "chrome/browser/chromeos/wm_ipc.h"
-#include "chrome/browser/in_process_webkit/dom_storage_context.h"
-#include "chrome/browser/in_process_webkit/webkit_context.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/render_view_host_factory.h"
-#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
-#include "chrome/browser/renderer_host/site_instance.h"
-#include "chrome/browser/renderer_preferences_util.h"
-#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/views/bubble_border.h"
-#include "gfx/insets.h"
-#include "gfx/point.h"
-#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "views/background.h"
-#include "views/controls/native/native_view_host.h"
-#include "views/painter.h"
-#include "views/screen.h"
-#include "views/widget/root_view.h"
-#include "views/widget/widget_gtk.h"
-
-namespace {
-
-// Padding & margins for the navigation entry.
-const int kNavigationEntryPadding = 2;
-const int kNavigationEntryXMargin = 3;
-const int kNavigationEntryYMargin = 1;
-
-// NavigationBar size.
-const int kNavigationBarHeight = 25;
-
-// Padding for the bubble info window.
-const int kBubbleWindowXPadding = 6;
-const int kBubbleWindowYPadding = 16;
-
-// Command line switch for specifying url of the page.
-const wchar_t kURLSwitch[] = L"main-menu-url";
-
-// Command line switch for specifying the size of the main menu. The default is
-// full screen.
-const wchar_t kMenuSizeSwitch[] = L"main-menu-size";
-
-// URL of the page to load. This is ignored if kURLSwitch is specified.
-const char kMenuURL[] = "http://goto.ext.google.com/crux-home";
-
-// Returns the URL of the menu.
-static GURL GetMenuURL() {
- std::wstring url_string =
- CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch);
- if (!url_string.empty())
- return GURL(WideToUTF8(url_string));
- return GURL(kMenuURL);
-}
-
-// RenderWidgetHostViewGtk propagates the mouse press events (see
-// render_widget_host_view_gtk.cc). We subclass to stop the propagation here,
-// as if the click event was propagated it would reach the TopContainer view and
-// it would close the popup.
-class RWHVNativeViewHost : public views::NativeViewHost {
- public:
- RWHVNativeViewHost() {}
-
- virtual bool OnMousePressed(const views::MouseEvent& event) { return true; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RWHVNativeViewHost);
-};
-
-} // namspace
-
-namespace chromeos {
-
-////////////////////////////////////////////////////////////////////////////////
-// NavigationBar
-//
-// A navigation bar that is shown in the app launcher in compact navigation bar
-// mode.
-
-class NavigationBar : public views::View,
- public AutocompleteEditController,
- public BubblePositioner {
- public:
- explicit NavigationBar(AppLauncher* app_launcher)
- : views::View(),
- app_launcher_(app_launcher),
- location_entry_view_(NULL) {
- SetFocusable(true);
- location_entry_view_ = new views::NativeViewHost;
- AddChildView(location_entry_view_);
- }
-
- virtual ~NavigationBar() {
- if (location_entry_view_->native_view())
- location_entry_view_->Detach();
- }
-
- // views::View overrides.
- virtual void Focus() {
- location_entry_->SetFocus();
- location_entry_->SelectAll(true);
- }
-
- virtual void Layout() {
- gfx::Rect bounds = GetLocalBounds(false);
-
- const int vertical_margin =
- kNavigationEntryPadding + kNavigationEntryYMargin;
-
- location_entry_view_->SetBounds(
- bounds.x() + kNavigationEntryXMargin + kNavigationEntryPadding,
- bounds.y() + vertical_margin,
- bounds.width() - 2 * (kNavigationEntryPadding +
- kNavigationEntryXMargin),
- bounds.height() - vertical_margin * 2);
- }
-
- virtual void Paint(gfx::Canvas* canvas) {
- const int padding = kNavigationEntryPadding;
- canvas->FillRectInt(SK_ColorWHITE, 0, 0, width(), height());
- // Draw border around the entry.
- gfx::Rect bounds = location_entry_view_->GetBounds(
- views::View::APPLY_MIRRORING_TRANSFORMATION);
- canvas->DrawRectInt(SK_ColorGRAY,
- bounds.x() - padding,
- bounds.y() - padding,
- bounds.width() + padding * 2,
- bounds.height() + padding * 2);
- }
-
- // BubblePositioner implementation.
- virtual gfx::Rect GetLocationStackBounds() const {
- gfx::Rect bounds = location_entry_view_->GetBounds(
- views::View::APPLY_MIRRORING_TRANSFORMATION);
- gfx::Point origin(bounds.x(), bounds.bottom() + kNavigationEntryPadding);
- views::View::ConvertPointToScreen(this, &origin);
- gfx::Rect rect = gfx::Rect(origin, gfx::Size(500, 0));
- if (UILayoutIsRightToLeft()) {
- // Align the window to the right side of the entry view when
- // UI is RTL mode.
- rect.set_x(rect.x() - (rect.width() - location_entry_view_->width()));
- }
- return rect;
- }
-
- // AutocompleteController implementation.
- virtual void OnAutocompleteAccept(const GURL& url,
- WindowOpenDisposition disposition,
- PageTransition::Type transition,
- const GURL& alternate_nav_url) {
- app_launcher_->AddTabWithURL(url, transition);
- app_launcher_->Hide();
- }
- virtual void OnChanged() {}
- virtual void OnInputInProgress(bool in_progress) {}
- virtual void OnKillFocus() {}
- virtual void OnSetFocus() {
- views::FocusManager* focus_manager = GetFocusManager();
- if (!focus_manager) {
- NOTREACHED();
- return;
- }
- focus_manager->SetFocusedView(this);
- }
- virtual SkBitmap GetFavIcon() const {
- return SkBitmap();
- }
- virtual std::wstring GetTitle() const {
- return std::wstring();
- }
-
- // AutocompleteEditView depends on the browser instance.
- // Create new one when the browser instance changes.
- void Update(Browser* browser) {
- // Detach the native view if any.
- if (location_entry_view_ && location_entry_view_->native_view())
- location_entry_view_->Detach();
-
- location_entry_.reset(new AutocompleteEditViewGtk(
- this, browser->toolbar_model(), browser->profile(),
- browser->command_updater(), false, this));
- location_entry_->Init();
- gtk_widget_show_all(location_entry_->widget());
- gtk_widget_hide(location_entry_->widget());
-
- location_entry_view_->set_focus_view(this);
- location_entry_view_->Attach(location_entry_->widget());
- }
-
- private:
- AppLauncher* app_launcher_;
- views::NativeViewHost* location_entry_view_;
- scoped_ptr<AutocompleteEditViewGtk> location_entry_;
-
- DISALLOW_COPY_AND_ASSIGN(NavigationBar);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// TopContainer
-//
-// A view that grays-out the browser and contains the navigation bar and
-// renderer view.
-
-AppLauncher::TopContainer::TopContainer(AppLauncher* app_launcher)
- : app_launcher_(app_launcher) {
- // Use a transparent black background so the browser appears grayed-out.
- set_background(views::Background::CreateSolidBackground(0, 0, 0, 100));
-}
-
-void AppLauncher::TopContainer::Layout() {
- if (bounds().IsEmpty())
- return;
-
- // We only expect to contain the BubbleContents.
- DCHECK(GetChildViewCount() == 1);
- GetChildViewAt(0)->SetBounds(kBubbleWindowXPadding, kBubbleWindowYPadding,
- width() * 2 / 3, height() * 4 / 5);
-}
-
-bool AppLauncher::TopContainer::OnMousePressed(const views::MouseEvent& event) {
- // Clicking outside the bubble closes the bubble.
- app_launcher_->Hide();
- return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BubbleContainer
-//
-// The view that contains the navigation bar and render view. It has a bubble
-// border.
-
-AppLauncher::BubbleContainer::BubbleContainer(AppLauncher* app_launcher)
- : app_launcher_(app_launcher) {
- BubbleBorder* bubble_border = new BubbleBorder();
- bubble_border->set_arrow_location(BubbleBorder::TOP_LEFT);
- set_border(bubble_border);
- set_background(new BubbleBackground(bubble_border));
-}
-
-void AppLauncher::BubbleContainer::Layout() {
- if (bounds().IsEmpty() || GetChildViewCount() == 0)
- return;
-
- gfx::Rect bounds = GetLocalBounds(false);
- // TODO(jcampan): figure-out why we need to inset for the contained view not
- // to paint over the bubble border.
- bounds.Inset(2, 2);
-
- app_launcher_->navigation_bar_->SetBounds(bounds.x(), bounds.y(),
- bounds.width(),
- kNavigationBarHeight);
- int render_y = app_launcher_->navigation_bar_->bounds().bottom();
- gfx::Size rwhv_size =
- gfx::Size(bounds.width(),
- std::max(0, bounds.height() - render_y + bounds.y()));
- app_launcher_->render_view_container_->SetBounds(bounds.x(), render_y,
- rwhv_size.width(),
- rwhv_size.height());
- app_launcher_->rwhv_->SetSize(rwhv_size);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// AppLauncher
-
-AppLauncher::AppLauncher(Browser* browser)
- : browser_(browser),
- popup_(NULL),
- site_instance_(NULL),
- contents_rvh_(NULL),
- rwhv_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
- top_container_(NULL),
- bubble_container_(NULL),
- navigation_bar_(NULL),
- render_view_container_(NULL),
- has_shown_(false) {
- popup_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
- // The background image has transparency, so we make the window transparent.
- popup_->MakeTransparent();
- popup_->Init(NULL, gfx::Rect());
- WmIpc::instance()->SetWindowType(
- popup_->GetNativeView(),
- WmIpc::WINDOW_TYPE_CHROME_INFO_BUBBLE,
- NULL);
-
- // Register Esc as an accelerator for closing the app launcher.
- views::FocusManager* focus_manager = popup_->GetFocusManager();
- focus_manager->RegisterAccelerator(views::Accelerator(base::VKEY_ESCAPE,
- false, false, false),
- this);
-
- top_container_ = new TopContainer(this);
- popup_->SetContentsView(top_container_);
-
- bubble_container_ = new BubbleContainer(this);
- top_container_->AddChildView(bubble_container_);
- navigation_bar_ = new NavigationBar(this);
- bubble_container_->AddChildView(navigation_bar_);
-
- GURL menu_url(GetMenuURL());
- DCHECK(BrowserList::begin() != BrowserList::end());
- // TODO(sky): this shouldn't pick a random profile to use.
- Profile* profile = (*BrowserList::begin())->profile();
- int64 session_storage_namespace_id = profile->GetWebKitContext()->
- dom_storage_context()->AllocateSessionStorageNamespaceId();
- site_instance_ = SiteInstance::CreateSiteInstanceForURL(profile, menu_url);
- contents_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE,
- session_storage_namespace_id);
-
- rwhv_ = new RenderWidgetHostViewGtk(contents_rvh_);
- rwhv_->InitAsChild();
- contents_rvh_->CreateRenderView(profile->GetRequestContext());
-
- render_view_container_ = new RWHVNativeViewHost;
- bubble_container_->AddChildView(render_view_container_);
- render_view_container_->Attach(rwhv_->GetNativeView());
- contents_rvh_->NavigateToURL(menu_url);
-
- navigation_bar_->Update(browser);
- // Set the transient window so that ChromeOS WM treat this
- // as if a popup window.
- gtk_window_set_transient_for(
- GTK_WINDOW(popup_->GetNativeView()),
- GTK_WINDOW(browser_->window()->GetNativeHandle()));
-
- ActiveWindowWatcherX::AddObserver(this);
-}
-
-AppLauncher::~AppLauncher() {
- contents_rvh_->Shutdown();
- popup_->CloseNow();
- ActiveWindowWatcherX::RemoveObserver(this);
-}
-
-void AppLauncher::Update() {
- popup_->SetBounds(browser_->window()->GetRestoredBounds());
- top_container_->Layout();
-}
-
-void AppLauncher::Show() {
- Cleanup();
-
- Update();
- popup_->Show();
-
- GtkWidget* rwhv_widget = rwhv_->GetNativeView();
- if (!has_shown_) {
- has_shown_ = true;
- gtk_widget_realize(rwhv_widget);
- }
-}
-
-void AppLauncher::ActiveWindowChanged(GdkWindow* active_window) {
- if (!popup_->IsActive())
- Hide();
- else
- navigation_bar_->RequestFocus();
-}
-
-bool AppLauncher::AcceleratorPressed(const views::Accelerator& accelerator) {
- DCHECK(accelerator.GetKeyCode() == base::VKEY_ESCAPE);
- popup_->Hide();
- return true;
-}
-
-void AppLauncher::Hide() {
- popup_->Hide();
- // The stack may have pending_contents_ on it. Delay deleting the
- // pending_contents_ as TabContents doesn't deal well with being deleted
- // while on the stack.
- MessageLoop::current()->PostTask(FROM_HERE,
- method_factory_.NewRunnableMethod(&AppLauncher::Cleanup));
-}
-
-void AppLauncher::Cleanup() {
- pending_contents_.reset(NULL);
- method_factory_.RevokeAll();
-}
-
-void AppLauncher::RequestMove(const gfx::Rect& new_bounds) {
- // Invoking PositionChild results in a gtk signal that triggers attempting to
- // to resize the window. We need to set the size request so that it resizes
- // correctly when this happens.
- gtk_widget_set_size_request(popup_->GetNativeView(),
- new_bounds.width(), new_bounds.height());
- popup_->SetBounds(new_bounds);
-}
-
-RendererPreferences AppLauncher::GetRendererPrefs(Profile* profile) const {
- RendererPreferences preferences;
- renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile);
- return preferences;
-}
-
-void AppLauncher::AddTabWithURL(const GURL& url,
- PageTransition::Type transition) {
- switch (StatusAreaView::GetOpenTabsMode()) {
- case StatusAreaView::OPEN_TABS_ON_LEFT: {
- // Add the new tab at the first non-pinned location.
- int index = browser_->tabstrip_model()->IndexOfFirstNonMiniTab();
- browser_->AddTabWithURL(url, GURL(), transition,
- true, index, true, NULL);
- break;
- }
- case StatusAreaView::OPEN_TABS_CLOBBER: {
- browser_->GetSelectedTabContents()->controller().LoadURL(
- url, GURL(), transition);
- break;
- }
- case StatusAreaView::OPEN_TABS_ON_RIGHT: {
- browser_->AddTabWithURL(url, GURL(), transition, true, -1, true, NULL);
- break;
- }
- }
-}
-
-void AppLauncher::CreateNewWindow(int route_id) {
- if (pending_contents_.get()) {
- NOTREACHED();
- return;
- }
-
- helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
- DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())),
- NULL);
- pending_contents_.reset(helper_.GetCreatedWindow(route_id));
- pending_contents_->set_delegate(&tab_contents_delegate_);
-}
-
-void AppLauncher::ShowCreatedWindow(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
- if (disposition == NEW_POPUP) {
- pending_contents_->set_delegate(NULL);
- browser_->GetSelectedTabContents()->AddNewContents(
- pending_contents_.release(), disposition, initial_pos, user_gesture);
- Hide();
- }
-}
-
-void AppLauncher::StartDragging(const WebDropData& drop_data,
- WebKit::WebDragOperationsMask allowed_ops,
- const SkBitmap& image,
- const gfx::Point& image_offset) {
- // We're not going to do any drag & drop, but we have to tell the renderer the
- // drag & drop ended, othewise the renderer thinks the drag operation is
- // underway and mouse events won't work.
- contents_rvh_->DragSourceSystemDragEnded();
-}
-
-AppLauncher::TabContentsDelegateImpl::TabContentsDelegateImpl(
- AppLauncher* app_launcher)
- : app_launcher_(app_launcher) {
-}
-
-void AppLauncher::TabContentsDelegateImpl::OpenURLFromTab(
- TabContents* source,
- const GURL& url,
- const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition) {
- app_launcher_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
- PageTransition::LINK);
- app_launcher_->Hide();
-}
-
-} // namespace chromeos
diff --git a/chrome/browser/chromeos/frame/browser_view.cc b/chrome/browser/chromeos/frame/browser_view.cc
index f5cd791..a8040ad0 100644
--- a/chrome/browser/chromeos/frame/browser_view.cc
+++ b/chrome/browser/chromeos/frame/browser_view.cc
@@ -11,7 +11,6 @@
#include "app/menus/simple_menu_model.h"
#include "app/theme_provider.h"
#include "chrome/app/chrome_dll_resource.h"
-#include "chrome/browser/chromeos/app_launcher.h"
#include "chrome/browser/chromeos/compact_location_bar_host.h"
#include "chrome/browser/chromeos/compact_navigation_bar.h"
#include "chrome/browser/chromeos/frame/panel_browser_view.h"
@@ -20,6 +19,7 @@
#include "chrome/browser/chromeos/status/status_area_button.h"
#include "chrome/browser/chromeos/wm_ipc.h"
#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/app_launcher.h"
#include "chrome/browser/views/frame/browser_extender.h"
#include "chrome/browser/views/frame/browser_frame_gtk.h"
#include "chrome/browser/views/frame/browser_view.h"
@@ -338,7 +338,6 @@ class BrowserViewLayout : public ::BrowserViewLayout {
BrowserView::BrowserView(Browser* browser)
: ::BrowserView(browser),
- main_menu_(NULL),
main_menu_button_(NULL),
status_area_(NULL),
compact_navigation_bar_(NULL),
@@ -458,10 +457,7 @@ void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) {
// views::ButtonListener overrides.
void BrowserView::ButtonPressed(views::Button* sender,
const views::Event& event) {
- if (!main_menu_.get()) {
- main_menu_.reset(new AppLauncher(browser()));
- }
- main_menu_->Show();
+ AppLauncher::Show(browser());
}
// views::ContextMenuController overrides.
diff --git a/chrome/browser/chromeos/frame/browser_view.h b/chrome/browser/chromeos/frame/browser_view.h
index 44a4ccd..7f38d95 100644
--- a/chrome/browser/chromeos/frame/browser_view.h
+++ b/chrome/browser/chromeos/frame/browser_view.h
@@ -28,13 +28,12 @@ class BrowserStatusAreaView;
class CompactLocationBar;
class CompactLocationBarHost;
class CompactNavigationBar;
-class AppLauncher;
class StatusAreaButton;
// chromeos::BrowserView adds ChromeOS specific controls and menus to a
// BrowserView created with Browser::TYPE_NORMAL. This extender adds controls
// to the title bar as follows:
-// ____ __ __
+// ____ __ __
// [AppLauncher] / \ \ \ [StatusArea]
//
// and adds the system context menu to the remaining arae of the titlebar.
@@ -96,9 +95,6 @@ class BrowserView : public ::BrowserView,
private:
void InitSystemMenu();
- // AppLauncher instance.
- scoped_ptr<AppLauncher> main_menu_;
-
// AppLauncher button.
views::ImageButton* main_menu_button_;
diff --git a/chrome/browser/views/app_launcher.cc b/chrome/browser/views/app_launcher.cc
new file mode 100644
index 0000000..d787f16
--- /dev/null
+++ b/chrome/browser/views/app_launcher.cc
@@ -0,0 +1,520 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/app_launcher.h"
+
+#include <string>
+#include <vector>
+
+#include "app/resource_bundle.h"
+#include "base/command_line.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/task.h"
+#include "chrome/browser/autocomplete/autocomplete_edit.h"
+#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/bubble_positioner.h"
+#include "chrome/browser/in_process_webkit/webkit_context.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_view_host_factory.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/browser/renderer_host/site_instance.h"
+#include "chrome/browser/renderer_preferences_util.h"
+#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/views/info_bubble.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "views/controls/native/native_view_host.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h"
+#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
+#elif defined(OS_LINUX)
+#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
+#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
+#endif
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/status/status_area_view.h"
+#endif
+
+namespace {
+
+// Padding & margins for the navigation entry.
+const int kNavigationEntryPadding = 2;
+const int kNavigationEntryXMargin = 3;
+const int kNavigationEntryYMargin = 1;
+
+// NavigationBar size.
+const int kNavigationBarHeight = 25;
+
+// The delta applied to the default font size for the omnibox.
+const int kAutocompleteEditFontDelta = 3;
+
+// Command line switch for specifying url of the page.
+const wchar_t kURLSwitch[] = L"main-menu-url";
+
+// URL of the page to load. This is ignored if kURLSwitch is specified.
+const char kMenuURL[] = "http://goto.ext.google.com/crux-home";
+
+// Returns the URL of the menu.
+static GURL GetMenuURL() {
+ std::wstring url_string =
+ CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch);
+ if (!url_string.empty())
+ return GURL(WideToUTF8(url_string));
+ return GURL(kMenuURL);
+}
+
+// RenderWidgetHostViewGtk propagates the mouse press events (see
+// render_widget_host_view_gtk.cc). We subclass to stop the propagation here,
+// as if the click event was propagated it would reach the TopContainer view and
+// it would close the popup.
+class RWHVNativeViewHost : public views::NativeViewHost {
+ public:
+ RWHVNativeViewHost() {}
+
+ virtual bool OnMousePressed(const views::MouseEvent& event) { return true; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RWHVNativeViewHost);
+};
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// TabContentsDelegateImpl
+//
+// TabContentsDelegate and RenderViewHostDelegate::View have some methods
+// in common (with differing signatures). The TabContentsDelegate methods are
+// implemented by this class.
+
+class TabContentsDelegateImpl : public TabContentsDelegate {
+ public:
+ explicit TabContentsDelegateImpl(AppLauncher* app_launcher);
+
+ // TabContentsDelegate.
+ virtual void OpenURLFromTab(TabContents* source,
+ const GURL& url, const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition);
+ virtual void NavigationStateChanged(const TabContents* source,
+ unsigned changed_flags) {}
+ virtual void AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {}
+ virtual void ActivateContents(TabContents* contents) {}
+ virtual void LoadingStateChanged(TabContents* source) {}
+ virtual void CloseContents(TabContents* source) {}
+ virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {}
+ virtual bool IsPopup(TabContents* source) { return false; }
+ virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {}
+ virtual void URLStarredChanged(TabContents* source, bool starred) {}
+ virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
+
+ private:
+ AppLauncher* app_launcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl);
+};
+
+TabContentsDelegateImpl::TabContentsDelegateImpl(AppLauncher* app_launcher)
+ : app_launcher_(app_launcher) {
+}
+
+void TabContentsDelegateImpl::OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) {
+ app_launcher_->browser()->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
+ PageTransition::LINK);
+ app_launcher_->Hide();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NavigationBar
+//
+// A navigation bar that is shown in the app launcher in compact navigation bar
+// mode.
+
+class NavigationBar : public views::View,
+ public AutocompleteEditController,
+ public BubblePositioner {
+ public:
+ explicit NavigationBar(AppLauncher* app_launcher)
+ : app_launcher_(app_launcher),
+ location_entry_view_(NULL) {
+ SetFocusable(true);
+ location_entry_view_ = new views::NativeViewHost;
+ AddChildView(location_entry_view_);
+ set_border(views::Border::CreateSolidBorder(1, SK_ColorGRAY));
+ }
+
+ virtual ~NavigationBar() {
+ if (location_entry_view_->native_view())
+ location_entry_view_->Detach();
+ }
+
+ // views::View overrides.
+ virtual void Focus() {
+ location_entry_->SetFocus();
+ location_entry_->SelectAll(true);
+ }
+
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (!is_add || child != this)
+ return;
+
+ DCHECK(!location_entry_.get());
+
+ Browser* browser = app_launcher_->browser();
+#if defined (OS_WIN)
+ gfx::Font font;
+ font = font.DeriveFont(kAutocompleteEditFontDelta);
+ AutocompleteEditViewWin* autocomplete_view =
+ new AutocompleteEditViewWin(font, this, browser->toolbar_model(),
+ this, GetWidget()->GetNativeView(),
+ browser->profile(),
+ browser->command_updater(), false, this);
+ location_entry_.reset(autocomplete_view);
+ autocomplete_view->Update(NULL);
+ // The Update call above sets the autocomplete text to the current one in
+ // the location bar, make sure to clear it.
+ autocomplete_view->SetUserText(std::wstring());
+#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
+ AutocompleteEditViewGtk* autocomplete_view =
+ new AutocompleteEditViewGtk(this, browser->toolbar_model(),
+ browser->profile(),
+ browser->command_updater(), false, this);
+ autocomplete_view->Init();
+ gtk_widget_show_all(autocomplete_view->widget());
+ gtk_widget_hide(autocomplete_view->widget());
+ location_entry_.reset(autocomplete_view);
+#else
+ NOTIMPLEMENTED();
+#endif
+ location_entry_view_->set_focus_view(this);
+ location_entry_view_->Attach(location_entry_->GetNativeView());
+ }
+
+ virtual void Layout() {
+ gfx::Rect bounds = GetLocalBounds(false);
+ location_entry_view_->SetBounds(
+ bounds.x() + kNavigationEntryXMargin + kNavigationEntryPadding,
+ bounds.y() + kNavigationEntryYMargin,
+ bounds.width() - 2 * (kNavigationEntryPadding +
+ kNavigationEntryXMargin),
+ bounds.height() - kNavigationEntryYMargin * 2);
+ }
+
+ // BubblePositioner implementation.
+ virtual gfx::Rect GetLocationStackBounds() const {
+ gfx::Rect bounds = location_entry_view_->GetBounds(
+ views::View::APPLY_MIRRORING_TRANSFORMATION);
+ gfx::Point origin(bounds.x(), bounds.bottom() + kNavigationEntryPadding);
+ views::View::ConvertPointToScreen(this, &origin);
+ gfx::Rect rect = gfx::Rect(origin, gfx::Size(500, 0));
+ if (UILayoutIsRightToLeft()) {
+ // Align the window to the right side of the entry view when
+ // UI is RTL mode.
+ rect.set_x(rect.x() - (rect.width() - location_entry_view_->width()));
+ }
+ return rect;
+ }
+
+ // AutocompleteController implementation.
+ virtual void OnAutocompleteAccept(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url) {
+ app_launcher_->AddTabWithURL(url, transition);
+ app_launcher_->Hide();
+ }
+ virtual void OnChanged() {}
+ virtual void OnInputInProgress(bool in_progress) {}
+ virtual void OnKillFocus() {}
+ virtual void OnSetFocus() {
+ views::FocusManager* focus_manager = GetFocusManager();
+ if (!focus_manager) {
+ NOTREACHED();
+ return;
+ }
+ focus_manager->SetFocusedView(this);
+ }
+ virtual SkBitmap GetFavIcon() const {
+ return SkBitmap();
+ }
+ virtual std::wstring GetTitle() const {
+ return std::wstring();
+ }
+
+ private:
+ AppLauncher* app_launcher_;
+ views::NativeViewHost* location_entry_view_;
+#if defined(OS_WIN)
+ scoped_ptr<AutocompleteEditViewWin> location_entry_;
+#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
+ scoped_ptr<AutocompleteEditViewGtk> location_entry_;
+#else
+ NOTIMPLEMENTED();
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationBar);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// InfoBubbleContentsView
+//
+// The view that contains the navigation bar and render view.
+// It is displayed in an info-bubble.
+
+class InfoBubbleContentsView : public views::View {
+ public:
+ explicit InfoBubbleContentsView(AppLauncher* app_launcher);
+ ~InfoBubbleContentsView();
+
+ // Sets the initial focus.
+ // Should be called when the bubble that contains us is shown.
+ void BubbleShown();
+
+ // views::View override:
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+
+ private:
+ // The application launcher displaying this info bubble.
+ AppLauncher* app_launcher_;
+
+ // The navigation bar.
+ NavigationBar* navigation_bar_;
+
+ // The view containing the renderer view.
+ views::NativeViewHost* render_view_container_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfoBubbleContentsView);
+};
+
+InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher)
+ : app_launcher_(app_launcher),
+ navigation_bar_(NULL),
+ render_view_container_(NULL) {
+}
+
+InfoBubbleContentsView::~InfoBubbleContentsView() {
+}
+
+void InfoBubbleContentsView::BubbleShown() {
+ navigation_bar_->RequestFocus();
+}
+
+void InfoBubbleContentsView::ViewHierarchyChanged(
+ bool is_add, views::View* parent, views::View* child) {
+ if (!is_add || child != this)
+ return;
+
+ DCHECK(!render_view_container_);
+ render_view_container_ = new RWHVNativeViewHost;
+ AddChildView(render_view_container_);
+#if defined(OS_WIN)
+ RenderWidgetHostViewWin* view_win =
+ static_cast<RenderWidgetHostViewWin*>(app_launcher_->rwhv_);
+ // Create the HWND now that we are parented.
+ HWND hwnd = view_win->Create(GetWidget()->GetNativeView());
+ view_win->ShowWindow(SW_SHOW);
+#endif
+ render_view_container_->Attach(app_launcher_->rwhv_->GetNativeView());
+
+ navigation_bar_ = new NavigationBar(app_launcher_);
+ AddChildView(navigation_bar_);
+}
+
+gfx::Size InfoBubbleContentsView::GetPreferredSize() {
+ gfx::Rect bounds = app_launcher_->browser()->window()->GetRestoredBounds();
+ return gfx::Size(bounds.width() * 2 / 3, bounds.width() * 4 / 5);
+}
+
+void InfoBubbleContentsView::Layout() {
+ if (bounds().IsEmpty() || GetChildViewCount() == 0)
+ return;
+
+ int navigation_bar_height =
+ kNavigationBarHeight + kNavigationEntryYMargin * 2;
+ const views::Border* border = navigation_bar_->border();
+ if (border) {
+ gfx::Insets insets;
+ border->GetInsets(&insets);
+ navigation_bar_height += insets.height();
+ }
+ navigation_bar_->SetBounds(x(), y(), width(), navigation_bar_height);
+ int render_y = navigation_bar_->bounds().bottom();
+ gfx::Size rwhv_size =
+ gfx::Size(width(), std::max(0, height() - render_y + y()));
+ render_view_container_->SetBounds(x(), render_y,
+ rwhv_size.width(), rwhv_size.height());
+ app_launcher_->rwhv_->SetSize(rwhv_size);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AppLauncher
+
+AppLauncher::AppLauncher(Browser* browser)
+ : browser_(browser),
+ info_bubble_(NULL),
+ site_instance_(NULL),
+ contents_rvh_(NULL),
+ rwhv_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ tab_contents_delegate_(new TabContentsDelegateImpl(this))) {
+ info_bubble_content_ = new InfoBubbleContentsView(this);
+
+ Profile* profile = browser_->profile();
+ int64 session_storage_namespace_id = profile->GetWebKitContext()->
+ dom_storage_context()->AllocateSessionStorageNamespaceId();
+ site_instance_ = SiteInstance::CreateSiteInstanceForURL(profile,
+ GetMenuURL());
+ contents_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE,
+ session_storage_namespace_id);
+ rwhv_ = RenderWidgetHostView::CreateViewForWidget(contents_rvh_);
+ contents_rvh_->set_view(rwhv_);
+
+ // On Windows, we'll create the RWHV HWND once we are attached as we need
+ // to be parented for CreateWindow to work.
+#if defined(OS_LINUX)
+ RenderWidgetHostViewGtk* view_gtk =
+ static_cast<RenderWidgetHostViewGtk*>(rwhv_);
+ view_gtk->InitAsChild();
+#endif
+
+ contents_rvh_->CreateRenderView(profile->GetRequestContext());
+ DCHECK(contents_rvh_->IsRenderViewLive());
+ contents_rvh_->NavigateToURL(GetMenuURL());
+}
+
+AppLauncher::~AppLauncher() {
+ contents_rvh_->Shutdown();
+}
+
+// static
+AppLauncher* AppLauncher::Show(Browser* browser) {
+ AppLauncher* app_launcher = new AppLauncher(browser);
+
+ BrowserView* browser_view = static_cast<BrowserView*>(browser->window());
+ TabStrip* tabstrip = browser_view->tabstrip()->AsTabStrip();
+ if (!tabstrip) {
+ delete app_launcher;
+ return NULL;
+ }
+ gfx::Rect bounds = tabstrip->GetNewTabButtonBounds();
+ gfx::Point origin = bounds.origin();
+ views::RootView::ConvertPointToScreen(tabstrip, &origin);
+ bounds.set_origin(origin);
+ app_launcher->info_bubble_ =
+ InfoBubble::Show(browser_view->frame()->GetWindow(), bounds,
+ app_launcher->info_bubble_content_, app_launcher);
+ app_launcher->info_bubble_content_->BubbleShown();
+ return app_launcher;
+}
+
+void AppLauncher::Hide() {
+ info_bubble_->Close();
+}
+
+void AppLauncher::InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape) {
+ // The stack may have pending_contents_ on it. Delay deleting the
+ // pending_contents_ as TabContents doesn't deal well with being deleted
+ // while on the stack.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ new DeleteTask<AppLauncher>(this));
+}
+
+void AppLauncher::RequestMove(const gfx::Rect& new_bounds) {
+#if defined(OS_LINUX)
+ // Invoking PositionChild results in a gtk signal that triggers attempting to
+ // to resize the window. We need to set the size request so that it resizes
+ // correctly when this happens.
+ gtk_widget_set_size_request(info_bubble_->GetNativeView(),
+ new_bounds.width(), new_bounds.height());
+ info_bubble_->SetBounds(new_bounds);
+#endif
+}
+
+RendererPreferences AppLauncher::GetRendererPrefs(Profile* profile) const {
+ RendererPreferences preferences;
+ renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile);
+ return preferences;
+}
+
+void AppLauncher::CreateNewWindow(int route_id) {
+ if (pending_contents_.get()) {
+ NOTREACHED();
+ return;
+ }
+
+ helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
+ DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())),
+ NULL);
+ pending_contents_.reset(helper_.GetCreatedWindow(route_id));
+ pending_contents_->set_delegate(tab_contents_delegate_.get());
+}
+
+void AppLauncher::ShowCreatedWindow(int route_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+ if (disposition == NEW_POPUP) {
+ pending_contents_->set_delegate(NULL);
+ browser_->GetSelectedTabContents()->AddNewContents(
+ pending_contents_.release(), disposition, initial_pos, user_gesture);
+ Hide();
+ }
+}
+
+void AppLauncher::StartDragging(const WebDropData& drop_data,
+ WebKit::WebDragOperationsMask allowed_ops,
+ const SkBitmap& image,
+ const gfx::Point& image_offset) {
+ // We're not going to do any drag & drop, but we have to tell the renderer the
+ // drag & drop ended, othewise the renderer thinks the drag operation is
+ // underway and mouse events won't work.
+ contents_rvh_->DragSourceSystemDragEnded();
+}
+
+void AppLauncher::AddTabWithURL(const GURL& url,
+ PageTransition::Type transition) {
+#if defined(OS_CHROMEOS)
+ switch (chromeos::StatusAreaView::GetOpenTabsMode()) {
+ case chromeos::StatusAreaView::OPEN_TABS_ON_LEFT: {
+ // Add the new tab at the first non-pinned location.
+ int index = browser_->tabstrip_model()->IndexOfFirstNonMiniTab();
+ browser_->AddTabWithURL(url, GURL(), transition,
+ true, index, true, NULL);
+ break;
+ }
+ case chromeos::StatusAreaView::OPEN_TABS_CLOBBER: {
+ browser_->GetSelectedTabContents()->controller().LoadURL(
+ url, GURL(), transition);
+ break;
+ }
+ case chromeos::StatusAreaView::OPEN_TABS_ON_RIGHT: {
+ browser_->AddTabWithURL(url, GURL(), transition, true, -1, true, NULL);
+ break;
+ }
+ }
+#else
+ browser_->AddTabWithURL(url, GURL(), transition, true, -1, true, NULL);
+#endif
+}
diff --git a/chrome/browser/chromeos/app_launcher.h b/chrome/browser/views/app_launcher.h
index f2a8145..c641988 100644
--- a/chrome/browser/chromeos/app_launcher.h
+++ b/chrome/browser/views/app_launcher.h
@@ -2,27 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CHROMEOS_APP_LAUNCHER_H_
-#define CHROME_BROWSER_CHROMEOS_APP_LAUNCHER_H_
+#ifndef CHROME_BROWSER_VIEWS_APP_LAUNCHER_H_
+#define CHROME_BROWSER_VIEWS_APP_LAUNCHER_H_
-#include <gtk/gtk.h>
-
-#include "app/active_window_watcher_x.h"
#include "base/scoped_ptr.h"
-#include "base/task.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
+#include "chrome/browser/views/info_bubble.h"
#include "chrome/common/renderer_preferences.h"
#include "views/view.h"
class Browser;
-class RenderWidgetHostViewGtk;
class SiteInstance;
-class SkBitmap;
namespace gfx {
-class Point;
class Size;
}
namespace views {
@@ -31,9 +25,9 @@ class View;
class WidgetGtk;
}
-namespace chromeos {
-
+class InfoBubbleContentsView;
class NavigationBar;
+class TabContentsDelegateImpl;
// AppLauncher manages showing the application launcher and optionally the
// navigation bar in compact navigation bar mode. The app launcher is
@@ -57,94 +51,25 @@ class NavigationBar;
//
// When a new url is opened, or the user clicks outsides the bounds of the
// widget the app launcher is closed.
-class AppLauncher : public RenderViewHostDelegate,
- public RenderViewHostDelegate::View,
- public ActiveWindowWatcherX::Observer,
- public views::AcceleratorTarget {
+class AppLauncher : public InfoBubbleDelegate,
+ public RenderViewHostDelegate,
+ public RenderViewHostDelegate::View {
public:
- AppLauncher(Browser* browser);
- ~AppLauncher();
-
- // Shows the menu.
- void Show();
+ // Shows an application launcher bubble pointing to the new tab button.
+ // The caller DOES NOT OWN the AppLauncher returned. It is deleted
+ // automatically when the AppLauncher is closed.
+ static AppLauncher* Show(Browser* browser);
- private:
- // TabContentsDelegate and RenderViewHostDelegate::View have some methods
- // in common (with differing signatures). The TabContentsDelegate methods are
- // implemented by this class.
- class TabContentsDelegateImpl : public TabContentsDelegate {
- public:
- explicit TabContentsDelegateImpl(AppLauncher* app_launcher);
-
- // TabContentsDelegate.
- virtual void OpenURLFromTab(TabContents* source,
- const GURL& url, const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition);
- virtual void NavigationStateChanged(const TabContents* source,
- unsigned changed_flags) {}
- virtual void AddNewContents(TabContents* source,
- TabContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {}
- virtual void ActivateContents(TabContents* contents) {}
- virtual void LoadingStateChanged(TabContents* source) {}
- virtual void CloseContents(TabContents* source) {}
- virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {}
- virtual bool IsPopup(TabContents* source) { return false; }
- virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {}
- virtual void URLStarredChanged(TabContents* source, bool starred) {}
- virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
-
- private:
- AppLauncher* app_launcher_;
-
- DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl);
- };
-
- class TopContainer : public views::View {
- public:
- explicit TopContainer(AppLauncher* app_launcher);
- virtual ~TopContainer() {}
-
- // views::View overrides.
- virtual void Layout();
- virtual bool OnMousePressed(const views::MouseEvent& event);
-
- private:
- AppLauncher* app_launcher_;
-
- DISALLOW_COPY_AND_ASSIGN(TopContainer);
- };
-
- class BubbleContainer : public views::View {
- public:
- explicit BubbleContainer(AppLauncher* app_launcher);
-
- // views::View overrides.
- virtual void Layout();
-
- private:
- AppLauncher* app_launcher_;
-
- DISALLOW_COPY_AND_ASSIGN(BubbleContainer);
- };
-
- friend class BubbleContainer;
- friend class NavigationBar;
- friend class TabContentsDelegateImpl;
- friend class TopContainer;
+ // Returns the browser this AppLauncher is associated with.
+ Browser* browser() const { return browser_; }
// Hides the app launcher.
void Hide();
- // Cleans up state. This is invoked before showing and after a delay when
- // hidden.
- void Cleanup();
-
- // Updates the app launcher's state.
- void Update();
+ // InfoBubbleDelegate overrides.
+ virtual void InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape);
+ virtual bool CloseOnEscape() { return true; }
// RenderViewHostDelegate overrides.
virtual int GetBrowserWindowID() const {
@@ -185,58 +110,44 @@ class AppLauncher : public RenderViewHostDelegate,
virtual void HandleMouseLeave() {}
virtual void UpdatePreferredSize(const gfx::Size& pref_size) {}
- // ActiveWindowWatcherX::Observer implementation.
- virtual void ActiveWindowChanged(GdkWindow* active_window);
+ private:
+ friend class DeleteTask<AppLauncher>;
+ friend class NavigationBar;
+ friend class InfoBubbleContentsView;
- // views::AcceleratorTarget implementation:
- virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
+ explicit AppLauncher(Browser* browser);
+ ~AppLauncher();
void AddTabWithURL(const GURL& url, PageTransition::Type transition);
// The currently active browser. We use this to open urls.
Browser* browser_;
- // The widget displaying the rwvh_.
- views::WidgetGtk* popup_;
+ // The InfoBubble displaying the omnibox and app contents.
+ InfoBubble* info_bubble_;
// SiteInstance for the RenderViewHosts we create.
- SiteInstance* site_instance_;
+ scoped_refptr<SiteInstance> site_instance_;
// RenderViewHost for the contents.
RenderViewHost* contents_rvh_;
// RenderWidgetHostView from the contents_rvh_.
- RenderWidgetHostViewGtk* rwhv_;
+ RenderWidgetHostView* rwhv_;
// Handles creating the child TabContents.
RenderViewHostDelegateViewHelper helper_;
// Delegate of the TabContents created by helper_.
- TabContentsDelegateImpl tab_contents_delegate_;
+ scoped_ptr<TabContentsDelegateImpl> tab_contents_delegate_;
// TabContents created when the user clicks a link.
scoped_ptr<TabContents> pending_contents_;
- ScopedRunnableMethodFactory<AppLauncher> method_factory_;
-
- // Container of the background, NavigationBar and Renderer.
- views::View* top_container_;
-
- // Container of the NavigationBar and Renderer (shown in a bubble).
- views::View* bubble_container_;
-
- // The navigation bar. Only shown in compact navigation bar mode.
- NavigationBar* navigation_bar_;
-
- // The view containing the renderer view.
- views::NativeViewHost* render_view_container_;
-
- // True if the popup has ever been shown.
- bool has_shown_;
+ // The view with the navigation bar and render view, shown in the info-bubble.
+ InfoBubbleContentsView* info_bubble_content_;
DISALLOW_COPY_AND_ASSIGN(AppLauncher);
};
-} // namespace chromeos
-
-#endif // CHROME_BROWSER_CHROMEOS_APP_LAUNCHER_H_
+#endif // CHROME_BROWSER_VIEWS_APP_LAUNCHER_H_
diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc
index 7f21bca..e1bb401 100644
--- a/chrome/browser/views/info_bubble.cc
+++ b/chrome/browser/views/info_bubble.cc
@@ -264,7 +264,7 @@ void InfoBubble::Init(views::Window* parent,
// Calculate and set the bounds for all windows and views.
gfx::Rect window_bounds;
- bool prefer_arrow_on_right =
+ bool prefer_arrow_on_right = delegate &&
(contents->UILayoutIsRightToLeft() == delegate->PreferOriginSideAnchor());
#if defined(OS_WIN)
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index ec15794..ccfc31a 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -10,7 +10,9 @@
#include "app/os_exchange_data.h"
#include "app/resource_bundle.h"
#include "app/slide_animation.h"
+#include "base/command_line.h"
#include "base/stl_util-inl.h"
+#include "chrome/browser/browser.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/metrics/user_metrics.h"
@@ -19,8 +21,10 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/app_launcher.h"
#include "chrome/browser/views/tabs/dragged_tab_controller.h"
#include "chrome/browser/views/tabs/tab.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "gfx/path.h"
#include "gfx/size.h"
@@ -818,6 +822,10 @@ bool TabStrip::IsCompatibleWith(TabStrip* other) const {
return model_->profile() == other->model()->profile();
}
+gfx::Rect TabStrip::GetNewTabButtonBounds() {
+ return newtab_button_->bounds();
+}
+
////////////////////////////////////////////////////////////////////////////////
// TabStrip, BaseTabStrip implementation:
@@ -1399,6 +1407,16 @@ bool TabStrip::HasAvailableDragActions() const {
void TabStrip::ButtonPressed(views::Button* sender, const views::Event& event) {
if (sender == newtab_button_) {
+ // TODO(jcampan): if we decide to keep the app launcher as the default
+ // behavior for the new tab button, we should add a method
+ // on the TabStripDelegate to do so.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAppLauncherForNewTab)) {
+ NavigationController& controller =
+ model_->GetSelectedTabContents()->controller();
+ AppLauncher::Show(Browser::GetBrowserForController(&controller, NULL));
+ return;
+ }
UserMetrics::RecordAction("NewTab_Button", model_->profile());
model_->delegate()->AddBlankTab(true);
}
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index 6285e1d..73e89c8 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -61,19 +61,22 @@ class TabStrip : public BaseTabStrip,
// Removes the drag source Tab from this TabStrip, and deletes it.
void DestroyDraggedSourceTab(Tab* tab);
- // Retrieve the ideal bounds for the Tab at the specified index.
+ // Retrieves the ideal bounds for the Tab at the specified index.
gfx::Rect GetIdealBounds(int index);
// Returns the currently selected tab.
Tab* GetSelectedTab() const;
- // Create the new tab button.
+ // Creates the new tab button.
void InitTabStripButtons();
// Return true if this tab strip is compatible with the provided tab strip.
// Compatible tab strips can transfer tabs during drag and drop.
bool IsCompatibleWith(TabStrip* other) const;
+ // Returns the bounds of the new tab button.
+ gfx::Rect GetNewTabButtonBounds();
+
// BaseTabStrip implementation:
virtual int GetPreferredHeight();
virtual void SetBackgroundOffset(const gfx::Point& offset);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index acbd591..bebf2c8 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -304,8 +304,6 @@
'browser/chrome_plugin_host.h',
'browser/chrome_thread.cc',
'browser/chrome_thread.h',
- 'browser/chromeos/app_launcher.h',
- 'browser/chromeos/app_launcher.cc',
'browser/chromeos/notifications/balloon_collection_impl.h',
'browser/chromeos/notifications/balloon_collection_impl.cc',
'browser/chromeos/notifications/balloon_view.h',
@@ -2042,6 +2040,8 @@
'browser/views/accelerator_table_gtk.h',
'browser/views/accessible_toolbar_view.cc',
'browser/views/accessible_toolbar_view.h',
+ 'browser/views/app_launcher.cc',
+ 'browser/views/app_launcher.h',
'browser/views/appcache_info_view.cc',
'browser/views/appcache_info_view.h',
'browser/views/autocomplete/autocomplete_popup_contents_view.cc',
@@ -2678,6 +2678,8 @@
['include', '^browser/views/accelerator_table_gtk.h'],
['include', '^browser/views/accessible_toolbar_view.cc'],
['include', '^browser/views/accessible_toolbar_view.h'],
+ ['include', '^browser/views/app_launcher.cc'],
+ ['include', '^browser/views/app_launcher.h'],
['include', '^browser/views/autocomplete/autocomplete_popup_contents_view.cc'],
['include', '^browser/views/autocomplete/autocomplete_popup_contents_view.h'],
['include', '^browser/views/autocomplete/autocomplete_popup_gtk.cc'],
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 07e9433..cb93cbc 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -39,6 +39,9 @@ const char kAppId[] = "app-id";
// panel window.
const char kAppLaunchAsPanel[] = "app-launch-as-panel";
+// Makes the app launcher popup when a new tab is created.
+const char kAppLauncherForNewTab[] = "app-launcher-new-tab";
+
// Authentication white list for servers
const char kAuthServerWhitelist[] = "auth-server-whitelist";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index e6c541e..27a53d2 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -26,6 +26,7 @@ extern const char kAlwaysEnableDevTools[];
extern const char kApp[];
extern const char kAppId[];
extern const char kAppLaunchAsPanel[];
+extern const char kAppLauncherForNewTab[];
extern const char kAuthServerWhitelist[];
extern const char kAutomationClientChannelID[];
extern const char kBookmarkMenu[];