2010-06-03 Martin Robinson <mrobinson@igalia.com>
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Jun 2010 20:08:53 +0000 (20:08 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Jun 2010 20:08:53 +0000 (20:08 +0000)
        Reviewed by Xan Lopez.

        [GTK] Drag gesture can take mouse grab indefinitely
        https://bugs.webkit.org/show_bug.cgi?id=32840

        Start GTK+ drags with the previous mouse button down event instead of
        synthesizing the event. The synthesized event was not completely valid
        and froze some drags indefinitely.

        * WebCoreSupport/DragClientGtk.cpp:
        (WebKit::buttonPressEvent): Added.
        (WebKit::DragClient::DragClient):
        Connect to the 'button-press-event' signal of the WebView.
        (WebKit::DragClient::startDrag):
        Instead of synthesizing a button press event use the last real one.
        * WebCoreSupport/DragClientGtk.h:
        (WebKit::DragClient::setLastButtonPressEvent): Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@60632 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/gtk/ChangeLog
WebKit/gtk/WebCoreSupport/DragClientGtk.cpp
WebKit/gtk/WebCoreSupport/DragClientGtk.h

index 4753aea..f3a9288 100644 (file)
@@ -1,3 +1,23 @@
+2010-06-03  Martin Robinson  <mrobinson@igalia.com>
+
+        Reviewed by Xan Lopez.
+
+        [GTK] Drag gesture can take mouse grab indefinitely
+        https://bugs.webkit.org/show_bug.cgi?id=32840
+
+        Start GTK+ drags with the previous mouse button down event instead of
+        synthesizing the event. The synthesized event was not completely valid
+        and froze some drags indefinitely.
+
+        * WebCoreSupport/DragClientGtk.cpp:
+        (WebKit::buttonPressEvent): Added.
+        (WebKit::DragClient::DragClient):
+        Connect to the 'button-press-event' signal of the WebView.
+        (WebKit::DragClient::startDrag):
+        Instead of synthesizing a button press event use the last real one.
+        * WebCoreSupport/DragClientGtk.h:
+        (WebKit::DragClient::setLastButtonPressEvent): Added.
+
 2010-06-01  Xan Lopez  <xlopez@igalia.com>
 
         Reviewed by Gustavo Noronha.
index c1e8e74..d1ba71f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) Igalia S.L.
+ * Copyright (C) 2010 Igalia S.L.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -29,7 +29,6 @@
 #include "GRefPtrGtk.h"
 #include "NotImplemented.h"
 #include "PasteboardHelper.h"
-#include "RenderObject.h"
 #include "webkitprivate.h"
 #include "webkitwebview.h"
 
@@ -42,10 +41,17 @@ using namespace WebCore;
 
 namespace WebKit {
 
+static gboolean buttonPressEvent(GtkWidget* widget, GdkEventButton* event, DragClient* client)
+{
+    client->setLastButtonPressEvent(gdk_event_copy(reinterpret_cast<GdkEvent*>(event)));
+    return FALSE;
+}
+
 DragClient::DragClient(WebKitWebView* webView)
     : m_webView(webView)
     , m_startPos(0, 0)
 {
+    g_signal_connect(webView, "button-press-event", G_CALLBACK(buttonPressEvent), this);
 }
 
 void DragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*)
@@ -72,25 +78,27 @@ DragSourceAction DragClient::dragSourceActionMaskForPoint(const IntPoint&)
 void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool linkDrag)
 {
     ClipboardGtk* clipboardGtk = reinterpret_cast<ClipboardGtk*>(clipboard);
-
-    WebKitWebView* webView = webkit_web_frame_get_web_view(kit(frame));
     RefPtr<DataObjectGtk> dataObject = clipboardGtk->dataObject();
-
     GRefPtr<GtkTargetList> targetList(clipboardGtk->helper()->targetListForDataObject(dataObject.get()));
-    GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
-    // This will be decremented by gdk_event_free() below.
-    event->button.window = static_cast<GdkWindow*>(g_object_ref(gtk_widget_get_window(GTK_WIDGET(m_webView))));
-    event->button.time = GDK_CURRENT_TIME;
 
-    GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragOperationToGdkDragActions(clipboard->sourceOperation()), 1, event);
-    webView->priv->draggingDataObjects.set(context, dataObject);
+    // The DRT does not use the GTK+ event queue for mouse down and motion
+    // events. Instead of using the gtk_get_current_event, we listen for mouse
+    // button-down-event signals on the WebView and use those events instead.
+    if (!m_lastButtonPressEvent)
+        return;
+
+    GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragOperationToGdkDragActions(clipboard->sourceOperation()), 1, m_lastButtonPressEvent.get());
+    setLastButtonPressEvent(0);
+
+    if (!context)
+        return;
+
+    m_webView->priv->draggingDataObjects.set(context, dataObject);
 
     if (image)
         gtk_drag_set_icon_pixbuf(context, image, eventPos.x() - dragImageOrigin.x(), eventPos.y() - dragImageOrigin.y());
     else
         gtk_drag_set_icon_default(context);
-
-    gdk_event_free(event);
 }
 
 DragImageRef DragClient::createDragImageForLink(KURL&, const String&, Frame*)
index 6604940..6382866 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2007 Apple Inc.  All rights reserved.
  * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2010 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define DragClientGtk_h
 
 #include "DragClient.h"
+#include "GOwnPtrGtk.h"
 
 typedef struct _WebKitWebView WebKitWebView;
+typedef union _GdkEvent GdkEvent;
 
 namespace WebKit {
 
@@ -50,10 +53,12 @@ namespace WebKit {
         virtual WebCore::DragImageRef createDragImageForLink(WebCore::KURL&, const WebCore::String& label, WebCore::Frame*);
 
         virtual void dragControllerDestroyed();
+        void setLastButtonPressEvent(GdkEvent* press) { m_lastButtonPressEvent.set(press); }
 
     private:
         WebKitWebView* m_webView;
         WebCore::IntPoint m_startPos;
+        GOwnPtr<GdkEvent> m_lastButtonPressEvent;
     };
 }