summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-01 00:35:16 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-01 00:35:16 +0000
commitbc10d9d99a26a7da6df8e359604bae90fa772e44 (patch)
tree8fd4c70adf1a85d669b0eab4f47679b4c7cb2935
parent47a4216e91764c7284582112408626ccaf8d9583 (diff)
downloadchromium_src-bc10d9d99a26a7da6df8e359604bae90fa772e44.zip
chromium_src-bc10d9d99a26a7da6df8e359604bae90fa772e44.tar.gz
chromium_src-bc10d9d99a26a7da6df8e359604bae90fa772e44.tar.bz2
GTK: add middle click and right click functionality to maximize button.
If the user right clicks on the maximize button, it will horizontally maximize the window, and if the user middle clicks on the maximize button it will vertically maximize the window. At least on kde, the window manager supports more complicated behavior, e.g. right clicking on a window that is horizontally maximized will return it to its former size. It seems to keep track of multiple restored rects. However, we're not well equipped to replicate this behavior, so I just didn't add it. If the user wants it, they can disable the custom frame. BUG=28881 Review URL: http://codereview.chromium.org/455012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33389 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/browser_titlebar.cc33
-rw-r--r--chrome/browser/gtk/browser_titlebar.h4
-rw-r--r--chrome/common/gtk_util.cc32
-rw-r--r--chrome/common/gtk_util.h5
4 files changed, 64 insertions, 10 deletions
diff --git a/chrome/browser/gtk/browser_titlebar.cc b/chrome/browser/gtk/browser_titlebar.cc
index 7d95754..55c192e 100644
--- a/chrome/browser/gtk/browser_titlebar.cc
+++ b/chrome/browser/gtk/browser_titlebar.cc
@@ -325,6 +325,9 @@ void BrowserTitlebar::Init() {
IDR_MINIMIZE_H, buttons_hbox,
IDS_XPFRAME_MINIMIZE_TOOLTIP));
+ gtk_util::SetButtonClickableByMouseButtons(maximize_button_->widget(),
+ true, true, true);
+
gtk_widget_size_request(close_button_->widget(), &close_button_req_);
gtk_widget_size_request(minimize_button_->widget(), &minimize_button_req_);
gtk_widget_size_request(restore_button_->widget(), &restore_button_req_);
@@ -504,6 +507,34 @@ void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) {
favicon_menu_->Popup(app_mode_favicon_, reinterpret_cast<GdkEvent*>(event));
}
+void BrowserTitlebar::MaximizeButtonClicked() {
+ GdkEventButton* event = &gtk_get_current_event()->button;
+ if (event->button == 1) {
+ gtk_window_maximize(window_);
+ } else {
+ GtkWidget* widget = GTK_WIDGET(window_);
+ GdkScreen* screen = gtk_widget_get_screen(widget);
+ gint monitor = gdk_screen_get_monitor_at_window(screen, widget->window);
+ GdkRectangle screen_rect;
+ gdk_screen_get_monitor_geometry(screen, monitor, &screen_rect);
+
+ gint x, y;
+ gtk_window_get_position(window_, &x, &y);
+ gint width = widget->allocation.width;
+ gint height = widget->allocation.height;
+
+ if (event->button == 3) {
+ x = 0;
+ width = screen_rect.width;
+ } else if (event->button == 2) {
+ y = 0;
+ height = screen_rect.height;
+ }
+
+ browser_window_->SetBounds(gfx::Rect(x, y, width, height));
+ }
+}
+
// static
gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
GdkEventWindowState* event, BrowserTitlebar* titlebar) {
@@ -544,7 +575,7 @@ void BrowserTitlebar::OnButtonClicked(GtkWidget* button,
} else if (titlebar->restore_button_->widget() == button) {
titlebar->browser_window_->UnMaximize();
} else if (titlebar->maximize_button_->widget() == button) {
- gtk_window_maximize(titlebar->window_);
+ titlebar->MaximizeButtonClicked();
} else if (titlebar->minimize_button_->widget() == button) {
gtk_window_iconify(titlebar->window_);
}
diff --git a/chrome/browser/gtk/browser_titlebar.h b/chrome/browser/gtk/browser_titlebar.h
index a9ace55..d9d75e1 100644
--- a/chrome/browser/gtk/browser_titlebar.h
+++ b/chrome/browser/gtk/browser_titlebar.h
@@ -98,6 +98,10 @@ class BrowserTitlebar : public MenuGtk::Delegate,
// Show the menu that the user gets from left-clicking the favicon.
void ShowFaviconMenu(GdkEventButton* event);
+ // The maximize button was clicked, take an action depending on which mouse
+ // button the user pressed.
+ void MaximizeButtonClicked();
+
// Callback for changes to window state. This includes
// maximizing/restoring/minimizing the window.
static gboolean OnWindowStateChanged(GtkWindow* window,
diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc
index 8cd0cf0..c6c08e4 100644
--- a/chrome/common/gtk_util.cc
+++ b/chrome/common/gtk_util.cc
@@ -28,14 +28,15 @@ void RemoveWidget(GtkWidget* widget, gpointer container) {
// These two functions are copped almost directly from gtk core. The only
// difference is that they accept middle clicks.
gboolean OnMouseButtonPressed(GtkWidget* widget, GdkEventButton* event,
- gpointer unused) {
+ gpointer userdata) {
if (event->type == GDK_BUTTON_PRESS) {
if (gtk_button_get_focus_on_click(GTK_BUTTON(widget)) &&
!GTK_WIDGET_HAS_FOCUS(widget)) {
gtk_widget_grab_focus(widget);
}
- if (event->button == 1 || event->button == 2)
+ gint button_mask = GPOINTER_TO_INT(userdata);
+ if (button_mask && (1 << event->button))
gtk_button_pressed(GTK_BUTTON(widget));
}
@@ -43,8 +44,9 @@ gboolean OnMouseButtonPressed(GtkWidget* widget, GdkEventButton* event,
}
gboolean OnMouseButtonReleased(GtkWidget* widget, GdkEventButton* event,
- gpointer unused) {
- if (event->button == 1 || event->button == 2)
+ gpointer userdata) {
+ gint button_mask = GPOINTER_TO_INT(userdata);
+ if (button_mask && (1 << event->button))
gtk_button_released(GTK_BUTTON(widget));
return TRUE;
@@ -325,13 +327,25 @@ void EnumerateTopLevelWindows(x11_util::EnumerateWindowsDelegate* delegate) {
}
}
-void SetButtonTriggersNavigation(GtkWidget* button) {
- // We handle button activation manually because we want to accept middle mouse
- // clicks.
+void SetButtonClickableByMouseButtons(GtkWidget* button,
+ bool left, bool middle, bool right) {
+ gint button_mask = 0;
+ if (left)
+ button_mask |= 1 << 1;
+ if (middle)
+ button_mask |= 1 << 2;
+ if (right)
+ button_mask |= 1 << 3;
+ void* userdata = GINT_TO_POINTER(button_mask);
+
g_signal_connect(G_OBJECT(button), "button-press-event",
- G_CALLBACK(OnMouseButtonPressed), NULL);
+ G_CALLBACK(OnMouseButtonPressed), userdata);
g_signal_connect(G_OBJECT(button), "button-release-event",
- G_CALLBACK(OnMouseButtonReleased), NULL);
+ G_CALLBACK(OnMouseButtonReleased), userdata);
+}
+
+void SetButtonTriggersNavigation(GtkWidget* button) {
+ SetButtonClickableByMouseButtons(button, true, true, false);
}
int MirroredLeftPointForRect(GtkWidget* widget, const gfx::Rect& bounds) {
diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h
index 384ac1f..7c10ce3 100644
--- a/chrome/common/gtk_util.h
+++ b/chrome/common/gtk_util.h
@@ -116,6 +116,11 @@ bool IsScreenComposited();
// Enumerates the top-level gdk windows of the current display.
void EnumerateTopLevelWindows(x11_util::EnumerateWindowsDelegate* delegate);
+// Set that clicking the button with the given mouse buttons will cause a click
+// event.
+void SetButtonClickableByMouseButtons(GtkWidget* button,
+ bool left, bool middle, bool right);
+
// Set that a button causes a page navigation. In particular, it will accept
// middle clicks. Warning: only call this *after* you have connected your
// own handlers for button-press and button-release events, or you will not get