diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-23 20:48:55 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-23 20:48:55 +0000 |
commit | 839cabf415f69301d024f2b96a68fce9494ab91a (patch) | |
tree | b40a94ca465ac3432c3775862e7498eb3d1acb63 | |
parent | 42f1a14d1717c3e9f1a7d54ab7318c3dec8dea83 (diff) | |
download | chromium_src-839cabf415f69301d024f2b96a68fce9494ab91a.zip chromium_src-839cabf415f69301d024f2b96a68fce9494ab91a.tar.gz chromium_src-839cabf415f69301d024f2b96a68fce9494ab91a.tar.bz2 |
gtk: Fix the case where a user quickly moves the mouse away from a dragged tab
causing gtk to stop generating motion-notify-event signals. In this case,
a call to gtk_grab_add lets gtk clean up the drag for us.
BUG=16509
TEST=Quickly move the mouse away from a dragged tab (up and left works best).
The drag will end and a new window will open. The dragged tab window should
not still exist.
Review URL: http://codereview.chromium.org/159290
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21440 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc | 10 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h | 5 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_gtk.cc | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_gtk.h | 5 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_strip_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_strip_gtk.h | 1 |
6 files changed, 33 insertions, 3 deletions
diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc index 4625902..0052f01 100644 --- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc +++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc @@ -4,6 +4,8 @@ #include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h" +#include <algorithm> + #include "chrome/browser/browser.h" #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/gtk/tabs/dragged_tab_gtk.h" @@ -100,10 +102,16 @@ TabGtk* DraggedTabControllerGtk::GetDragSourceTabForContents( return NULL; } -bool DraggedTabControllerGtk::IsDragSourceTab(TabGtk* tab) const { +bool DraggedTabControllerGtk::IsDragSourceTab(const TabGtk* tab) const { return source_tab_ == tab; } +bool DraggedTabControllerGtk::IsTabDetached(const TabGtk* tab) const { + if (!IsDragSourceTab(tab)) + return false; + return (attached_tabstrip_ == NULL); +} + //////////////////////////////////////////////////////////////////////////////// // DraggedTabControllerGtk, TabContentsDelegate implementation: diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h index 5b1b66b..1b4b1ee 100644 --- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h +++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h @@ -48,7 +48,10 @@ class DraggedTabControllerGtk : public NotificationObserver, TabGtk* GetDragSourceTabForContents(TabContents* contents) const; // Returns true if the specified tab matches the tab being dragged. - bool IsDragSourceTab(TabGtk* tab) const; + bool IsDragSourceTab(const TabGtk* tab) const; + + // Returns true if the specified tab is detached. + bool IsTabDetached(const TabGtk* tab) const; private: // Enumeration of the ways a drag session can end. diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc index 8394bc4..90241100 100644 --- a/chrome/browser/gtk/tabs/tab_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_gtk.cc @@ -248,6 +248,15 @@ void TabGtk::DidProcessEvent(GdkEvent* event) { case GDK_MOTION_NOTIFY: delegate_->ContinueDrag(NULL); break; + case GDK_GRAB_BROKEN: + // If the user drags the mouse away from the dragged tab before the widget + // is created, gtk loses the grab used for the drag and we're stuck in a + // limbo where the drag is still active, but we don't get any + // motion-notify-event signals. Adding the grab back doesn't keep the + // drag alive, but it does get us out of this bind by finishing the drag. + if (delegate_->IsTabDetached(this)) + gtk_grab_add(widget()); + break; default: break; } diff --git a/chrome/browser/gtk/tabs/tab_gtk.h b/chrome/browser/gtk/tabs/tab_gtk.h index 384f7f6..4d1f704f 100644 --- a/chrome/browser/gtk/tabs/tab_gtk.h +++ b/chrome/browser/gtk/tabs/tab_gtk.h @@ -28,6 +28,9 @@ class TabGtk : public TabRendererGtk, // Returns true if the specified Tab is selected. virtual bool IsTabSelected(const TabGtk* tab) const = 0; + // Returns true if the specified Tab is detached. + virtual bool IsTabDetached(const TabGtk* tab) const = 0; + // Selects the specified Tab. virtual void SelectTab(TabGtk* tab) = 0; @@ -72,7 +75,7 @@ class TabGtk : public TabRendererGtk, virtual ThemeProvider* GetThemeProvider() = 0; }; - TabGtk(TabDelegate* delegate); + explicit TabGtk(TabDelegate* delegate); virtual ~TabGtk(); // Access the delegate. diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc index e8bc85e..85031ff 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -994,6 +994,12 @@ bool TabStripGtk::IsTabSelected(const TabGtk* tab) const { return GetIndexOfTab(tab) == model_->selected_index(); } +bool TabStripGtk::IsTabDetached(const TabGtk* tab) const { + if (drag_controller_.get()) + return drag_controller_->IsTabDetached(tab); + return false; +} + void TabStripGtk::GetCurrentTabWidths(double* unselected_width, double* selected_width) const { *unselected_width = current_unselected_width_; diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h index 5890e4a..fb11f50 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.h +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h @@ -106,6 +106,7 @@ class TabStripGtk : public TabStripModelObserver, // TabGtk::TabDelegate implementation: virtual bool IsTabSelected(const TabGtk* tab) const; + virtual bool IsTabDetached(const TabGtk* tab) const; virtual void SelectTab(TabGtk* tab); virtual void CloseTab(TabGtk* tab); virtual bool IsCommandEnabledForTab( |