summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
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(