From 35adb7af142847fa5f57c7bf68598b612f4a3dd1 Mon Sep 17 00:00:00 2001 From: Ziro Yamane Date: Wed, 10 Dec 2008 00:58:51 -0500 Subject: [PATCH] Rework pseudo-transparency by changing the background grabbing mechanism Rely by default on commonly used _XROOTPMAP_ID pixmap content instead of using a relatively slow (and flicker-inducing) for grabbing the background image. The upside of this is that is seems to "fix" pseudo-transparency on many compositing managers (XFWM compositor, Kwin, Metacity, Compiz). --- AUTHORS | 3 +++ configure.ac | 16 ++++++++++++++++ doc/adesklets_en.texi | 12 ++++++++++++ doc/adesklets_fr.texi | 15 +++++++++++++++ src/xwindow.c | 40 +++++++++++++++++++++++++++++++++++----- 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 18a601f..7367dc9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -48,6 +48,9 @@ Other contributors: Luca Scarabello translated the poster to Italian. + Ziro Yamane provided a patch to fix pseudo-transparency under many + X11 compositing manager by using a more common grabing mechanism. + Miscellaneous: I also have to thank Carsten Haitzler et al. diff --git a/configure.ac b/configure.ac index 5071589..7ccebb4 100644 --- a/configure.ac +++ b/configure.ac @@ -276,6 +276,22 @@ else AC_MSG_RESULT([no]) fi +dnl Legacy pseudo transparency +enableval= +AC_MSG_CHECKING([for legacy pseudo transparency]) +AC_ARG_ENABLE(legacy-pseudo-transparency, +[ --enable-legacy-pseudo-transparency + Use the old code implementing pseudo-transparency + grabbing [default=no]]) +: ${enableval:=no} +if test x$enableval != "xno" ; then +AC_MSG_RESULT([yes]) +AC_DEFINE(FAKE_TRANSPARENCY_OLD_STYLE, 1, +[Use former pseudo transparency code]) +else +AC_MSG_RESULT([no]) +fi + dnl New frontend driver enableval= AC_MSG_CHECKING([for frontend shell driver]) diff --git a/doc/adesklets_en.texi b/doc/adesklets_en.texi index db558ba..963a3f8 100644 --- a/doc/adesklets_en.texi +++ b/doc/adesklets_en.texi @@ -2038,6 +2038,18 @@ to change the real root, but then you could have to rerun the adesklets launcher afterwards to take advantage of a correct initial background grab if no notification was sent. +@subheading What have you done? Transparency worked before, but now it's screwed! + +The default scheme for grabbing the content of the root window changed +after adesklets 0.6.1 to match what seems the current @emph{ad hoc} +consensus of relying on the content of the _XROOTPMAP_ID pixmap. On +the bright side, it means that adesklets pseudo-transparency will work +on most up-to-date windows managers, even when compositing is +involved. Unfortunately, it also means there is a chance it won't work +on some non-composited WM that did just fine before: you can still get +the old behavior back by specifying +@command{--enable-legacy-pseudo-transparency} at configuration time. + @subheading I cannot see smaller desklets such as xmms_bar or asimpleclock, while others work. What gives? New desklets are always started in the leftmost, upper corner of the screen, at diff --git a/doc/adesklets_fr.texi b/doc/adesklets_fr.texi index 7bb3a1c..3b28ccf 100644 --- a/doc/adesklets_fr.texi +++ b/doc/adesklets_fr.texi @@ -2168,6 +2168,21 @@ changer la vraie racine, mais ensuite vous aurez peut- le lanceur d'adesklets pour profiter d'une récupération initiale du papier peint correcte si aucune notification n'a été envoyée. +@subheading Qu'avez-vous fait? La transparence fonctionnait avant, alors que maintenant elle foire! + +La méthode employée pour capturer le contenu de la fenêtre racine a +changé après adesklets 0.6.1 pour correspondre à la pratique la plus +courante du moment dans ce type d'application, soit d'utiliser le +contenu du plan de bits _XROOTMAP_ID. Le bon côté de cette méthode est +que la pseudo-transparence de adesklets marchera dorénavant avec la +majorité des gestionnaires de fenêtres, incluant ceux utilisant la +composition (@emph{compositing}). Malheureusement, cela signifie +également qu'il existe une chance que certains des gestionnaires de +fenêtres sans composition plus anciens ne soient plus correctement +supportés. Vous pouvez rétablir le comportement antérieur en +spécifiant @command{--enable-legacy-pseudo-transparency} au moment de +la configuration. + @subheading Je ne peut pas voir les petits desklets comme xmms_bar ou asimpleclock, alors que les autres fonctionnent. Pourquoi? Les nouveaux desklets sont toujours lancés dans le coin le plus en haut à gauche de diff --git a/src/xwindow.c b/src/xwindow.c index 12ec3bd..301f772 100644 --- a/src/xwindow.c +++ b/src/xwindow.c @@ -245,18 +245,48 @@ Imlib_Image xwindow_grab_background(Display * display, int screen, Window window) { int x, y; - XEvent ev; Window src; XWindowAttributes attr; Imlib_Image background=NULL; +#ifndef FAKE_TRANSPARENCY_OLD_STYLE + Atom id, actual_type; + unsigned char *prop = NULL; + int actual_format; + unsigned long n_items; + unsigned long bytes_after; +#else + XEvent ev; +#endif if (!(display && window)) return NULL; if(XGetWindowAttributes(display,window,&attr) && /* Avoid reparenting coordinates translation problem */ XTranslateCoordinates(display,window,RootWindow(display,screen), - 0, 0, &x, &y, &src)) { - /* The trick is to create an Overrideredirect window overlapping our + 0, 0, &x, &y, &src)) +#ifndef FAKE_TRANSPARENCY_OLD_STYLE + /* Just get a background pixmap from _XROOTPMAP_ID */ + if ((id = XInternAtom(display, "_XROOTPMAP_ID", True)) && + XGetWindowProperty(display, DefaultRootWindow (display), + id, 0, 1, False, XA_PIXMAP, + &actual_type, &actual_format, + &n_items, &bytes_after, &prop) == Success && + prop) { + xwindow_context_save(IMLIB_DRAWABLE|IMLIB_IMAGE); + imlib_context_set_drawable(*((Drawable *)prop)); + background = imlib_create_image_from_drawable(0, + attr.x, attr.y, + attr.width, attr.height, + 0); + imlib_context_set_image(background); + imlib_image_set_has_alpha(1); + xwindow_context_restore(); + XFree(prop); + } +#else + /* This method was the default on adesklets <= 0.6.1 + + The trick is to create an Overrideredirect window overlapping our window with background type of Parent relative and then grab it. It seems overkill, but: - XGetImage() on root get all viewable children windows embedded. @@ -283,7 +313,7 @@ xwindow_grab_background(Display * display, int screen, Window window) XWindowEvent(display, src, ExposureMask, &ev); while(ev.type!=Expose); imlib_context_set_drawable(src); - background=imlib_create_image_from_drawable(0,0,0, + background=imlib_create_image_from_drawable(0, 0, 0, attr.width,attr.height,0); XUngrabServer(display); XDestroyWindow(display,src); @@ -295,7 +325,7 @@ xwindow_grab_background(Display * display, int screen, Window window) /* Restore context */ xwindow_context_restore(); } - } +#endif return background; } -- 2.11.4.GIT