summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 03:28:11 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 03:28:11 +0000
commiteda19d2232e18f89c69ddceedbfdefea3c0c722b (patch)
treeb9882e1c7c1cc0dca9752876b404680d82e75f0e /chrome
parentc6f2baf134f965f280fa1e1b26c9e225cad58a8f (diff)
downloadchromium_src-eda19d2232e18f89c69ddceedbfdefea3c0c722b.zip
chromium_src-eda19d2232e18f89c69ddceedbfdefea3c0c722b.tar.gz
chromium_src-eda19d2232e18f89c69ddceedbfdefea3c0c722b.tar.bz2
Implement window open disposition for (some) navigation buttons.
still need to do similar for link buttons and such. BUG=14518 Review URL: http://codereview.chromium.org/131071 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18786 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gtk/back_forward_button_gtk.cc22
-rw-r--r--chrome/browser/gtk/back_forward_button_gtk.h7
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc21
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h7
-rw-r--r--chrome/common/gtk_util.cc34
-rw-r--r--chrome/common/gtk_util.h6
6 files changed, 92 insertions, 5 deletions
diff --git a/chrome/browser/gtk/back_forward_button_gtk.cc b/chrome/browser/gtk/back_forward_button_gtk.cc
index e1cdd53..b9b2aa5 100644
--- a/chrome/browser/gtk/back_forward_button_gtk.cc
+++ b/chrome/browser/gtk/back_forward_button_gtk.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/gtk/back_forward_menu_model_gtk.h"
#include "chrome/browser/gtk/menu_gtk.h"
+#include "chrome/common/gtk_util.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -21,6 +22,7 @@ static const int kMenuTimerDelay = 500;
BackForwardButtonGtk::BackForwardButtonGtk(Browser* browser, bool is_forward)
: browser_(browser),
is_forward_(is_forward),
+ last_release_event_flags_(0),
show_menu_factory_(this) {
int normal, active, highlight, depressed, tooltip;
if (is_forward) {
@@ -49,6 +51,8 @@ BackForwardButtonGtk::BackForwardButtonGtk(Browser* browser, bool is_forward)
G_CALLBACK(OnClick), this);
g_signal_connect(widget(), "button-press-event",
G_CALLBACK(OnButtonPress), this);
+ g_signal_connect(widget(), "button-release-event",
+ G_CALLBACK(OnButtonRelease), this);
gtk_widget_add_events(widget(), GDK_POINTER_MOTION_MASK);
g_signal_connect(widget(), "motion-notify-event",
G_CALLBACK(OnMouseMove), this);
@@ -57,6 +61,8 @@ BackForwardButtonGtk::BackForwardButtonGtk(Browser* browser, bool is_forward)
// default of right aligned.
g_object_set_data(G_OBJECT(widget()), "left-align-popup",
reinterpret_cast<void*>(true));
+
+ gtk_util::SetButtonTriggersNavigation(widget());
}
BackForwardButtonGtk::~BackForwardButtonGtk() {
@@ -83,13 +89,18 @@ void BackForwardButtonGtk::OnClick(GtkWidget* widget,
BackForwardButtonGtk* button) {
button->show_menu_factory_.RevokeAll();
- button->browser_->ExecuteCommand(button->is_forward_ ?
- IDC_FORWARD : IDC_BACK);
+ DCHECK(button->last_release_event_flags_ != 0);
+ button->browser_->ExecuteCommandWithDisposition(
+ button->is_forward_ ? IDC_FORWARD : IDC_BACK,
+ event_utils::DispositionFromEventFlags(
+ button->last_release_event_flags_));
}
// static
gboolean BackForwardButtonGtk::OnButtonPress(GtkWidget* widget,
GdkEventButton* event, BackForwardButtonGtk* button) {
+ button->last_release_event_flags_ = 0;
+
if (event->button != 1)
return FALSE;
@@ -102,6 +113,13 @@ gboolean BackForwardButtonGtk::OnButtonPress(GtkWidget* widget,
}
// static
+gboolean BackForwardButtonGtk::OnButtonRelease(GtkWidget* widget,
+ GdkEventButton* event, BackForwardButtonGtk* button) {
+ button->last_release_event_flags_ = event->state;
+ return FALSE;
+}
+
+// static
gboolean BackForwardButtonGtk::OnMouseMove(GtkWidget* widget,
GdkEventMotion* event, BackForwardButtonGtk* button) {
// If we aren't waiting to show the back forward menu, do nothing.
diff --git a/chrome/browser/gtk/back_forward_button_gtk.h b/chrome/browser/gtk/back_forward_button_gtk.h
index 64af330..693ff40 100644
--- a/chrome/browser/gtk/back_forward_button_gtk.h
+++ b/chrome/browser/gtk/back_forward_button_gtk.h
@@ -36,6 +36,10 @@ class BackForwardButtonGtk {
GdkEventButton* event,
BackForwardButtonGtk* toolbar);
+ static gboolean OnButtonRelease(GtkWidget* button,
+ GdkEventButton* event,
+ BackForwardButtonGtk* toolbar);
+
// If there is a timer to show the dropdown menu, and the mouse has moved
// sufficiently down the screen, cancel the timer and immediately show the
// menu.
@@ -57,6 +61,9 @@ class BackForwardButtonGtk {
// Whether this button is a forward button.
bool is_forward_;
+ // The event state from the last button release.
+ int last_release_event_flags_;
+
// The dropdown menu delegate.
scoped_ptr<BackForwardMenuModelGtk> menu_model_;
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 761bc66..8633e65 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -26,6 +26,7 @@
#include "chrome/browser/gtk/toolbar_star_toggle_gtk.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/profile.h"
+#include "chrome/common/gtk_util.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
@@ -63,7 +64,8 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window)
model_(browser->toolbar_model()),
browser_(browser),
window_(window),
- profile_(NULL) {
+ profile_(NULL),
+ last_release_event_flags_(0) {
browser_->command_updater()->AddCommandObserver(IDC_BACK, this);
browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this);
browser_->command_updater()->AddCommandObserver(IDC_RELOAD, this);
@@ -130,6 +132,7 @@ void BrowserToolbarGtk::Init(Profile* profile,
home_.reset(BuildToolbarButton(IDR_HOME, IDR_HOME_P, IDR_HOME_H, 0,
l10n_util::GetStringUTF8(IDS_TOOLTIP_HOME)));
+ gtk_util::SetButtonTriggersNavigation(home_->widget());
// Group the start, omnibox, and go button into an hbox.
GtkWidget* omnibox_hbox_ = gtk_hbox_new(FALSE, 0);
@@ -305,6 +308,8 @@ CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton(
localized_tooltip.c_str());
g_signal_connect(button->widget(), "clicked",
G_CALLBACK(OnButtonClick), this);
+ g_signal_connect(button->widget(), "button-release-event",
+ G_CALLBACK(OnButtonRelease), this);
gtk_box_pack_start(GTK_BOX(toolbar_), button->widget(), FALSE, FALSE, 0);
return button;
@@ -373,8 +378,18 @@ void BrowserToolbarGtk::OnButtonClick(GtkWidget* button,
else if (button == toolbar->star_->widget())
tag = IDC_STAR;
- DCHECK_NE(tag, -1) << "Impossible button click callback";
- toolbar->browser_->ExecuteCommand(tag);
+ DCHECK_NE(tag, -1) << "Unexpected button click callback";
+ toolbar->browser_->ExecuteCommandWithDisposition(tag,
+ event_utils::DispositionFromEventFlags(
+ toolbar->last_release_event_flags_));
+}
+
+// static
+gboolean BrowserToolbarGtk::OnButtonRelease(GtkWidget* button,
+ GdkEventButton* event,
+ BrowserToolbarGtk* toolbar) {
+ toolbar->last_release_event_flags_ = event->state;
+ return FALSE;
}
// static
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index cbe288c..a636905 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -109,6 +109,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Gtk callback for the "clicked" signal.
static void OnButtonClick(GtkWidget* button, BrowserToolbarGtk* toolbar);
+ // Gtk callback for the "button-release-event" signal.
+ static gboolean OnButtonRelease(GtkWidget* button, GdkEventButton* event,
+ BrowserToolbarGtk* toolbar);
+
// Gtk callback to intercept mouse clicks to the menu buttons.
static gboolean OnMenuButtonPressEvent(GtkWidget* button,
GdkEventButton* event,
@@ -151,6 +155,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Controls whether or not a home button should be shown on the toolbar.
BooleanPrefMember show_home_button_;
+ // The event state the last time we observed a button release event.
+ int last_release_event_flags_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserToolbarGtk);
};
diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc
index b280a6b..4c9f052 100644
--- a/chrome/common/gtk_util.cc
+++ b/chrome/common/gtk_util.cc
@@ -19,6 +19,31 @@ void RemoveWidget(GtkWidget* widget, gpointer container) {
gtk_container_remove(GTK_CONTAINER(container), widget);
}
+// 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) {
+ 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)
+ gtk_button_pressed(GTK_BUTTON(widget));
+ }
+
+ return TRUE;
+}
+
+gboolean OnMouseButtonReleased(GtkWidget* widget, GdkEventButton* event,
+ gpointer unused) {
+ if (event->button == 1 || event->button == 2)
+ gtk_button_released(GTK_BUTTON(widget));
+
+ return TRUE;
+}
+
} // namespace
namespace event_utils {
@@ -207,4 +232,13 @@ void EnumerateChildWindows(EnumerateWindowsDelegate* delegate) {
g_list_free(stack);
}
+void SetButtonTriggersNavigation(GtkWidget* button) {
+ // We handle button activation manually because we want to accept middle mouse
+ // clicks.
+ g_signal_connect(G_OBJECT(button), "button-press-event",
+ G_CALLBACK(OnMouseButtonPressed), NULL);
+ g_signal_connect(G_OBJECT(button), "button-release-event",
+ G_CALLBACK(OnMouseButtonReleased), NULL);
+}
+
} // namespace gtk_util
diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h
index 92ea54e..b996c07 100644
--- a/chrome/common/gtk_util.h
+++ b/chrome/common/gtk_util.h
@@ -100,6 +100,12 @@ class EnumerateWindowsDelegate {
// Enumerates the top-level gdk windows of the current display.
void EnumerateChildWindows(EnumerateWindowsDelegate* delegate);
+// 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
+// those events.
+void SetButtonTriggersNavigation(GtkWidget* button);
+
} // namespace gtk_util
#endif // CHROME_COMMON_GTK_UTIL_H_