зеркало из 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 "nsCRT.h"
|
||||||
|
|
||||||
#include "gfxASurface.h"
|
#include "gfxASurface.h"
|
||||||
|
#include "gfxXlibSurface.h"
|
||||||
|
#include "gfxContext.h"
|
||||||
#include "nsImageToPixbuf.h"
|
#include "nsImageToPixbuf.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsISelection.h"
|
#include "nsISelection.h"
|
||||||
|
|
||||||
|
// This sets how opaque the drag image is
|
||||||
|
#define DRAG_IMAGE_ALPHA_LEVEL 0.5
|
||||||
|
|
||||||
static PRLogModuleInfo *sDragLm = NULL;
|
static PRLogModuleInfo *sDragLm = NULL;
|
||||||
|
|
||||||
static const char gMimeListType[] = "application/x-moz-internal-item-list";
|
static const char gMimeListType[] = "application/x-moz-internal-item-list";
|
||||||
|
@ -202,27 +207,34 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
||||||
1,
|
1,
|
||||||
&event);
|
&event);
|
||||||
|
|
||||||
GdkPixbuf* dragPixbuf = nsnull;
|
PRBool needsFallbackIcon = PR_FALSE;
|
||||||
nsRect dragRect;
|
nsRect dragRect;
|
||||||
nsPresContext* pc;
|
nsPresContext* pc;
|
||||||
|
nsRefPtr<gfxASurface> surface;
|
||||||
if (mHasImage || mSelection) {
|
if (mHasImage || mSelection) {
|
||||||
nsRefPtr<gfxASurface> surface;
|
|
||||||
DrawDrag(aDOMNode, aRegion, mScreenX, mScreenY,
|
DrawDrag(aDOMNode, aRegion, mScreenX, mScreenY,
|
||||||
&dragRect, getter_AddRefs(surface), &pc);
|
&dragRect, getter_AddRefs(surface), &pc);
|
||||||
if (surface) {
|
|
||||||
dragPixbuf =
|
|
||||||
nsImageToPixbuf::SurfaceToPixbuf(surface, dragRect.width, dragRect.height);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragPixbuf) {
|
if (surface) {
|
||||||
PRInt32 sx = mScreenX, sy = mScreenY;
|
PRInt32 sx = mScreenX, sy = mScreenY;
|
||||||
ConvertToUnscaledDevPixels(pc, &sx, &sy);
|
ConvertToUnscaledDevPixels(pc, &sx, &sy);
|
||||||
gtk_drag_set_icon_pixbuf(context, dragPixbuf,
|
|
||||||
sx - NSToIntRound(dragRect.x),
|
PRInt32 offsetX = sx - NSToIntRound(dragRect.x);
|
||||||
sy - NSToIntRound(dragRect.y));
|
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;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (needsFallbackIcon)
|
||||||
gtk_drag_set_icon_default(context);
|
gtk_drag_set_icon_default(context);
|
||||||
|
|
||||||
gtk_target_list_unref(sourceList);
|
gtk_target_list_unref(sourceList);
|
||||||
|
@ -231,6 +243,56 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
||||||
return NS_OK;
|
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
|
NS_IMETHODIMP
|
||||||
nsDragService::StartDragSession()
|
nsDragService::StartDragSession()
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,6 +142,14 @@ private:
|
||||||
// get a list of the sources in gtk's format
|
// get a list of the sources in gtk's format
|
||||||
GtkTargetList *GetSourceList(void);
|
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__
|
#endif // nsDragService_h__
|
||||||
|
|
|
@ -1677,7 +1677,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
||||||
GetHasTransparentBackground(translucent);
|
GetHasTransparentBackground(translucent);
|
||||||
nsIntRect boundsRect;
|
nsIntRect boundsRect;
|
||||||
GdkPixmap* bufferPixmap = nsnull;
|
GdkPixmap* bufferPixmap = nsnull;
|
||||||
nsRefPtr<gfxXlibSurface> bufferPixmapSurface;
|
nsRefPtr<gfxASurface> bufferPixmapSurface;
|
||||||
|
|
||||||
updateRegion->GetBoundingBox(&boundsRect.x, &boundsRect.y,
|
updateRegion->GetBoundingBox(&boundsRect.x, &boundsRect.y,
|
||||||
&boundsRect.width, &boundsRect.height);
|
&boundsRect.width, &boundsRect.height);
|
||||||
|
@ -1715,13 +1715,8 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
|
||||||
gint depth = gdk_drawable_get_depth(d);
|
gint depth = gdk_drawable_get_depth(d);
|
||||||
bufferPixmap = gdk_pixmap_new(d, boundsRect.width, boundsRect.height, depth);
|
bufferPixmap = gdk_pixmap_new(d, boundsRect.width, boundsRect.height, depth);
|
||||||
if (bufferPixmap) {
|
if (bufferPixmap) {
|
||||||
GdkVisual* visual = gdk_drawable_get_visual(GDK_DRAWABLE(bufferPixmap));
|
bufferPixmapSurface = GetSurfaceForGdkDrawable(GDK_DRAWABLE(bufferPixmap),
|
||||||
Visual* XVisual = gdk_x11_visual_get_xvisual(visual);
|
boundsRect.Size());
|
||||||
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));
|
|
||||||
if (bufferPixmapSurface) {
|
if (bufferPixmapSurface) {
|
||||||
bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
|
bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
|
||||||
nsCOMPtr<nsIRenderingContext> newRC;
|
nsCOMPtr<nsIRenderingContext> newRC;
|
||||||
|
@ -6180,6 +6175,19 @@ IM_get_input_context(nsWindow *aWindow)
|
||||||
|
|
||||||
#endif
|
#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
|
// return the gfxASurface for rendering to this widget
|
||||||
gfxASurface*
|
gfxASurface*
|
||||||
nsWindow::GetThebesSurface()
|
nsWindow::GetThebesSurface()
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsWidgetAtoms.h"
|
#include "nsWidgetAtoms.h"
|
||||||
|
|
||||||
|
#include "gfxASurface.h"
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
|
@ -364,6 +366,9 @@ public:
|
||||||
|
|
||||||
gfxASurface *GetThebesSurface();
|
gfxASurface *GetThebesSurface();
|
||||||
|
|
||||||
|
static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||||
|
const nsSize& aSize);
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
static PRBool sAccessibilityEnabled;
|
static PRBool sAccessibilityEnabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче