summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 20:48:55 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 20:48:55 +0000
commit839cabf415f69301d024f2b96a68fce9494ab91a (patch)
treeb40a94ca465ac3432c3775862e7498eb3d1acb63 /chrome
parent42f1a14d1717c3e9f1a7d54ab7318c3dec8dea83 (diff)
downloadchromium_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
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc10
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h5
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.cc9
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.h5
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc6
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.h1
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(