diff options
Diffstat (limited to 'chrome/browser/gtk/bookmark_menu_controller_gtk.cc')
-rw-r--r-- | chrome/browser/gtk/bookmark_menu_controller_gtk.cc | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc index a0d905b..af9e97f 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc @@ -11,6 +11,8 @@ #include "base/gfx/gtk_util.h" #include "base/string_util.h" #include "chrome/browser/gtk/bookmark_context_menu.h" +#include "chrome/browser/gtk/bookmark_utils_gtk.h" +#include "chrome/browser/gtk/dnd_registry.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/page_navigator.h" @@ -51,7 +53,8 @@ BookmarkMenuController::BookmarkMenuController(Browser* browser, profile_(profile), page_navigator_(navigator), parent_window_(window), - node_(node) { + node_(node), + ignore_button_release_(false) { menu_.Own(gtk_menu_new()); BuildMenu(node, start_child_index, menu_.get()); gtk_widget_show_all(menu_.get()); @@ -103,6 +106,7 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, GtkWidget* menu_item = gtk_image_menu_item_new_with_label( WideToUTF8(node->GetTitle()).c_str()); + g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node)); if (node->is_url()) { SkBitmap icon = profile_->GetBookmarkModel()->GetFavIcon(node); @@ -111,7 +115,6 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, GetBitmapNamed(IDR_DEFAULT_FAVICON); } SetImageMenuItem(menu_item, icon); - g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node)); g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(OnMenuItemActivated), this); g_signal_connect(G_OBJECT(menu_item), "button-press-event", @@ -130,6 +133,17 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, NOTREACHED(); } + gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK, + NULL, 0, GDK_ACTION_MOVE); + dnd::SetSourceTargetListFromCodeMask(menu_item, + dnd::X_CHROME_BOOKMARK_ITEM); + g_signal_connect(G_OBJECT(menu_item), "drag-begin", + G_CALLBACK(&OnMenuItemDragBegin), this); + g_signal_connect(G_OBJECT(menu_item), "drag-end", + G_CALLBACK(&OnMenuItemDragEnd), this); + g_signal_connect(G_OBJECT(menu_item), "drag-data-get", + G_CALLBACK(&OnMenuItemDragGet), this); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); node_to_menu_widget_map_[node] = menu_item; } @@ -146,6 +160,8 @@ gboolean BookmarkMenuController::OnButtonPressed( GtkWidget* sender, GdkEventButton* event, BookmarkMenuController* controller) { + controller->ignore_button_release_ = false; + if (event->button == 3) { // Show the right click menu and stop processing this button event. const BookmarkNode* node = GetNodeFromMenuItem(sender); @@ -168,9 +184,11 @@ gboolean BookmarkMenuController::OnButtonReleased( GtkWidget* sender, GdkEventButton* event, BookmarkMenuController* controller) { - // TODO(erg): The OnButtonPressed and OnButtonReleased handlers should have - // the same guard code that prevents them from interfering with DnD as - // BookmarkBarGtk's versions. + if (controller->ignore_button_release_) { + // Don't handle this message; it was a drag. + controller->ignore_button_release_ = false; + return FALSE; + } // Releasing either button 1 or 2 should trigger the bookmark menu. if (event->button == 1 || event->button == 2) { @@ -191,3 +209,47 @@ void BookmarkMenuController::OnMenuItemActivated( GtkMenuItem* menu_item, BookmarkMenuController* controller) { controller->NavigateToMenuItem(GTK_WIDGET(menu_item), CURRENT_TAB); } + +// static +void BookmarkMenuController::OnMenuItemDragBegin( + GtkWidget* menu_item, + GdkDragContext* drag_context, + BookmarkMenuController* controller) { + // The parent menu item might be removed during the drag. Ref it so |button| + // won't get destroyed. + g_object_ref(menu_item->parent); + + // Signal to any future OnButtonReleased calls that we're dragging instead of + // pressing. + controller->ignore_button_release_ = true; + + const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item); + GtkWidget* window = bookmark_utils::GetDragRepresentation(node, + controller->model_); + gint x, y; + gtk_widget_get_pointer(menu_item, &x, &y); + gtk_drag_set_icon_widget(drag_context, window, x, y); + + // Hide our node. + gtk_widget_hide(menu_item); +} + +// static +void BookmarkMenuController::OnMenuItemDragEnd( + GtkWidget* menu_item, + GdkDragContext* drag_context, + BookmarkMenuController* controller) { + gtk_widget_show(menu_item); + g_object_unref(menu_item->parent); +} + +// static +void BookmarkMenuController::OnMenuItemDragGet( + GtkWidget* widget, GdkDragContext* context, + GtkSelectionData* selection_data, + guint target_type, guint time, + BookmarkMenuController* controller) { + const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget); + bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type, + controller->profile_); +} |