summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/gtk/bookmark_menu_controller_gtk.cc53
-rw-r--r--chrome/browser/gtk/bookmark_menu_controller_gtk.h14
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.