Hi, A couple months ago I submitted a patch to XDirectFB showing how to change a top-level X window's transparency through the X11 protocol. I called this patch the X-Transparency protocol extension.
I have now gotten around to integrating this X Extension into an X11 window manager. I choose sawfish because it is easily scriptable with a dialect of lisp and it seems to be pretty popular with XDirectFB users. Again, like the original protocol extension patch this sawfish patch is a simple 'proof of concept'. I have created wrappers around the xlib X-Transparency get/set calls that allow them to be called from a lisp-like script executed by the sawfish window manager. I have also created a sample .sawfishrc startup script that will allow top-level window transparency to be varied by dragging the mouse along the title bar of a window. You need to hold the control key while doing this drag. Control-drag mouse left on the title bar to increase transparency, Control-drag right to decrease it. Control doubleclick the title bar to toggle transparency. I took the sawfish source from the download page at http://sawmill.sourceforge.net. The patch is meant to be applied against sawfish-1.2-gtk1. If you download sawfish-1.2-gtk1.tgz and apply this patch, make sure that you run autoconf at the top of the sawfish source tree. This is because the patch touches configure.in, config.h.in and Makedefs.in and these files need to be regenerated using the autoconf system. Oh, and you do need to build sawfish against an X11 tree with the X-Transparency extension patch applied. Thanks for XDirectFB, it makes all this cool stuff possible. Scott Brumbaugh ;; .sawfishrc ;; ;; Some sample lisp functions showing how to use the x-transparency ;; librep functions in sawfish. Ctrl-Button1 double click on the tile ;; bar will change window transparency between fixed ;; values. Ctrl-Button1 drag mouse on the tile bar to vary ;; transparency. Drag left will decrease opacity, drag right will ;; increase opacity (require 'sawmill-defaults) ;; My preference (setq default-frame-style 'simple) ;; ;; Functions for setting the window transparency to fixed values ;; ;; ;; Some constants used to toggle window transparency. (defconst opaque-value 255 "The opacity value for a non-transparency window") (defconst transparent-value 200 "The opacity value for a transparency window") ;; Change the opacity of the window using the above values (defun set-transparent () (x-set-transparency (current-event-window) transparent-value)) (defun set-opaque () (x-set-transparency (current-event-window) opaque-value)) (defun toggle-transparency () "toggle top-level window transparency" (let* ((window (current-event-window)) (opacity (x-get-transparency window))) (if (equal opacity opaque-value) (set-transparent) (set-opaque)))) ;; ;; Functions for variable transparency of windows ;; ;; (defvar mark-position "The saved position of the pointer") (defvar mark-value "The saved value of window opacity") (defun mark-transparency () "Save initial pointer position and window opacity" (setq mark-position (car (query-button-press-pointer))) (setq mark-value (x-get-transparency (current-event-window)))) ;; Function which will change the window transparency based on ;; movement of the mouse. Requires that mark-transparency was called ;; initially This is a simple example, transparency is decreased if ;; the mouse is moved left, increased if the mouse is moved right. (defun vary-transparency () "Change the transparency of the window depending on which direction, left or right, the mouse has moved in the horizontal direction" (let* ((current-x (car (query-pointer nil)))) (if (< mark-position current-x) (setq mark-value (+ mark-value 10)) (setq mark-value (- mark-value 10))) (if (> mark-value 255) (setq mark-value 255)) (if (< mark-value 0) (setq mark-value 0)) (x-set-transparency (current-event-window) mark-value) (setq mark-position current-x))) ;; Function which will change the window transparency based on ;; movement of the mouse. Requires that mark-transparency was called ;; initially This example is a little more complex. The amount of transparency ;; change is proportional to how far the mouse has moved. (defun vary-transparency-2 () "Change the transparency of the window depending on how much the mouse has moved in the horizontal direction" (let* ((current-width (car (window-dimensions (current-event-window)))) (current-x (car (query-pointer nil)))) ;; Calculate the ration of the current mouse offset to the width ;; of the window (setq delta-trans (- current-x mark-position)) (setq delta-trans (/ delta-trans current-width)) ;; Renormalize to the maximum opacitiy value. If the mouse has ;; moved all the way across the windw the new opacity difference ;; should be maximum. (setq delta-trans (* delta-trans 255)) ;; Add this new delat transparency to the current transparency (setq mark-value (+ mark-value delta-trans)) ;; Clamp transparency to 0 on the low side and 255 on the high (if (> mark-value 255) (setq mark-value 255)) (if (< mark-value 0) (setq mark-value 0)) ;; Convert transparency back to an integer (setq mark-value (truncate mark-value)) (setq mark-value (inexact->exact mark-value)) ;; Set the transparency on the window with the new value (x-set-transparency (current-event-window) mark-value) ;; Save the current mouse position (setq mark-position current-x))) ;; Add the new functions to the window title-bars (bind-keys title-keymap "C-Button1-Click1" mark-transparency "C-Button1-Move" vary-transparency-2 "C-Button1-Click2" toggle-transparency) diff -Naur sawfish-1.2-gtk1.org/Makedefs.in sawfish-1.2-gtk1/Makedefs.in --- sawfish-1.2-gtk1.org/Makedefs.in Sat Nov 2 20:23:21 2002 +++ sawfish-1.2-gtk1/Makedefs.in Sun Mar 9 17:16:20 2003 @@ -54,7 +54,7 @@ LIBOBJS= [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ -lX11 @X_LIBS@ @X_EXTRA_LIBS@ [EMAIL PROTECTED]@ @XFT_LIBS@ -lXext [EMAIL PROTECTED]@ @XINERAMA_LIBS@ @XFT_LIBS@ -lXext [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ diff -Naur sawfish-1.2-gtk1.org/config.h.in sawfish-1.2-gtk1/config.h.in --- sawfish-1.2-gtk1.org/config.h.in Sat Nov 2 20:23:21 2002 +++ sawfish-1.2-gtk1/config.h.in Sun Mar 9 17:14:35 2003 @@ -86,6 +86,9 @@ /* Define if <X11/extensions/Xinerama.h> exists */ #undef HAVE_X11_EXTENSIONS_XINERAMA_H +/* Define if <X11/extensions/transparency.h> exists */ +#undef HAVE_X11_EXTENSIONS_TRANSPARENCY_H + /* Define if <X11/Xft/Xft.h> exists */ #undef HAVE_X11_XFT_XFT_H diff -Naur sawfish-1.2-gtk1.org/configure.in sawfish-1.2-gtk1/configure.in --- sawfish-1.2-gtk1.org/configure.in Sat Nov 9 21:39:53 2002 +++ sawfish-1.2-gtk1/configure.in Sun Mar 9 18:00:22 2003 @@ -91,6 +91,13 @@ AC_CHECK_HEADERS(X11/SM/SMlib.h X11/extensions/Xdbe.h) +XTRANSPARENCY_LIBS="" +AC_SUBST(XTRANSPARENCY_LIBS) +AC_CHECK_LIB(XTransparency, XTransparencyQueryExtension, + [XTRANSPARENCY_LIBS="-lXTransparency" + AC_CHECK_HEADERS(X11/extensions/transparency.h)], + [],[$X_LIBS -lX11 -lXext]) + XINERAMA_LIBS="" AC_SUBST(XINERAMA_LIBS) AC_CHECK_LIB(Xinerama, XineramaQueryScreens, diff -Naur sawfish-1.2-gtk1.org/src/functions.c sawfish-1.2-gtk1/src/functions.c --- sawfish-1.2-gtk1.org/src/functions.c Sun Nov 3 13:00:36 2002 +++ sawfish-1.2-gtk1/src/functions.c Sun Mar 9 18:18:38 2003 @@ -63,6 +63,11 @@ # endif #endif +#ifdef HAVE_X11_EXTENSIONS_TRANSPARENCY_H +#include <X11/extensions/transparency.h> +static int have_x_transparency; +#endif + DEFSYM(root, "root"); DEFSYM(after_restacking_hook, "after-restacking-hook"); DEFSYM(position, "position"); @@ -70,6 +75,54 @@ DEFSYM(window, "window"); DEFSYM(head, "head"); +#ifdef HAVE_X11_EXTENSIONS_TRANSPARENCY_H +DEFUN("x-get-transparency", Fx_get_transparency, Sx_get_transparency, + (repv win), rep_Subr1 ) /* +::doc:sawfish.wm.windows.subrs#x-get-transparency:: +x-get-transparency WINDOW + +Return the transparency of the top-level window WINDOW. Values +of transparency vary from 0 for invisible to 255 for opaque. +::end:: */ +{ + + OpacityValue value; + rep_DECLARE1(win, WINDOWP); + + if (have_x_transparency) + { + XGetTransparency(dpy, VWIN(win)->frame, &value); + return rep_MAKE_INT(value); + } else { + return Qnil; + } + +} + +DEFUN("x-set-transparency", Fx_set_transparency, Sx_set_transparency, + (repv win, repv value), rep_Subr2 ) /* +::doc:sawfish.wm.windows.subrs#x-set-transparency:: +x-set-transparency WINDOW VALUE + +Set the transparency of the top-level window WINDOW to VALUE. A +VALUE of 0 is invisible, 255 is fully opaque. +::end:: */ +{ + + rep_DECLARE1(win, WINDOWP); + rep_DECLARE2(value, rep_INTP); + + if (have_x_transparency) + { + XSetTransparency(dpy, VWIN(win)->frame, rep_INT(value)); + return Qt; + } else { + return Qnil; + } + +} +#endif /* HAVE_X11_EXTENSIONS_TRANSPARENCY_H */ + DEFUN("restack-windows", Frestack_windows, Srestack_windows, (repv list), rep_Subr1) /* ::doc:sawfish.wm.windows.subrs#restack-windows:: @@ -1322,6 +1375,8 @@ repv tem; tem = rep_push_structure ("sawfish.wm.windows.subrs"); + rep_ADD_SUBR(Sx_get_transparency); + rep_ADD_SUBR(Sx_set_transparency); rep_ADD_SUBR(Srestack_windows); rep_ADD_SUBR(Sx_raise_window); rep_ADD_SUBR(Sx_lower_window); @@ -1390,6 +1445,21 @@ xinerama_heads = debug_nheads; # endif #endif + +#ifdef HAVE_X11_EXTENSIONS_TRANSPARENCY_H + if (dpy != 0) + { + int event_base, error_base; + if (!XTransparencyQueryExtension(dpy, &event_base, &error_base)) { + fprintf(stderr, "Transparency extension not found\n"); + have_x_transparency=0; + } else { + fprintf(stderr, "Transparency extension found\n"); + have_x_transparency=1; + } + } +#endif + } void -- Info: To unsubscribe send a mail to [EMAIL PROTECTED] with "unsubscribe directfb-dev" as subject.
