зеркало из https://github.com/mozilla/gecko-dev.git
Back out Ventron's patch in bug 376238 due to test failures.
This commit is contained in:
Родитель
3dff3690a9
Коммит
70feff0f85
|
@ -58,12 +58,17 @@
|
|||
#include "nsCRT.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxXlibSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsImageToPixbuf.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsISelection.h"
|
||||
|
||||
// This sets how opaque the drag image is
|
||||
#define DRAG_IMAGE_ALPHA_LEVEL 0.5
|
||||
|
||||
static PRLogModuleInfo *sDragLm = NULL;
|
||||
|
||||
static const char gMimeListType[] = "application/x-moz-internal-item-list";
|
||||
|
@ -202,27 +207,34 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
|||
1,
|
||||
&event);
|
||||
|
||||
GdkPixbuf* dragPixbuf = nsnull;
|
||||
PRBool needsFallbackIcon = PR_FALSE;
|
||||
nsRect dragRect;
|
||||
nsPresContext* pc;
|
||||
if (mHasImage || mSelection) {
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
if (mHasImage || mSelection) {
|
||||
DrawDrag(aDOMNode, aRegion, mScreenX, mScreenY,
|
||||
&dragRect, getter_AddRefs(surface), &pc);
|
||||
if (surface) {
|
||||
dragPixbuf =
|
||||
nsImageToPixbuf::SurfaceToPixbuf(surface, dragRect.width, dragRect.height);
|
||||
}
|
||||
}
|
||||
|
||||
if (dragPixbuf) {
|
||||
if (surface) {
|
||||
PRInt32 sx = mScreenX, sy = mScreenY;
|
||||
ConvertToUnscaledDevPixels(pc, &sx, &sy);
|
||||
gtk_drag_set_icon_pixbuf(context, dragPixbuf,
|
||||
sx - NSToIntRound(dragRect.x),
|
||||
sy - NSToIntRound(dragRect.y));
|
||||
}
|
||||
|
||||
PRInt32 offsetX = sx - NSToIntRound(dragRect.x);
|
||||
PRInt32 offsetY = sy - NSToIntRound(dragRect.y);
|
||||
if (!SetAlphaPixmap(surface, context, offsetX, offsetY, dragRect)) {
|
||||
GdkPixbuf* dragPixbuf =
|
||||
nsImageToPixbuf::SurfaceToPixbuf(surface, dragRect.width, dragRect.height);
|
||||
if (dragPixbuf)
|
||||
gtk_drag_set_icon_pixbuf(context, dragPixbuf, offsetX, offsetY);
|
||||
else
|
||||
needsFallbackIcon = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
needsFallbackIcon = PR_TRUE;
|
||||
}
|
||||
|
||||
if (needsFallbackIcon)
|
||||
gtk_drag_set_icon_default(context);
|
||||
|
||||
gtk_target_list_unref(sourceList);
|
||||
|
@ -231,6 +243,56 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDragService::SetAlphaPixmap(gfxASurface *aSurface,
|
||||
GdkDragContext *aContext,
|
||||
PRInt32 aXOffset,
|
||||
PRInt32 aYOffset,
|
||||
const nsRect& dragRect)
|
||||
{
|
||||
GdkScreen* screen = gtk_widget_get_screen(mHiddenWidget);
|
||||
|
||||
// Transparent drag icons need, like a lot of transparency-related things,
|
||||
// a compositing X window manager
|
||||
if (!gdk_screen_is_composited(screen))
|
||||
return PR_FALSE;
|
||||
|
||||
GdkColormap* alphaColormap = gdk_screen_get_rgba_colormap(screen);
|
||||
if (!alphaColormap)
|
||||
return PR_FALSE;
|
||||
|
||||
GdkPixmap* pixmap = gdk_pixmap_new(NULL, dragRect.width, dragRect.height,
|
||||
gdk_colormap_get_visual(alphaColormap)->depth);
|
||||
if (!pixmap)
|
||||
return PR_FALSE;
|
||||
|
||||
gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), alphaColormap);
|
||||
|
||||
// Make a gfxXlibSurface wrapped around the pixmap to render on
|
||||
nsRefPtr<gfxASurface> xPixmapSurface =
|
||||
nsWindow::GetSurfaceForGdkDrawable(GDK_DRAWABLE(pixmap),
|
||||
dragRect.Size());
|
||||
if (!xPixmapSurface)
|
||||
return PR_FALSE;
|
||||
|
||||
nsRefPtr<gfxContext> xPixmapCtx = new gfxContext(xPixmapSurface);
|
||||
|
||||
// Clear it...
|
||||
xPixmapCtx->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
xPixmapCtx->Paint();
|
||||
|
||||
// ...and paint the drag image with translucency
|
||||
xPixmapCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
xPixmapCtx->SetSource(aSurface);
|
||||
xPixmapCtx->Paint(DRAG_IMAGE_ALPHA_LEVEL);
|
||||
|
||||
// The drag transaction addrefs the pixmap, so we can just unref it from us here
|
||||
gtk_drag_set_icon_pixmap(aContext, alphaColormap, pixmap, NULL,
|
||||
aXOffset, aYOffset);
|
||||
gdk_pixmap_unref(pixmap);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDragService::StartDragSession()
|
||||
{
|
||||
|
|
|
@ -142,6 +142,14 @@ private:
|
|||
// get a list of the sources in gtk's format
|
||||
GtkTargetList *GetSourceList(void);
|
||||
|
||||
// attempts to create a semi-transparent drag image. Returns TRUE if
|
||||
// successful, FALSE if not
|
||||
PRBool SetAlphaPixmap(gfxASurface *aPixbuf,
|
||||
GdkDragContext *aContext,
|
||||
PRInt32 aXOffset,
|
||||
PRInt32 aYOffset,
|
||||
const nsRect& dragRect);
|
||||
|
||||
};
|
||||
|
||||
#endif // nsDragService_h__
|
||||
|
|
|
@ -1677,7 +1677,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
GetHasTransparentBackground(translucent);
|
||||
nsIntRect boundsRect;
|
||||
GdkPixmap* bufferPixmap = nsnull;
|
||||
nsRefPtr<gfxXlibSurface> bufferPixmapSurface;
|
||||
nsRefPtr<gfxASurface> bufferPixmapSurface;
|
||||
|
||||
updateRegion->GetBoundingBox(&boundsRect.x, &boundsRect.y,
|
||||
&boundsRect.width, &boundsRect.height);
|
||||
|
@ -1715,13 +1715,8 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
|||
gint depth = gdk_drawable_get_depth(d);
|
||||
bufferPixmap = gdk_pixmap_new(d, boundsRect.width, boundsRect.height, depth);
|
||||
if (bufferPixmap) {
|
||||
GdkVisual* visual = gdk_drawable_get_visual(GDK_DRAWABLE(bufferPixmap));
|
||||
Visual* XVisual = gdk_x11_visual_get_xvisual(visual);
|
||||
Display* display = gdk_x11_drawable_get_xdisplay(GDK_DRAWABLE(bufferPixmap));
|
||||
Drawable drawable = gdk_x11_drawable_get_xid(GDK_DRAWABLE(bufferPixmap));
|
||||
bufferPixmapSurface =
|
||||
new gfxXlibSurface(display, drawable, XVisual,
|
||||
gfxIntSize(boundsRect.width, boundsRect.height));
|
||||
bufferPixmapSurface = GetSurfaceForGdkDrawable(GDK_DRAWABLE(bufferPixmap),
|
||||
boundsRect.Size());
|
||||
if (bufferPixmapSurface) {
|
||||
bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
|
||||
nsCOMPtr<nsIRenderingContext> newRC;
|
||||
|
@ -6180,6 +6175,19 @@ IM_get_input_context(nsWindow *aWindow)
|
|||
|
||||
#endif
|
||||
|
||||
/* static */ already_AddRefed<gfxASurface>
|
||||
nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
const nsSize& aSize)
|
||||
{
|
||||
GdkVisual* visual = gdk_drawable_get_visual(aDrawable);
|
||||
Visual* xVisual = gdk_x11_visual_get_xvisual(visual);
|
||||
Display* xDisplay = gdk_x11_drawable_get_xdisplay(aDrawable);
|
||||
Drawable xDrawable = gdk_x11_drawable_get_xid(aDrawable);
|
||||
|
||||
return new gfxXlibSurface(xDisplay, xDrawable, xVisual,
|
||||
gfxIntSize(aSize.width, aSize.height));
|
||||
}
|
||||
|
||||
// return the gfxASurface for rendering to this widget
|
||||
gfxASurface*
|
||||
nsWindow::GetThebesSurface()
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
#include "nsITimer.h"
|
||||
#include "nsWidgetAtoms.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
|
@ -364,6 +366,9 @@ public:
|
|||
|
||||
gfxASurface *GetThebesSurface();
|
||||
|
||||
static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
const nsSize& aSize);
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
static PRBool sAccessibilityEnabled;
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче