diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-19 03:28:11 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-19 03:28:11 +0000 |
commit | eda19d2232e18f89c69ddceedbfdefea3c0c722b (patch) | |
tree | b9882e1c7c1cc0dca9752876b404680d82e75f0e /chrome | |
parent | c6f2baf134f965f280fa1e1b26c9e225cad58a8f (diff) | |
download | chromium_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.cc | 22 | ||||
-rw-r--r-- | chrome/browser/gtk/back_forward_button_gtk.h | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 21 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 7 | ||||
-rw-r--r-- | chrome/common/gtk_util.cc | 34 | ||||
-rw-r--r-- | chrome/common/gtk_util.h | 6 |
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_ |