diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 16:42:58 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 16:42:58 +0000 |
commit | 73ef1dc925c76e0f6d672a71a3463913678fe8e0 (patch) | |
tree | 7a1207a044225b9a97316c034db033cdd6219969 /chrome | |
parent | f12ab642b2bbe2107ef884beb7f8667b744a612e (diff) | |
download | chromium_src-73ef1dc925c76e0f6d672a71a3463913678fe8e0.zip chromium_src-73ef1dc925c76e0f6d672a71a3463913678fe8e0.tar.gz chromium_src-73ef1dc925c76e0f6d672a71a3463913678fe8e0.tar.bz2 |
GTK: allow drags on bookmark menu folder nodes.
Note that the folder menu can't be showing its submenu when the user starts the drag. Since the submenu shows automatically, the user actually has to click once to get rid of it before starting the drag.
BUG=30066
TEST=put a folder node in the other bookmarks folder. Drag it out of the other bookmarks folder and onto the bookmarks bar.
Review URL: http://codereview.chromium.org/799004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41166 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/bookmark_menu_controller_gtk.cc | 53 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_menu_controller_gtk.h | 14 |
2 files changed, 52 insertions, 15 deletions
diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc index a5f6066..b284f91 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc @@ -173,11 +173,11 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, SetImageMenuItem(menu_item, node, profile_->GetBookmarkModel()); gtk_util::SetAlwaysShowImage(menu_item); + g_signal_connect(menu_item, "button-release-event", + G_CALLBACK(OnButtonReleased), this); if (node->is_url()) { g_signal_connect(menu_item, "activate", G_CALLBACK(OnMenuItemActivated), this); - g_signal_connect(menu_item, "button-release-event", - G_CALLBACK(OnButtonReleased), this); } else if (node->is_folder()) { GtkWidget* submenu = gtk_menu_new(); BuildMenu(node, 0, submenu); @@ -199,6 +199,14 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, g_signal_connect(menu_item, "drag-data-get", G_CALLBACK(&OnMenuItemDragGet), this); + // It is important to connect to this signal after setting up the drag + // source because we only want to stifle the menu's default handler and + // not the handler that the drag source uses. + if (node->is_folder()) { + g_signal_connect(menu_item, "button-press-event", + G_CALLBACK(OnFolderButtonPressed), this); + } + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); node_to_menu_widget_map_[node] = menu_item; } @@ -284,22 +292,43 @@ gboolean BookmarkMenuController::OnButtonReleased( return FALSE; } - // Releasing either button 1 or 2 should trigger the bookmark menu. - if (event->button == 1 || event->button == 2) { - WindowOpenDisposition disposition = - event_utils::DispositionFromEventFlags(event->state); - controller->NavigateToMenuItem(sender, disposition); - - // We need to manually dismiss the popup menu because we're overriding - // button-release-event. - gtk_menu_popdown(GTK_MENU(controller->menu_)); - return TRUE; + // Releasing either button 1 or 2 should trigger the bookmark. + if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))) { + // The menu item is a link node. + if (event->button == 1 || event->button == 2) { + WindowOpenDisposition disposition = + event_utils::DispositionFromEventFlags(event->state); + controller->NavigateToMenuItem(sender, disposition); + + // We need to manually dismiss the popup menu because we're overriding + // button-release-event. + gtk_menu_popdown(GTK_MENU(controller->menu_)); + return TRUE; + } + } else { + // The menu item is a folder node. + if (event->button == 1) { + gtk_menu_popup(GTK_MENU(gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))), + sender->parent, sender, NULL, NULL, + event->button, event->time); + } } return FALSE; } // static +gboolean BookmarkMenuController::OnFolderButtonPressed( + GtkWidget* sender, + GdkEventButton* event, + BookmarkMenuController* controller) { + // The button press may start a drag; don't let the default handler run. + if (event->button == 1) + return TRUE; + return FALSE; +} + +// static void BookmarkMenuController::OnMenuHidden(GtkWidget* menu, BookmarkMenuController* controller) { if (controller->triggering_widget_) { diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.h b/chrome/browser/gtk/bookmark_menu_controller_gtk.h index b07b658..ea68a78 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.h +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.h @@ -63,15 +63,23 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, void NavigateToMenuItem(GtkWidget* menu_item, WindowOpenDisposition disposition); - // Button press and release events for a GtkMenuItem. We have to override - // these separate from OnMenuItemActivated because we need to handle right - // clicks and opening bookmarks with different dispositions. + // Button press and release events for a GtkMenu and GtkMenuItem, + // respectively. We have to override these separate from OnMenuItemActivated + // because we need to handle right clicks and opening bookmarks with + // different dispositions. static gboolean OnButtonPressed(GtkWidget* sender, GdkEventButton* event, BookmarkMenuController* controller); static gboolean OnButtonReleased(GtkWidget* sender, GdkEventButton* event, BookmarkMenuController* controller); + // We connect this handler to the button-press-event signal for folder nodes. + // It suppresses the normal behavior (popping up the submenu) to allow these + // nodes to be draggable. The submenu is instead popped up on a + // button-release-event. + static gboolean OnFolderButtonPressed(GtkWidget* sender, + GdkEventButton* event, + BookmarkMenuController* controller); // We have to stop drawing |triggering_widget_| as active when the menu // closes. |