summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authortony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-21 20:19:12 +0000
committertony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-21 20:19:12 +0000
commit840da55a87590507054a43cc550718022eef86b8 (patch)
treed94856626dd2d5f51bb61afaec47ac09b3959530 /chrome/browser
parentcdd9fea014653052e1e2fc2a354b8526235bc65f (diff)
downloadchromium_src-840da55a87590507054a43cc550718022eef86b8.zip
chromium_src-840da55a87590507054a43cc550718022eef86b8.tar.gz
chromium_src-840da55a87590507054a43cc550718022eef86b8.tar.bz2
Hack around the floating tab when using space/enter to end a drag.
We don't get a drag-end or a drag-failed event if the user presses space/enter, so we hack around this with a timer. I filed a bug with GTK+ upstream about not getting the event: https://bugzilla.gnome.org/show_bug.cgi?id=599130 BUG=21627 Review URL: http://codereview.chromium.org/300028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29697 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.cc25
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.h15
2 files changed, 38 insertions, 2 deletions
diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc
index 251f04f..4713063 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_gtk.cc
@@ -118,7 +118,8 @@ TabGtk::TabGtk(TabDelegate* delegate)
last_mouse_down_(NULL),
drag_widget_(NULL),
title_width_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(drag_end_factory_(this)) {
event_box_ = gtk_event_box_new();
gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_), FALSE);
g_signal_connect(G_OBJECT(event_box_), "button-press-event",
@@ -219,6 +220,19 @@ gboolean TabGtk::OnDragFailed(GtkWidget* widget, GdkDragContext* context,
}
// static
+gboolean TabGtk::OnDragButtonReleased(GtkWidget* widget, GdkEventButton* button,
+ TabGtk* tab) {
+ // We always get this event when gtk is releasing the grab and ending the
+ // drag. However, if the user ended the drag with space or enter, we don't
+ // get a follow up event to tell us the drag has finished (either a
+ // drag-failed or a drag-end). So we post a task to manually end the drag.
+ // If GTK+ does send the drag-failed or drag-end event, we cancel the task.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ tab->drag_end_factory_.NewRunnableMethod(&TabGtk::EndDrag, false));
+ return TRUE;
+}
+
+// static
void TabGtk::OnDragBegin(GtkWidget* widget, GdkDragContext* context,
TabGtk* tab) {
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
@@ -319,9 +333,12 @@ void TabGtk::UpdateTooltipState() {
}
void TabGtk::CreateDragWidget() {
+ DCHECK(!drag_widget_);
drag_widget_ = gtk_invisible_new();
g_signal_connect(drag_widget_, "drag-failed",
G_CALLBACK(OnDragFailed), this);
+ g_signal_connect(drag_widget_, "button-release-event",
+ G_CALLBACK(OnDragButtonReleased), this);
g_signal_connect_after(drag_widget_, "drag-begin",
G_CALLBACK(OnDragBegin), this);
}
@@ -338,7 +355,7 @@ void TabGtk::StartDragging(gfx::Point drag_offset) {
GtkTargetList* list = GtkDndUtil::GetTargetListFromCodeMask(
GtkDndUtil::CHROME_TAB);
- gtk_drag_begin(drag_widget_, list, GDK_ACTION_COPY,
+ gtk_drag_begin(drag_widget_, list, GDK_ACTION_MOVE,
1, // Drags are always initiated by the left button.
last_mouse_down_);
@@ -346,6 +363,10 @@ void TabGtk::StartDragging(gfx::Point drag_offset) {
}
void TabGtk::EndDrag(bool canceled) {
+ // Make sure we only run EndDrag once by canceling any tasks that want
+ // to call EndDrag.
+ drag_end_factory_.RevokeAll();
+
// We must let gtk clean up after we handle the drag operation, otherwise
// there will be outstanding references to the drag widget when we try to
// destroy it.
diff --git a/chrome/browser/gtk/tabs/tab_gtk.h b/chrome/browser/gtk/tabs/tab_gtk.h
index 5c3c662..c5a91d2 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_gtk.h
@@ -122,6 +122,14 @@ class TabGtk : public TabRendererGtk,
static gboolean OnDragFailed(GtkWidget* widget, GdkDragContext* context,
GtkDragResult result, TabGtk* tab);
+ // When a drag is ending, a fake button release event is passed to the drag
+ // widget to fake letting go of the mouse button. We need a callback for
+ // this event because it is the only way to catch drag end events when the
+ // user presses space or return.
+ static gboolean OnDragButtonReleased(GtkWidget* widget,
+ GdkEventButton* event,
+ TabGtk* tab);
+
// Shows the context menu.
void ShowContextMenu();
@@ -179,6 +187,13 @@ class TabGtk : public TabRendererGtk,
// Used to destroy the drag widget after a return to the message loop.
ScopedRunnableMethodFactory<TabGtk> destroy_factory_;
+ // Due to a bug in GTK+, we need to force the end of a drag when we get a
+ // mouse release event on the the dragged widget, otherwise, we don't know
+ // when the drag has ended when the user presses space or enter. We queue
+ // a task to end the drag and only run it if GTK+ didn't send us the
+ // drag-failed event.
+ ScopedRunnableMethodFactory<TabGtk> drag_end_factory_;
+
DISALLOW_COPY_AND_ASSIGN(TabGtk);
};