summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/gtk/browser_titlebar.cc264
-rw-r--r--chrome/browser/gtk/browser_titlebar.h106
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc134
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h44
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc97
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.h20
-rw-r--r--chrome/browser/tabs/tab_strip_model.h1
-rw-r--r--chrome/chrome.gyp2
8 files changed, 389 insertions, 279 deletions
diff --git a/chrome/browser/gtk/browser_titlebar.cc b/chrome/browser/gtk/browser_titlebar.cc
new file mode 100644
index 0000000..4540c5d
--- /dev/null
+++ b/chrome/browser/gtk/browser_titlebar.cc
@@ -0,0 +1,264 @@
+// Copyright (c) 2009 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/gtk/browser_titlebar.h"
+
+#include <gtk/gtk.h>
+
+#include "app/l10n_util.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
+#include "chrome/browser/gtk/custom_button.h"
+#include "chrome/browser/gtk/nine_box.h"
+#include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "grit/app_resources.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+
+namespace {
+
+// The space above the titlebars.
+const int kTitlebarHeight = 14;
+
+// A linux specific menu item for toggling window decorations.
+const int kShowWindowDecorationsCommand = 200;
+
+}
+
+BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window,
+ GtkWindow* window)
+ : browser_window_(browser_window), window_(window) {
+ Init();
+}
+
+void BrowserTitlebar::Init() {
+ titlebar_background_.reset(new NineBox(
+ browser_window_->browser()->profile()->GetThemeProvider(),
+ 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0));
+ titlebar_background_otr_.reset(new NineBox(
+ browser_window_->browser()->profile()->GetThemeProvider(),
+ 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0));
+
+ // The widget hierarchy is shown below. In addition to the diagram, there is
+ // a gtk event box surrounding the titlebar_hbox which catches mouse events
+ // in the titlebar.
+ //
+ // +- HBox (titlebar_hbox) -----------------------------------------------+
+ // |+- Alignment (titlebar_alignment_)-++- VBox (titlebar_buttons_box_) -+|
+ // || ||+- HBox -----------------------+||
+ // || |||+- button -++- button -+ |||
+ // ||+- TabStripGtk ------------------+|||| minimize || restore | ... |||
+ // ||| tab tab tab tabclose +|||+----------++----------+ |||
+ // ||+--------------------------------+||+------------------------------+||
+ // |+----------------------------------++--------------------------------+|
+ // +----------------------------------------------------------------------+
+ container_ = gtk_event_box_new();
+ GtkWidget* titlebar_hbox = gtk_hbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(container_), titlebar_hbox);
+
+ g_signal_connect(G_OBJECT(container_), "button-press-event",
+ G_CALLBACK(OnMouseButtonPress), this);
+ g_signal_connect(G_OBJECT(titlebar_hbox), "expose-event",
+ G_CALLBACK(OnExpose), this);
+ g_signal_connect(window_, "window-state-event",
+ G_CALLBACK(OnWindowStateChanged), this);
+
+ // We use an alignment to control the titlebar height.
+ titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_box_pack_start(GTK_BOX(titlebar_hbox), titlebar_alignment_, TRUE,
+ TRUE, 0);
+
+ // Put the tab strip in the titlebar.
+ gtk_container_add(GTK_CONTAINER(titlebar_alignment_),
+ browser_window_->tabstrip()->widget());
+
+ // We put the min/max/restore/close buttons in a vbox so they are top aligned
+ // and don't vertically stretch.
+ titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0);
+ GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE,
+ FALSE, 0);
+
+ close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H,
+ buttons_hbox, IDS_XPFRAME_CLOSE_TOOLTIP));
+ restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
+ IDR_RESTORE_H, buttons_hbox,
+ IDS_XPFRAME_RESTORE_TOOLTIP));
+ maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
+ IDR_MAXIMIZE_H, buttons_hbox,
+ IDS_XPFRAME_MAXIMIZE_TOOLTIP));
+ minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
+ IDR_MINIMIZE_H, buttons_hbox,
+ IDS_XPFRAME_MINIMIZE_TOOLTIP));
+
+ gtk_box_pack_end(GTK_BOX(titlebar_hbox), titlebar_buttons_box_, FALSE,
+ FALSE, 0);
+
+ gtk_widget_show_all(container_);
+}
+
+CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image,
+ int image_pressed, int image_hot, GtkWidget* box, int tooltip) {
+ CustomDrawButton* button = new CustomDrawButton(image, image_pressed,
+ image_hot, 0);
+ g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked),
+ this);
+ std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip);
+ gtk_widget_set_tooltip_text(button->widget(),
+ localized_tooltip.c_str());
+ gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
+ return button;
+}
+
+void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) {
+ if (use_custom_frame) {
+ gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_),
+ kTitlebarHeight, 0, 0, 0);
+ gtk_widget_show_all(titlebar_buttons_box_);
+ } else {
+ gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), 0, 0, 0, 0);
+ gtk_widget_hide(titlebar_buttons_box_);
+ }
+}
+
+gboolean BrowserTitlebar::OnExpose(GtkWidget* widget, GdkEventExpose* e,
+ BrowserTitlebar* titlebar) {
+ cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
+ cairo_rectangle(cr, e->area.x, e->area.y, e->area.width, e->area.height);
+ cairo_clip(cr);
+ Profile* profile = titlebar->browser_window_->browser()->profile();
+ NineBox* image = profile->IsOffTheRecord()
+ ? titlebar->titlebar_background_otr_.get()
+ : titlebar->titlebar_background_.get();
+ image->RenderTopCenterStrip(cr, e->area.x, 0, e->area.width);
+ cairo_destroy(cr);
+
+ return FALSE; // Allow subwidgets to paint.
+}
+
+gboolean BrowserTitlebar::OnMouseButtonPress(GtkWidget* widget,
+ GdkEventButton* event, BrowserTitlebar* titlebar) {
+ if (1 == event->button) {
+ if (GDK_BUTTON_PRESS == event->type) {
+ gtk_window_begin_move_drag(GTK_WINDOW(titlebar->window_),
+ event->button, event->x_root, event->y_root, event->time);
+ return TRUE;
+ } else if (GDK_2BUTTON_PRESS == event->type) {
+ // Maximize/restore on double click.
+ if (titlebar->browser_window_->IsMaximized()) {
+ gtk_window_unmaximize(titlebar->window_);
+ } else {
+ gtk_window_maximize(titlebar->window_);
+ }
+ return TRUE;
+ }
+ } else if (3 == event->button) {
+ titlebar->ShowContextMenu();
+ return TRUE;
+ }
+
+ return FALSE; // Continue to propagate the event.
+}
+
+gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
+ GdkEventWindowState* event, BrowserTitlebar* titlebar) {
+ // Update the maximize/restore button.
+ if (titlebar->browser_window_->IsMaximized()) {
+ gtk_widget_hide(titlebar->maximize_button_->widget());
+ gtk_widget_show(titlebar->restore_button_->widget());
+ } else {
+ gtk_widget_hide(titlebar->restore_button_->widget());
+ gtk_widget_show(titlebar->maximize_button_->widget());
+ }
+ return FALSE;
+}
+
+void BrowserTitlebar::OnButtonClicked(GtkWidget* button,
+ BrowserTitlebar* titlebar) {
+ if (titlebar->close_button_->widget() == button) {
+ titlebar->browser_window_->Close();
+ } else if (titlebar->restore_button_->widget() == button) {
+ gtk_window_unmaximize(titlebar->window_);
+ } else if (titlebar->maximize_button_->widget() == button) {
+ gtk_window_maximize(titlebar->window_);
+ } else if (titlebar->minimize_button_->widget() == button) {
+ gtk_window_iconify(titlebar->window_);
+ }
+}
+
+void BrowserTitlebar::ShowContextMenu() {
+ if (!context_menu_.get()) {
+ context_menu_.reset(new MenuGtk(this, false));
+ context_menu_->AppendMenuItemWithLabel(
+ IDC_NEW_TAB,
+ l10n_util::GetStringUTF8(IDS_TAB_CXMENU_NEWTAB));
+ context_menu_->AppendMenuItemWithLabel(
+ IDC_RESTORE_TAB,
+ l10n_util::GetStringUTF8(IDS_RESTORE_TAB));
+
+ context_menu_->AppendSeparator();
+
+ context_menu_->AppendMenuItemWithLabel(
+ IDC_TASK_MANAGER,
+ l10n_util::GetStringUTF8(IDS_TASK_MANAGER));
+
+ context_menu_->AppendSeparator();
+
+ context_menu_->AppendCheckMenuItemWithLabel(
+ kShowWindowDecorationsCommand,
+ l10n_util::GetStringUTF8(IDS_SHOW_WINDOW_DECORATIONS));
+ }
+
+ context_menu_->PopupAsContext(gtk_get_current_event_time());
+}
+
+bool BrowserTitlebar::IsCommandEnabled(int command_id) const {
+ switch (command_id) {
+ case IDC_NEW_TAB:
+ case kShowWindowDecorationsCommand:
+ return true;
+
+ case IDC_RESTORE_TAB:
+ return browser_window_->browser()->CanRestoreTab();
+
+ case IDC_TASK_MANAGER:
+ // TODO(tc): Task manager needs to be implemented.
+ return false;
+
+ default:
+ NOTREACHED();
+ }
+ return false;
+}
+
+bool BrowserTitlebar::IsItemChecked(int command_id) const {
+ DCHECK(command_id == kShowWindowDecorationsCommand);
+ PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
+ return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
+}
+
+void BrowserTitlebar::ExecuteCommand(int command_id) {
+ switch (command_id) {
+ case IDC_NEW_TAB:
+ case IDC_RESTORE_TAB:
+ case IDC_TASK_MANAGER:
+ browser_window_->browser()->ExecuteCommand(command_id);
+ break;
+
+ case kShowWindowDecorationsCommand:
+ {
+ PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
+ prefs->SetBoolean(prefs::kUseCustomChromeFrame,
+ !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+}
diff --git a/chrome/browser/gtk/browser_titlebar.h b/chrome/browser/gtk/browser_titlebar.h
new file mode 100644
index 0000000..c937f85
--- /dev/null
+++ b/chrome/browser/gtk/browser_titlebar.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2009 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.
+//
+// A helper class that contains the gtk widgets that make up the titlebar. The
+// titlebar consists of the tabstrip and if the custom chrome frame is turned
+// on, it includes the taller titlebar and minimize, restore, maximize, and
+// close buttons.
+
+#ifndef CHROME_BROWSER_GTK_BROWSER_TITLEBAR_H_
+#define CHROME_BROWSER_GTK_BROWSER_TITLEBAR_H_
+
+#include <gtk/gtk.h>
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/gtk/menu_gtk.h"
+#include "chrome/browser/gtk/nine_box.h"
+
+class BrowserWindowGtk;
+class CustomDrawButton;
+class TabStripGtk;
+
+class BrowserTitlebar : public MenuGtk::Delegate {
+ public:
+ BrowserTitlebar(BrowserWindowGtk* browser_window, GtkWindow* window);
+ virtual ~BrowserTitlebar() { }
+
+ GtkWidget* widget() {
+ return container_;
+ }
+
+ // Update the appearance of the title bar based on whether we're showing a
+ // custom frame or not. If |use_custom_frame| is true, we show an extra
+ // tall titlebar and the min/max/close buttons.
+ void UpdateCustomFrame(bool use_custom_frame);
+
+ private:
+ // Build the titlebar, the space above the tab
+ // strip, and (maybe) the min, max, close buttons. |container| is the gtk
+ // continer that we put the widget into.
+ void Init();
+
+ // Constructs a CustomDraw button given 3 image ids (IDR_), the box to place
+ // the button into, and a tooltip id (IDS_).
+ CustomDrawButton* BuildTitlebarButton(int image, int image_pressed,
+ int image_hot, GtkWidget* box,
+ int tooltip);
+
+ // Callback for when the titlebar (include the background of the tab strip)
+ // needs to be redrawn.
+ static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e,
+ BrowserTitlebar* window);
+
+ // Callback for when the titlebar (include the background of the tab strip)
+ // needs to be redrawn.
+ static gboolean OnMouseButtonPress(GtkWidget* widget, GdkEventButton* e,
+ BrowserTitlebar* window);
+
+ // Callback for changes to window state. This includes
+ // maximizing/restoring/minimizing the window.
+ static gboolean OnWindowStateChanged(GtkWindow* window,
+ GdkEventWindowState* event,
+ BrowserTitlebar* titlebar);
+
+ // Callback for min/max/close buttons.
+ static void OnButtonClicked(GtkWidget* button, BrowserTitlebar* window);
+
+ // -- Context Menu -----------------------------------------------------------
+
+ // On Windows, right clicking in the titlebar background brings up the system
+ // menu. There's no such thing on linux, so we just show the menu items we
+ // add to the menu.
+ void ShowContextMenu();
+ // MenuGtk::Delegate implementation:
+ virtual bool IsCommandEnabled(int command_id) const;
+ virtual bool IsItemChecked(int command_id) const;
+ virtual void ExecuteCommand(int command_id);
+
+ // Pointers to the browser window that owns us and it's GtkWindow.
+ BrowserWindowGtk* browser_window_;
+ GtkWindow* window_;
+
+ // The container widget the holds the whole titlebar.
+ GtkWidget* container_;
+ // Box that holds the min/max/close buttons if the user turns off window
+ // manager decorations.
+ GtkWidget* titlebar_buttons_box_;
+ // Gtk alignment that contains the tab strip. If the user turns off window
+ // manager decorations, we draw this taller.
+ GtkWidget* titlebar_alignment_;
+
+ // Maximize and restore widgets in the titlebar.
+ scoped_ptr<CustomDrawButton> minimize_button_;
+ scoped_ptr<CustomDrawButton> maximize_button_;
+ scoped_ptr<CustomDrawButton> restore_button_;
+ scoped_ptr<CustomDrawButton> close_button_;
+
+ // The background of the title bar and tab strip.
+ scoped_ptr<NineBox> titlebar_background_;
+ scoped_ptr<NineBox> titlebar_background_otr_;
+
+ // The context menu.
+ scoped_ptr<MenuGtk> context_menu_;
+};
+
+#endif // CHROME_BROWSER_GTK_BROWSER_TITLEBAR_H_
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index e43327f..d62c7a1 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -7,7 +7,6 @@
#include <gdk/gdkkeysyms.h>
#include "app/resource_bundle.h"
-#include "app/l10n_util.h"
#include "base/base_paths_linux.h"
#include "base/gfx/gtk_util.h"
#include "base/logging.h"
@@ -23,15 +22,14 @@
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/gtk/about_chrome_dialog.h"
#include "chrome/browser/gtk/bookmark_bar_gtk.h"
+#include "chrome/browser/gtk/browser_titlebar.h"
#include "chrome/browser/gtk/browser_toolbar_gtk.h"
#include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h"
-#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/download_shelf_gtk.h"
#include "chrome/browser/gtk/go_button_gtk.h"
#include "chrome/browser/gtk/import_dialog_gtk.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"
#include "chrome/browser/gtk/find_bar_gtk.h"
-#include "chrome/browser/gtk/nine_box.h"
#include "chrome/browser/gtk/status_bubble_gtk.h"
#include "chrome/browser/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
@@ -43,8 +41,6 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
-#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
namespace {
@@ -59,9 +55,6 @@ const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__";
// The width of the custom frame.
const int kCustomFrameWidth = 3;
-// The space above the titlebars.
-const int kTitlebarHeight = 14;
-
gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event,
BrowserWindowGtk* browser_win) {
gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height);
@@ -323,13 +316,6 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
ConnectAccelerators();
bounds_ = GetInitialWindowBounds(window_);
- titlebar_background_.reset(new NineBox(
- browser_->profile()->GetThemeProvider(),
- 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0));
- titlebar_background_otr_.reset(new NineBox(
- browser_->profile()->GetThemeProvider(),
- 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0));
-
// This vbox encompasses all of the widgets within the browser, including the
// tabstrip and the content vbox. The vbox is put in a floating container
// (see gtk_floating_container.h) so we can position the
@@ -342,8 +328,13 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
window_container_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
gtk_container_add(GTK_CONTAINER(window_container_), window_vbox);
+ tabstrip_.reset(new TabStripGtk(browser_->tabstrip_model()));
+ tabstrip_->Init(browser_->profile());
+
// Build the titlebar (tabstrip + header space + min/max/close buttons).
- BuildTitlebar(window_vbox);
+ titlebar_.reset(new BrowserTitlebar(this, window_));
+ gtk_box_pack_start(GTK_BOX(window_vbox), titlebar_->widget(), FALSE, FALSE,
+ 0);
// The content_vbox_ surrounds the "content": toolbar+bookmarks bar+page.
content_vbox_ = gtk_vbox_new(FALSE, 0);
@@ -420,34 +411,6 @@ gboolean BrowserWindowGtk::OnContentAreaExpose(GtkWidget* widget,
return FALSE; // Allow subwidgets to paint.
}
-gboolean BrowserWindowGtk::OnTitlebarExpose(GtkWidget* widget,
- GdkEventExpose* e,
- BrowserWindowGtk* window) {
- cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
- cairo_rectangle(cr, e->area.x, e->area.y, e->area.width, e->area.height);
- cairo_clip(cr);
- NineBox* image = window->browser_->profile()->IsOffTheRecord()
- ? window->titlebar_background_otr_.get()
- : window->titlebar_background_.get();
- image->RenderTopCenterStrip(cr, e->area.x, e->area.y, e->area.width);
- cairo_destroy(cr);
-
- return FALSE; // Allow subwidgets to paint.
-}
-
-void BrowserWindowGtk::OnButtonClicked(GtkWidget* button,
- BrowserWindowGtk* window) {
- if (window->close_button_->widget() == button) {
- window->Close();
- } else if (window->restore_button_->widget() == button) {
- gtk_window_unmaximize(window->window_);
- } else if (window->maximize_button_->widget() == button) {
- gtk_window_maximize(window->window_);
- } else if (window->minimize_button_->widget() == button) {
- gtk_window_iconify(window->window_);
- }
-}
-
void BrowserWindowGtk::Show() {
gtk_widget_show(GTK_WIDGET(window_));
}
@@ -794,15 +757,6 @@ void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) {
void BrowserWindowGtk::OnStateChanged(GdkWindowState state) {
state_ = state;
- // Update the maximize/restore button.
- if (IsMaximized()) {
- gtk_widget_hide(maximize_button_->widget());
- gtk_widget_show(restore_button_->widget());
- } else {
- gtk_widget_hide(restore_button_->widget());
- gtk_widget_show(maximize_button_->widget());
- }
-
SaveWindowPosition();
}
@@ -908,88 +862,16 @@ void BrowserWindowGtk::ConnectAccelerators() {
}
}
-void BrowserWindowGtk::BuildTitlebar(GtkWidget* container) {
- // +- HBox (titlebar_hbox) -----------------------------------------------+
- // |+- Alignment (titlebar_alignment_)-++- VBox (titlebar_buttons_box_) -+|
- // || ||+- HBox -----------------------+||
- // || |||+- button -++- button -+ |||
- // ||+- TabStripGtk ------------------+|||| minimize || restore | ... |||
- // ||| tab tab tab tabclose +|||+----------++----------+ |||
- // ||+--------------------------------+||+------------------------------+||
- // |+----------------------------------++--------------------------------+|
- // +----------------------------------------------------------------------+
- //
- GtkWidget* titlebar_hbox = gtk_hbox_new(FALSE, 0);
- g_signal_connect(G_OBJECT(titlebar_hbox), "expose-event",
- G_CALLBACK(&OnTitlebarExpose), this);
-
- // We use an alignment to control the titlebar height.
- titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
- gtk_box_pack_start(GTK_BOX(titlebar_hbox), titlebar_alignment_, TRUE,
- TRUE, 0);
-
- tabstrip_.reset(new TabStripGtk(browser_->tabstrip_model()));
- tabstrip_->Init(browser_->profile());
- gtk_container_add(GTK_CONTAINER(titlebar_alignment_), tabstrip_->widget());
-
- // We put the min/max/restore/close buttons in a vbox so they are top aligned
- // and don't vertically stretch.
- titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0);
- GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE,
- FALSE, 0);
-
- close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H,
- buttons_hbox, IDS_XPFRAME_CLOSE_TOOLTIP));
- restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
- IDR_RESTORE_H, buttons_hbox,
- IDS_XPFRAME_RESTORE_TOOLTIP));
- maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
- IDR_MAXIMIZE_H, buttons_hbox,
- IDS_XPFRAME_MAXIMIZE_TOOLTIP));
- minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
- IDR_MINIMIZE_H, buttons_hbox,
- IDS_XPFRAME_MINIMIZE_TOOLTIP));
-
- gtk_box_pack_end(GTK_BOX(titlebar_hbox), titlebar_buttons_box_, FALSE,
- FALSE, 0);
-
- gtk_widget_show_all(titlebar_hbox);
- if (IsMaximized()) {
- gtk_widget_hide(maximize_button_->widget());
- } else {
- gtk_widget_hide(restore_button_->widget());
- }
-
- gtk_box_pack_start(GTK_BOX(container), titlebar_hbox, FALSE, FALSE, 0);
-}
-
-CustomDrawButton* BrowserWindowGtk::BuildTitlebarButton(int image,
- int image_pressed, int image_hot, GtkWidget* box, int tooltip) {
- CustomDrawButton* button = new CustomDrawButton(image, image_pressed,
- image_hot, 0);
- g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked),
- this);
- std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip);
- gtk_widget_set_tooltip_text(button->widget(),
- localized_tooltip.c_str());
- gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
- return button;
-}
void BrowserWindowGtk::UpdateCustomFrame() {
gtk_window_set_decorated(window_,
!use_custom_frame_.GetValue());
+ titlebar_->UpdateCustomFrame(use_custom_frame_.GetValue());
if (use_custom_frame_.GetValue()) {
gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0,
kCustomFrameWidth, kCustomFrameWidth, kCustomFrameWidth);
- gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_),
- kTitlebarHeight, 0, 0, 0);
- gtk_widget_show_all(titlebar_buttons_box_);
} else {
gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0);
- gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), 0, 0, 0, 0);
- gtk_widget_hide(titlebar_buttons_box_);
}
}
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index ee43808..850431d 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -19,6 +19,8 @@
#include "chrome/common/x11_util.h"
class BookmarkBarGtk;
+class Browser;
+class BrowserTitlebar;
class BrowserToolbarGtk;
class CustomDrawButton;
class DownloadShelfGtk;
@@ -133,18 +135,16 @@ class BrowserWindowGtk : public BrowserWindow,
// ID of the top-level X window of this object.
static GtkWindow* GetBrowserWindowForXID(XID xid);
+ Browser* browser() {
+ return browser_.get();
+ }
+
protected:
virtual void DestroyBrowser();
// Top level window.
GtkWindow* window_;
// GtkAlignment that holds the interior components of the chromium window.
GtkWidget* window_container_;
- // Box that holds the min/max/close buttons if the user turns off window
- // manager decorations.
- GtkWidget* titlebar_buttons_box_;
- // Gtk alignment that contains the tab strip. If the user turns off window
- // manager decorations, we draw this taller.
- GtkWidget* titlebar_alignment_;
// VBox that holds everything below the tabs.
GtkWidget* content_vbox_;
// VBox that holds everything below the toolbar.
@@ -167,17 +167,6 @@ class BrowserWindowGtk : public BrowserWindow,
// ctrl-l, etc.).
void ConnectAccelerators();
- // Build the titlebar which includes the tab strip, the space above the tab
- // strip, and (maybe) the min, max, close buttons. |container| is the gtk
- // continer that we put the widget into.
- void BuildTitlebar(GtkWidget* container);
-
- // Constructs a CustomDraw button given 3 image ids (IDR_), the box to place
- // the button into, and a tooltip id (IDS_).
- CustomDrawButton* BuildTitlebarButton(int image, int image_pressed,
- int image_hot, GtkWidget* box,
- int tooltip);
-
// Change whether we're showing the custom blue frame.
// Must be called once at startup.
// Triggers relayout of the content.
@@ -191,14 +180,6 @@ class BrowserWindowGtk : public BrowserWindow,
static gboolean OnContentAreaExpose(GtkWidget* widget, GdkEventExpose* e,
BrowserWindowGtk* window);
- // Callback for when the titlebar (include the background of the tab strip)
- // needs to be redrawn.
- static gboolean OnTitlebarExpose(GtkWidget* widget, GdkEventExpose* e,
- BrowserWindowGtk* window);
-
- // Callback for min/max/close buttons.
- static void OnButtonClicked(GtkWidget* button, BrowserWindowGtk* window);
-
static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group,
GObject* acceleratable,
guint keyval,
@@ -234,6 +215,9 @@ class BrowserWindowGtk : public BrowserWindow,
// OnStateChanged(), we can't rely on |state_| & GDK_WINDOW_STATE_FULLSCREEN.
bool full_screen_;
+ // The container for the titlebar + tab strip.
+ scoped_ptr<BrowserTitlebar> titlebar_;
+
// The object that manages all of the widgets in the toolbar.
scoped_ptr<BrowserToolbarGtk> toolbar_;
@@ -254,16 +238,6 @@ class BrowserWindowGtk : public BrowserWindow,
// The container for info bars. Always non-NULL.
scoped_ptr<InfoBarContainerGtk> infobar_container_;
- // Maximize and restore widgets in the titlebar.
- scoped_ptr<CustomDrawButton> minimize_button_;
- scoped_ptr<CustomDrawButton> maximize_button_;
- scoped_ptr<CustomDrawButton> restore_button_;
- scoped_ptr<CustomDrawButton> close_button_;
-
- // The background of the title bar and tab strip.
- scoped_ptr<NineBox> titlebar_background_;
- scoped_ptr<NineBox> titlebar_background_otr_;
-
// The timer used to update frames for the Loading Animation.
base::RepeatingTimer<BrowserWindowGtk> loading_animation_timer_;
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index d460c59..2b95e74 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -18,10 +18,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/gtk_util.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/pref_service.h"
#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
namespace {
@@ -488,8 +485,6 @@ void TabStripGtk::Init(Profile* profile) {
G_CALLBACK(OnExpose), this);
g_signal_connect(G_OBJECT(tabstrip_.get()), "size-allocate",
G_CALLBACK(OnSizeAllocate), this);
- g_signal_connect(G_OBJECT(tabstrip_.get()), "button-press-event",
- G_CALLBACK(OnButtonPress), this);
g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-motion",
G_CALLBACK(OnDragMotion), this);
g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-drop",
@@ -1482,19 +1477,6 @@ void TabStripGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation,
}
// static
-gboolean TabStripGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event,
- TabStripGtk* tabstrip) {
- if (1 == event->button) {
- gtk_window_begin_move_drag(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
- event->button, event->x_root, event->y_root, event->time);
- } else if (3 == event->button) {
- tabstrip->ShowContextMenu();
- }
-
- return TRUE;
-}
-
-// static
gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context,
gint x, gint y, guint time,
TabStripGtk* tabstrip) {
@@ -1570,82 +1552,3 @@ CustomDrawButton* TabStripGtk::MakeNewTabButton() {
return button;
}
-
-void TabStripGtk::ShowContextMenu() {
- if (!context_menu_.get()) {
- context_menu_.reset(new MenuGtk(this, false));
- context_menu_->AppendMenuItemWithLabel(
- TabStripModel::CommandNewTab,
- l10n_util::GetStringUTF8(IDS_TAB_CXMENU_NEWTAB));
- context_menu_->AppendMenuItemWithLabel(
- TabStripModel::CommandRestoreTab,
- l10n_util::GetStringUTF8(IDS_RESTORE_TAB));
-
- context_menu_->AppendSeparator();
-
- context_menu_->AppendMenuItemWithLabel(
- TabStripModel::CommandTaskManager,
- l10n_util::GetStringUTF8(IDS_TASK_MANAGER));
-
- context_menu_->AppendSeparator();
-
- context_menu_->AppendCheckMenuItemWithLabel(
- kShowWindowDecorationsCommand,
- l10n_util::GetStringUTF8(IDS_SHOW_WINDOW_DECORATIONS));
- }
-
- context_menu_->PopupAsContext(gtk_get_current_event_time());
-}
-
-bool TabStripGtk::IsCommandEnabled(int command_id) const {
- switch (command_id) {
- case TabStripModel::CommandNewTab:
- case kShowWindowDecorationsCommand:
- return true;
-
- case TabStripModel::CommandRestoreTab:
- return model_->delegate()->CanRestoreTab();
-
- case TabStripModel::CommandTaskManager:
- // TODO(tc): This needs to be implemented in the TabStripModelDelegate.
- return false;
-
- default:
- NOTREACHED();
- }
- return false;
-}
-
-bool TabStripGtk::IsItemChecked(int command_id) const {
- DCHECK(command_id == kShowWindowDecorationsCommand);
- PrefService* prefs = model_->profile()->GetPrefs();
- return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
-}
-
-void TabStripGtk::ExecuteCommand(int command_id) {
- switch (command_id) {
- case TabStripModel::CommandNewTab:
- model_->delegate()->AddBlankTab(true);
- break;
-
- case TabStripModel::CommandRestoreTab:
- model_->delegate()->RestoreTab();
- break;
-
- case TabStripModel::CommandTaskManager:
- // TODO(tc): This needs to be implemented in the TabStripModelDelegate.
- NOTIMPLEMENTED();
- break;
-
- case kShowWindowDecorationsCommand:
- {
- PrefService* prefs = model_->profile()->GetPrefs();
- prefs->SetBoolean(prefs::kUseCustomChromeFrame,
- !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
- break;
- }
-
- default:
- NOTREACHED();
- }
-}
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h
index 93b953f..4e85403 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h
@@ -12,7 +12,6 @@
#include "base/gfx/rect.h"
#include "base/task.h"
#include "base/message_loop.h"
-#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/browser/gtk/tabs/tab_gtk.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/owned_widget_gtk.h"
@@ -22,7 +21,6 @@ class DraggedTabControllerGtk;
class TabStripGtk : public TabStripModelObserver,
public TabGtk::TabDelegate,
- public MenuGtk::Delegate,
public MessageLoopForUI::Observer {
public:
class TabAnimation;
@@ -189,10 +187,6 @@ class TabStripGtk : public TabStripModelObserver,
static void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation,
TabStripGtk* tabstrip);
- // Event handler for context menu popups.
- static gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event,
- TabStripGtk* tabstrip);
-
// drag-motion handler that is signaled when the user performs a drag in the
// tabstrip bounds.
static gboolean OnDragMotion(GtkWidget* widget, GdkDragContext* context,
@@ -282,17 +276,6 @@ class TabStripGtk : public TabStripModelObserver,
// during animations, so we can't use current_unselected_width_.
void LayoutNewTabButton(double last_tab_right, double unselected_width);
- // -- Context Menu -----------------------------------------------------------
-
- // On Windows, right clicking in the tab strip background brings up the
- // system menu. There's no such thing on linux, so we just show the menu
- // items we add to the menu.
- void ShowContextMenu();
- // MenuGtk::Delegate implementation:
- virtual bool IsCommandEnabled(int command_id) const;
- virtual bool IsItemChecked(int command_id) const;
- virtual void ExecuteCommand(int command_id);
-
// -- Link Drag & Drop ------------------------------------------------------
// Returns the bounds to render the drop at, in screen coordinates. Sets
@@ -385,9 +368,6 @@ class TabStripGtk : public TabStripModelObserver,
// the drag session.
scoped_ptr<DraggedTabControllerGtk> drag_controller_;
- // The context menu.
- scoped_ptr<MenuGtk> context_menu_;
-
// A factory that is used to construct a delayed callback to the
// ResizeLayoutTabsNow method.
ScopedRunnableMethodFactory<TabStripGtk> resize_layout_factory_;
diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h
index f56f984..2431883 100644
--- a/chrome/browser/tabs/tab_strip_model.h
+++ b/chrome/browser/tabs/tab_strip_model.h
@@ -420,7 +420,6 @@ class TabStripModel : public NotificationObserver {
CommandCloseTabsToRight,
CommandCloseTabsOpenedBy,
CommandRestoreTab,
- CommandTaskManager,
CommandLast
};
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 487c007..b474a99d 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -926,6 +926,8 @@
'browser/gtk/bookmark_utils_gtk.h',
'browser/gtk/bookmark_tree_model.cc',
'browser/gtk/bookmark_tree_model.h',
+ 'browser/gtk/browser_titlebar.cc',
+ 'browser/gtk/browser_titlebar.h',
'browser/gtk/browser_toolbar_gtk.cc',
'browser/gtk/browser_toolbar_gtk.h',
'browser/gtk/browser_window_factory_gtk.cc',