- Revision
- 141498
- Author
- [email protected]
- Date
- 2013-01-31 15:46:03 -0800 (Thu, 31 Jan 2013)
Log Message
[Gtk] drag and drop has black background without composition
https://bugs.webkit.org/show_bug.cgi?id=108376
Patch by Arnaud Renevier <[email protected]> on 2013-01-31
Reviewed by Martin Robinson.
Use gtk_drag_set_icon_surface (or gtk_drag_set_icon_pixbuf) when the
screen is not composited. That way, drag window will be decomposited
and rendered transparent with Xshape.
To determine which parts of the window must be transparent, gtk checks
if a pixel is more than 50% opaque. With dissolveDragImageToFraction,
all pixels are made 25% transparent. With antialiasing, opacity goes
below the threshold for some pixels, which makes the resulting image
messy. So, we need to skip dissolveDragImageToFraction when we use
gtk_drag_set_icon_surface.
* platform/gtk/DragIcon.cpp:
(WebCore::DragIcon::DragIcon):
(WebCore::DragIcon::~DragIcon):
(WebCore::DragIcon::setImage):
(WebCore::DragIcon::useForDrag):
* platform/gtk/DragIcon.h:
(DragIcon):
* platform/gtk/DragImageGtk.cpp:
(WebCore::dissolveDragImageToFraction):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (141497 => 141498)
--- trunk/Source/WebCore/ChangeLog 2013-01-31 23:43:21 UTC (rev 141497)
+++ trunk/Source/WebCore/ChangeLog 2013-01-31 23:46:03 UTC (rev 141498)
@@ -1,3 +1,31 @@
+2013-01-31 Arnaud Renevier <[email protected]>
+
+ [Gtk] drag and drop has black background without composition
+ https://bugs.webkit.org/show_bug.cgi?id=108376
+
+ Reviewed by Martin Robinson.
+
+ Use gtk_drag_set_icon_surface (or gtk_drag_set_icon_pixbuf) when the
+ screen is not composited. That way, drag window will be decomposited
+ and rendered transparent with Xshape.
+
+ To determine which parts of the window must be transparent, gtk checks
+ if a pixel is more than 50% opaque. With dissolveDragImageToFraction,
+ all pixels are made 25% transparent. With antialiasing, opacity goes
+ below the threshold for some pixels, which makes the resulting image
+ messy. So, we need to skip dissolveDragImageToFraction when we use
+ gtk_drag_set_icon_surface.
+
+ * platform/gtk/DragIcon.cpp:
+ (WebCore::DragIcon::DragIcon):
+ (WebCore::DragIcon::~DragIcon):
+ (WebCore::DragIcon::setImage):
+ (WebCore::DragIcon::useForDrag):
+ * platform/gtk/DragIcon.h:
+ (DragIcon):
+ * platform/gtk/DragImageGtk.cpp:
+ (WebCore::dissolveDragImageToFraction):
+
2013-01-31 Tony Gentilcore <[email protected]>
Begin to make XSSAuditor thread aware
Modified: trunk/Source/WebCore/platform/gtk/DragIcon.cpp (141497 => 141498)
--- trunk/Source/WebCore/platform/gtk/DragIcon.cpp 2013-01-31 23:43:21 UTC (rev 141497)
+++ trunk/Source/WebCore/platform/gtk/DragIcon.cpp 2013-01-31 23:46:03 UTC (rev 141498)
@@ -25,6 +25,7 @@
#include "config.h"
#include "DragIcon.h"
+#include "GdkCairoUtilities.h"
#include <gtk/gtk.h>
@@ -48,8 +49,13 @@
#endif // GTK_API_VERSION_2
DragIcon::DragIcon()
- : m_window(gtk_window_new(GTK_WINDOW_POPUP))
+ : isComposited(gdk_screen_is_composited(gdk_screen_get_default()))
+ , m_window(0)
{
+ if (!isComposited)
+ return;
+
+ m_window = gtk_window_new(GTK_WINDOW_POPUP);
#ifdef GTK_API_VERSION_2
g_signal_connect(m_window, "expose-event", G_CALLBACK(dragIconWindowDrawEventCallback), this);
#else
@@ -72,7 +78,8 @@
DragIcon::~DragIcon()
{
- gtk_widget_destroy(m_window);
+ if (m_window)
+ gtk_widget_destroy(m_window);
}
void DragIcon::draw(cairo_t* context)
@@ -90,7 +97,14 @@
ASSERT(image);
m_image = image;
m_imageSize = IntSize(cairo_image_surface_get_width(image), cairo_image_surface_get_height(image));
- gtk_window_resize(GTK_WINDOW(m_window), m_imageSize.width(), m_imageSize.height());
+ if (isComposited) {
+ gtk_window_resize(GTK_WINDOW(m_window), m_imageSize.width(), m_imageSize.height());
+ return;
+ }
+
+#ifdef GTK_API_VERSION_2
+ m_pixbuf = adoptGRef(cairoImageSurfaceToGdkPixbuf(image));
+#endif
}
void DragIcon::useForDrag(GdkDragContext* context)
@@ -102,7 +116,15 @@
void DragIcon::useForDrag(GdkDragContext* context, const IntPoint& hotspot)
{
- gtk_drag_set_icon_widget(context, m_window, hotspot.x(), hotspot.y());
+ if (isComposited) {
+ gtk_drag_set_icon_widget(context, m_window, hotspot.x(), hotspot.y());
+ return;
+ }
+#ifdef GTK_API_VERSION_2
+ gtk_drag_set_icon_pixbuf(context, m_pixbuf.get(), hotspot.x(), hotspot.y());
+#else
+ gtk_drag_set_icon_surface(context, m_image.get());
+#endif
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/gtk/DragIcon.h (141497 => 141498)
--- trunk/Source/WebCore/platform/gtk/DragIcon.h 2013-01-31 23:43:21 UTC (rev 141497)
+++ trunk/Source/WebCore/platform/gtk/DragIcon.h 2013-01-31 23:46:03 UTC (rev 141498)
@@ -28,6 +28,7 @@
#include "IntPoint.h"
#include <RefPtrCairo.h>
+#include <wtf/gobject/GRefPtr.h>
namespace WebCore {
@@ -42,9 +43,13 @@
void useForDrag(GdkDragContext*, const IntPoint& hotspot);
private:
+ bool isComposited;
GtkWidget* m_window;
RefPtr<cairo_surface_t> m_image;
IntSize m_imageSize;
+#ifdef GTK_API_VERSION_2
+ GRefPtr<GdkPixbuf> m_pixbuf;
+#endif
};
}
Modified: trunk/Source/WebCore/platform/gtk/DragImageGtk.cpp (141497 => 141498)
--- trunk/Source/WebCore/platform/gtk/DragImageGtk.cpp 2013-01-31 23:43:21 UTC (rev 141497)
+++ trunk/Source/WebCore/platform/gtk/DragImageGtk.cpp 2013-01-31 23:46:03 UTC (rev 141498)
@@ -23,6 +23,7 @@
#include "Image.h"
#include "RefPtrCairo.h"
#include <cairo.h>
+#include <gdk/gdk.h>
namespace WebCore {
@@ -66,6 +67,9 @@
if (!image)
return 0;
+ if (!gdk_screen_is_composited(gdk_screen_get_default()))
+ return image;
+
RefPtr<cairo_t> context = adoptRef(cairo_create(image));
cairo_set_operator(context.get(), CAIRO_OPERATOR_DEST_IN);
cairo_set_source_rgba(context.get(), 0, 0, 0, fraction);