Closed
Bug 376238
Opened 18 years ago
Closed 17 years ago
drag feedback should be transparent on gtk
Categories
(Core :: DOM: Copy & Paste and Drag & Drop, defect)
Tracking
()
RESOLVED
FIXED
mozilla1.9.1a1
People
(Reporter: enndeakin, Assigned: ventnor.bugzilla)
References
Details
Attachments
(3 files, 7 obsolete files)
|
3.15 KB,
patch
|
roc
:
review+
roc
:
superreview+
|
Details | Diff | Splinter Review |
|
3.35 KB,
patch
|
Details | Diff | Splinter Review | |
|
8.01 KB,
patch
|
roc
:
review+
roc
:
superreview+
|
Details | Diff | Splinter Review |
The drag feedback is currently opaque because otherwise artifacts appear on the image. Need to find out why.
Updated•18 years ago
|
Flags: blocking1.9?
| Reporter | ||
Comment 2•18 years ago
|
||
In reality, this is because gtk doesn't actually support translucent drag images. Alpha values are 'rounded' to 0 or 255.
So maybe this should just be disabled on linux, or just for larger images.
Comment 4•18 years ago
|
||
Neil, see bug 377823. This needs to be disabled in thunderbird as well, potentially conditionally on how many messages are dragged or what not.
Flags: blocking1.9? → blocking1.9-
Whiteboard: [wanted-1.9]
| Reporter | ||
Comment 5•18 years ago
|
||
As an interim measure, adding a pref to disable dragimages
Assignee: nobody → enndeakin
Status: NEW → ASSIGNED
Attachment #264479 -
Flags: superreview?(roc)
Attachment #264479 -
Flags: review?(roc)
Attachment #264479 -
Flags: superreview?(roc)
Attachment #264479 -
Flags: superreview+
Attachment #264479 -
Flags: review?(roc)
Attachment #264479 -
Flags: review+
| Reporter | ||
Comment 6•18 years ago
|
||
Checked in this patch.
Comment 7•18 years ago
|
||
Once this is fixed (given comment 2, will it ever be?), I think the content's background should be part of the drag feedback as well, e.g. when dragging text.
Updated•17 years ago
|
Flags: wanted1.9+
Whiteboard: [wanted-1.9]
Comment 9•17 years ago
|
||
Elaborating on comment 2, gtk sorta supports translucent drag images, and there is a way to work-around the limitation.
Using the existing code-path for gtk_drag_set_icon_pixbuf (used by widget/src/gtk2/nsDragService.cpp), if the display supports alpha-blended cursors and the composition of the cursor and the icon is smaller than the maximum cursor size (64 x 64 on my system) then everything should work. The problem is that the fall-back case creates a GTK window to hold the 'icon' image and explicitly thresholds the alpha for mask reasons. (Another complication is that without other code changes, the mozilla code uses an rgb colormap rather than an rgba one.)
The work-around is to call gtk_drag_set_icon_widget instead, passing a GTK window of your own to hold the image. Although this allows use of an rgba colormap and presumably that could allow extra fancy transparency, it's easier to just call gtk_window_set_opacity on the window since we only want a uniform level of transparency. (This just sets the _NET_WM_WINDOW_OPACITY property on the X window.)
All of this, of course, requires a compositing window manager using aiglx, Xgl, or friends.
I will attach a proof-of-concept (aka badly factored) patch to this bug that implements the gtk_window_set_opacity mechanism. Unfortunately, for reasons I do not understand (even after looking at the compiz sources), the transparency only works for me the first time I drag something, and even then intermittently. As far as I can tell, all of the window-manager-visible attributes of the window are consistent and the actual X window is destroyed. (But presumably I am missing something.)
Comment 10•17 years ago
|
||
| Assignee | ||
Comment 12•17 years ago
|
||
Nautilus managed to get this working by using pixmaps and some Cairo magic. This will make us use a pixmap with a semi-transparent pixbuf rendered on it, using similar Thebes operations as Nautilus does with Cairo.
This works beautifully, but like most things with transparent widgets, it needs a compositing window manager.
Assignee: enndeakin → ventnor.bugzilla
Attachment #325137 -
Flags: superreview?(roc)
Attachment #325137 -
Flags: review?(roc)
| Assignee | ||
Comment 13•17 years ago
|
||
Oops, found a last-second leak.
Attachment #325137 -
Attachment is obsolete: true
Attachment #325138 -
Flags: superreview?(roc)
Attachment #325138 -
Flags: review?(roc)
Attachment #325137 -
Flags: superreview?(roc)
Attachment #325137 -
Flags: review?(roc)
| Assignee | ||
Comment 14•17 years ago
|
||
Oops again, turns out something wasn't working like I hoped, causing an extremely serious leak :/
Attachment #325138 -
Attachment is obsolete: true
Attachment #325139 -
Flags: superreview?(roc)
Attachment #325139 -
Flags: review?(roc)
Attachment #325138 -
Flags: superreview?(roc)
Attachment #325138 -
Flags: review?(roc)
+ nsRefPtr<gfxContext> surfaceCtx = new gfxContext(aSurface);
+ surfaceCtx->SetOperator(gfxContext::OPERATOR_DEST_OUT);
+ surfaceCtx->Paint(0.3);
+
+ GdkPixbuf* pixbuf = nsImageToPixbuf::SurfaceToPixbuf(aSurface, dragRect.width, dragRect.height);
+ if (!pixbuf)
+ return PR_FALSE;
I think it's a bad idea to mangle aSurface and then return false. I know the alpha values aren't going to be used but probably the fallback image is darker because the premultiplied color channel values have decreased? Anyway, it's confusing. Just use a temporary surface here.
In fact, I think you can simplify this code by creating a gfxXlibSurface that wraps the pixmap. Then you can use cairo to clear it and then just draw aSurface into it with opacity 0.7. Don't need a temporary pixbuf at all.
| Assignee | ||
Comment 16•17 years ago
|
||
Yeah, using an Xlib surface works. It might even be faster, depending on how GDK compares with Thebes.
Attachment #325139 -
Attachment is obsolete: true
Attachment #325214 -
Flags: superreview?(roc)
Attachment #325214 -
Flags: review?(roc)
Attachment #325139 -
Flags: superreview?(roc)
Attachment #325139 -
Flags: review?(roc)
CreateAlphaPixbuf should be called SetAlphaPixmap I think. There's no pixbuf here any more.
+ nsRect dragRect)
const nsRect&
+ GdkVisual* visual = gdk_drawable_get_visual(GDK_DRAWABLE(pixmap));
+ Visual* XVisual = gdk_x11_visual_get_xvisual(visual);
+ Display* display = gdk_x11_drawable_get_xdisplay(GDK_DRAWABLE(pixmap));
+ Drawable drawable = gdk_x11_drawable_get_xid(GDK_DRAWABLE(pixmap));
This code is repeated in nsWindow::OnExposeEvent. We should be able to share it, perhaps via a static method in nsToolkit.cpp exposed via nsGTKToolit.h?
I'd use "xVisual" and "xPixmapSurface" and "xPixmapCtx" to conform to our naming conventions.
+ XPixmapCtx->Rectangle(gfxRect(0, 0, dragRect.width, dragRect.height));
+ XPixmapCtx->Fill();
xPixmapCtx->Paint(); --- that just fills the whole surface
+ XPixmapCtx->Paint(0.5);
0.7? Probably should make it a named #define constant at the top of the file to make it clear what this means.
| Assignee | ||
Comment 18•17 years ago
|
||
(In reply to comment #17)
> + GdkVisual* visual = gdk_drawable_get_visual(GDK_DRAWABLE(pixmap));
> + Visual* XVisual = gdk_x11_visual_get_xvisual(visual);
> + Display* display = gdk_x11_drawable_get_xdisplay(GDK_DRAWABLE(pixmap));
> + Drawable drawable = gdk_x11_drawable_get_xid(GDK_DRAWABLE(pixmap));
>
> This code is repeated in nsWindow::OnExposeEvent. We should be able to share
> it, perhaps via a static method in nsToolkit.cpp exposed via nsGTKToolit.h?
Not possible. There are consumers of nsGTKToolkit that can't access gfx and would cause compile errors.
Also, I changed it to 0.5 because it looked better.
Put it somewhere else then. A static method on nsWindow would work. Or create nsGtkUtils.h.
| Assignee | ||
Comment 20•17 years ago
|
||
Yeah, that works.
Attachment #325214 -
Attachment is obsolete: true
Attachment #325224 -
Flags: superreview?(roc)
Attachment #325224 -
Flags: review?(roc)
Attachment #325214 -
Flags: superreview?(roc)
Attachment #325214 -
Flags: review?(roc)
Comment on attachment 325224 [details] [diff] [review]
Patch 2.1
+/* static */ already_AddRefed<gfxXlibSurface>
+nsWindow::GetXSurfaceForGdkDrawable(GdkDrawable* aDrawable,
+ const nsSize& aSize)
Just one quibble. Make this gfxASurface and GetSurfaceForGdkDrawable. That will make life easier for the people doing GTK-DirectFB. I think the callers don't depend on this being an X surface.
Attachment #325224 -
Flags: superreview?(roc)
Attachment #325224 -
Flags: superreview+
Attachment #325224 -
Flags: review?(roc)
Attachment #325224 -
Flags: review+
| Assignee | ||
Comment 22•17 years ago
|
||
Attachment #325224 -
Attachment is obsolete: true
| Assignee | ||
Updated•17 years ago
|
Keywords: checkin-needed
Comment 23•17 years ago
|
||
Pushed in changeset 654d38d83392.
Status: ASSIGNED → RESOLVED
Closed: 17 years ago
Keywords: checkin-needed
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.9.1
Comment 24•17 years ago
|
||
Backed out due to test failures.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
| Assignee | ||
Comment 25•17 years ago
|
||
Don't use already_AddRefed<> because nsRefPtr isn't dumb like I thought. This will fix the test failures.
Attachment #325226 -
Attachment is obsolete: true
| Assignee | ||
Updated•17 years ago
|
Attachment #325387 -
Flags: superreview?(roc)
Attachment #325387 -
Flags: review?(roc)
It's best to avoid return a refcounted object with a zero refcount. So you should return already_AddRefed, but make sure that you actually add a ref.
| Assignee | ||
Comment 27•17 years ago
|
||
Attachment #325387 -
Attachment is obsolete: true
Attachment #325389 -
Flags: superreview?(roc)
Attachment #325389 -
Flags: review?(roc)
Attachment #325387 -
Flags: superreview?(roc)
Attachment #325387 -
Flags: review?(roc)
Attachment #325389 -
Flags: superreview?(roc)
Attachment #325389 -
Flags: superreview+
Attachment #325389 -
Flags: review?(roc)
Attachment #325389 -
Flags: review+
| Assignee | ||
Updated•17 years ago
|
Keywords: checkin-needed
Updated•17 years ago
|
Status: REOPENED → ASSIGNED
Comment 28•17 years ago
|
||
Landed in changeset a59b394a47aa
Status: ASSIGNED → RESOLVED
Closed: 17 years ago → 17 years ago
Keywords: checkin-needed
Resolution: --- → FIXED
Updated•17 years ago
|
Target Milestone: mozilla1.9.1 → mozilla1.9.1a1
You need to log in
before you can comment on or make changes to this bug.
Description
•