diff options
-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. |