diff options
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | doc/MBWM2-Overview.xml | 142 | ||||
-rw-r--r-- | src/core/mb-wm-client-base.c | 38 | ||||
-rw-r--r-- | src/core/mb-wm-client.c | 24 | ||||
-rw-r--r-- | src/core/mb-wm-client.h | 5 | ||||
-rw-r--r-- | src/core/mb-wm-object-props.h | 1 | ||||
-rw-r--r-- | src/managers/maemo/theme/background.png | bin | 21886 -> 24222 bytes | |||
-rw-r--r-- | src/managers/maemo/theme/theme.xml | 6 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme-cairo.c | 6 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme-png.c | 207 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme-png.h | 1 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme-simple.c | 7 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme-xml.h | 2 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme.c | 44 | ||||
-rw-r--r-- | src/theme-engines/mb-wm-theme.h | 65 |
16 files changed, 497 insertions, 99 deletions
@@ -1,3 +1,34 @@ +2007-12-19 Tomas Frydrych <tf@o-hand.com> + + * configure.ac: + Check for Xext. + + * doc/MBWM2-Overview.xml: + Updated documentation. + + * src/core/mb-wm-client-base.c: + (mb_wm_client_base_display_sync): + + * src/core/mb-wm-client.c: + * src/core/mb-wm-client.h: + (mb_wm_client_init): + (mb_wm_client_is_argb32): + Added new mb_wm_client_is_argb32() function to simplify checking + for visual type. + + * src/core/mb-wm-object-props.h: + * src/theme-engines/mb-wm-theme-xml.h: + * src/theme-engines/mb-wm-theme.c: + * src/theme-engines/mb-wm-theme.h: + * src/theme-engines/mb-wm-theme-cairo.c: + * src/theme-engines/mb-wm-theme-simple.c: + Implemented shaped windows in PNG themes. + + * src/managers/maemo/theme/background.png: + * src/managers/maemo/theme/theme.xml: + Tweaked sample maemo theme to use shaped windows for dialogs and + notifications. + 2007-12-18 Tomas Frydrych <tf@o-hand.com> * data/themes/Default/theme.xml: @@ -7,10 +38,10 @@ Changed attributes engine_version and engine_type to engine-version and engine-type respectively, so as to make attribute makeup consistent. - + * doc/MBWM2-Overview.xml: Updated documetation. - + 2007-12-14 Tomas Frydrych <tf@o-hand.com> * src/core/mb-wm-decor.c: diff --git a/configure.ac b/configure.ac index 0fc4cde..e838e93 100644 --- a/configure.ac +++ b/configure.ac @@ -114,6 +114,12 @@ if test x$have_xfixes = xyes; then AC_DEFINE(HAVE_XFIXES, [1], [Use XFixes ext to really hide cursor]) fi +PKG_CHECK_MODULES(XEXT, xext, have_xext=yes, have_xext=no) + +if test x$have_xext = xyes; then + AC_DEFINE(HAVE_XEXT, [1], [Use Xext ext]) +fi + PKG_CHECK_MODULES(XCURSOR, xcursor, have_xcursor=yes, have_xcursor=no) if test x$have_xcursor = xyes; then @@ -125,8 +131,8 @@ MBWM_CORE_LIB='$(top_builddir)/src/core/libmatchbox-window-manager-2-core.a' MBWM_CLIENT_LIBS='$(top_builddir)/src/client-types' MBWM_THEME_LIBS='$(top_builddir)/src/theme-engines' MBWM_COMPMGR_LIBS='$(top_builddir)/src/comp-mgr' -MBWM_CFLAGS="$MBWM_CFLAGS $MBWM_DEBUG_CFLAGS $THEME_PNG_CFLAGS $XFIXES_CFLAGS $XCURSOR_CFLAGS" -MBWM_LIBS="$MBWM_LIBS $THEME_PNG_LIBS $XFIXES_LIBS $XCURSOR_LIBS" +MBWM_CFLAGS="$MBWM_CFLAGS $MBWM_DEBUG_CFLAGS $THEME_PNG_CFLAGS $XFIXES_CFLAGS $XEXT_CFLAGS $XCURSOR_CFLAGS" +MBWM_LIBS="$MBWM_LIBS $THEME_PNG_LIBS $XFIXES_LIBS $XEXT_LIBS $XCURSOR_LIBS" AC_SUBST([MBWM_CFLAGS]) AC_SUBST([MBWM_LIBS]) @@ -164,7 +170,8 @@ echo " Extension: Xfixes : ${have_xfixes} - Xcursor : ${have_cursor} + Xext : ${have_xext} + Xcursor : ${have_xcursor} Themes: Cairo theme : ${use_cairo} diff --git a/doc/MBWM2-Overview.xml b/doc/MBWM2-Overview.xml index 8e7e397..0505665 100644 --- a/doc/MBWM2-Overview.xml +++ b/doc/MBWM2-Overview.xml @@ -252,7 +252,8 @@ <listitem> <para>MBWMClientOverride, encapsulating windows with override-redirect - attribute set (this type is only used when running in compositing mode). + attribute set (this type is only used when running in compositing + mode, since override windows are, by definition, unmanaged). </para> </listitem> @@ -312,7 +313,9 @@ <title>MBWMLayout</title> <para>MBWMLayout provides the logic for distributing the screen real - estate between the managed clients. + estate between the managed clients. This is intrinsic to the MBWM2 + management paradigm, and should rarely need to be subclassed when + designing a custom manager. </para> </section> @@ -337,9 +340,63 @@ <para>MBWindowManager is the core object representing the window manager itself. It provides the essential functionality of the manager, which in - most cases will be extended through a custom sub-classed object. + most cases will be extended through a custom sub-classed object. To this + end, MBWindowManager exposes a number of virtual methods. </para> + <section id="MBWindowManager-virtuals"> + <title>MBWindowManager Virtual Methods</title> + + <itemizedlist> + + <listitem> + <para>process_cmdline: handles command-line options; if the custom + object implements this method, it should chain up to the method + provided by it's parent class, so that standard MBWM2 options get + handled correctly. + </para> + </listitem> + + <listitem> + <para>client_new: method used to allocate instances of + MBWindowManagerClient and its sub-classes; any manager that uses + custom MBWindowManagerClient sub-classes must implement this method. + </para> + </listitem> + + <listitem> + <para>layout_new: method used to allocate an instance of the + MBWMLayout object; this method needs to be implemented only if the + custom WM sub-classes MBWMLayout. + </para> + </listitem> + + <listitem> + <para>client_activate: method used to activate a client; this method + only needs to be implemented if the custom WM requires some special + action to be taken while activating a client (in which case the + custom method should chain up to that of the parent class). + </para> + </listitem> + + <listitem> + <para>client_hang: this method allows the custom WM to handle a hang + client in a specific way (the default action is to shut it down); + used as part of the ping protocol. + </para> + </listitem> + + <listitem> + <para>client_responding: this method allows the custom WM to handle + client's response to a ping in a specific way (the default action is + to NOP); used as part of the ping protocol. + </para> + </listitem> + + </itemizedlist> + + </section> + </section> </section> @@ -368,9 +425,30 @@ <title>Theming Matchbox Window Manager II</title> <para>The MBWM II theme consists of an XML description and, in case of a - PNG-based theme, the theme image (NB: coordinates in PNG-based themes are - absolute, relative to the top-left corner of the image). The XML description - uses the following elements: + PNG-based theme, the theme image. There are three distinct theme engines + provided: a simple engine, using back Xlib drawing primites, an engine + using cairo library, and PNG-based engine. + </para> + + <para>The simple and cairo engines are suitable for simple themes with + minimal frills. The PNG engine, on the other hand, facilitates the creation + of visually impressive and complex themes; it is based on single template + image, which contains all the elements the theme consists of, with the + location of each element is described in the xml description file. + Essentially, the PNG image can be thought of as a screen shot, or a mockup + of the screen; however, it does not have to match the size of the screen + (indeed, in order to save HW resources, the image should contain minimum of + 'dead' space). + </para> + + <para> + PNG themes can also use shaped windows; any transparent pixels in any of the + decorations will be excluded from the window shape (as long as the both the + theme and the relevant client is marked as using shaped windows in the XML + description). + </para> + + <para>The XML theme description uses the following elements: </para> <section id="element-theme"> @@ -392,7 +470,8 @@ </listitem> <listitem> - <para>desc: longer description of the theme. + <para>desc: longer description of the theme, e.g., for display in a + GUI theme switcher. </para> </listitem> @@ -408,8 +487,20 @@ <listitem> <para>engine-type: type of theme engine preferred by this theme; - legitimate values are "png" and "default" (if unspecified, falls back - to "default"). + legitimate values are "png" and "default" (default is "default"). + </para> + </listitem> + + <listitem> + <para>compositing: whether composting should be enabled for this + theme; "yes" or "no", default "no". + </para> + </listitem> + + <listitem> + <para>shaped: whether this theme uses shaped windows; "yes" or + "no", default "no" (only available for PNG themes; see the "client" + element for more information). </para> </listitem> @@ -446,15 +537,32 @@ <para>The client element has the following attributes: </para> - <itemizedlist> + <itemizedlist> - <listitem> - <para>type: the type of client to which this description applies; - legal values are "app", "dialog", "panel", "input", "desktop", - "notification" (client of type MBWMClientTypeMenu and - MBWMClientTypeOverride cannot be themed). - </para> - </listitem> + <listitem> + <para>type: the type of client to which this description applies; + legal values are "app", "dialog", "panel", "input", "desktop", + "notification" (client of type MBWMClientTypeMenu and + MBWMClientTypeOverride cannot be themed). + </para> + </listitem> + + <listitem> + <para>shaped: whether this client uses shaped windows; "yes" or + "no", default "no". (Shapped windows are only supported with PNG + themes, where the invisible parts of the decorations are + transparent in the theme image.) + </para> + </listitem> + + <listitem> + <para>x, y, width, height: geometry for the client. (Note that for + most client types it makes little sense to specify geometry in the + theme, and the values will be ignored. The notable exception to this + are panel clients, the position and size of which might be + theme-dependent, as for example, with the maemo status bar.) + </para> + </listitem> </itemizedlist> diff --git a/src/core/mb-wm-client-base.c b/src/core/mb-wm-client-base.c index 85b75cc..19953e0 100644 --- a/src/core/mb-wm-client-base.c +++ b/src/core/mb-wm-client-base.c @@ -26,6 +26,10 @@ #include <X11/extensions/Xrender.h> #endif +#ifdef HAVE_XEXT +#include <X11/extensions/shape.h> +#endif + static void mb_wm_client_base_realize (MBWindowManagerClient *client); @@ -152,19 +156,7 @@ mb_wm_client_base_realize (MBWindowManagerClient *client) if (client->xwin_frame == None) { #ifdef ENABLE_COMPOSITE - XRenderPictFormat *format; - Bool is_argb32 = False; - XSetWindowAttributes attr2; - - format = XRenderFindVisualFormat (wm->xdpy, client->window->visual); - - if (format && format->type == PictTypeDirect && - format->direct.alphaMask) - { - is_argb32 = True; - } - - if (is_argb32) + if (mb_wm_client_is_argb32 (client)) { attr.colormap = client->window->colormap; @@ -494,6 +486,26 @@ mb_wm_client_base_display_sync (MBWindowManagerClient *client) if (mb_wm_client_needs_decor_sync (client)) { + /* + * First, we set the base shape mask, if needed, so that individual + * decors can add themselves to it. + */ +#ifdef HAVE_XEXT + if (mb_wm_theme_is_client_shaped (wm->theme, client)) + { + XRectangle rects[1]; + + rects[0].x = client->window->geometry.x - client->frame_geometry.x; + rects[0].y = client->window->geometry.y - client->frame_geometry.y; + rects[0].width = client->window->geometry.width; + rects[0].height = client->window->geometry.height; + + XShapeCombineRectangles (wm->xdpy, client->xwin_frame, + ShapeBounding, + 0, 0, rects, 1, ShapeSet, 0 ); + } +#endif + if (fullscreen) { if (client->xwin_frame) diff --git a/src/core/mb-wm-client.c b/src/core/mb-wm-client.c index e79e847..2653386 100644 --- a/src/core/mb-wm-client.c +++ b/src/core/mb-wm-client.c @@ -24,6 +24,10 @@ #include <unistd.h> #include <signal.h> +#ifdef ENABLE_COMPOSITE +#include <X11/extensions/Xrender.h> +#endif + struct MBWindowManagerClientPriv { Bool realized; @@ -169,6 +173,20 @@ mb_wm_client_init (MBWMObject *obj, va_list vap) status, win->xwindow); +#ifdef ENABLE_COMPOSITE + { + XRenderPictFormat *format; + + format = XRenderFindVisualFormat (wm->xdpy, win->visual); + + if (format && format->type == PictTypeDirect && + format->direct.alphaMask) + { + client->is_argb32 = True; + } + } +#endif + return 1; } @@ -1010,3 +1028,9 @@ mb_wm_client_get_stacking_layer (MBWindowManagerClient *client) return client->stacking_layer; } +Bool +mb_wm_client_is_argb32 (MBWindowManagerClient *client) +{ + return client->is_argb32; +} + diff --git a/src/core/mb-wm-client.h b/src/core/mb-wm-client.h index d0749a9..af73e4c 100644 --- a/src/core/mb-wm-client.h +++ b/src/core/mb-wm-client.h @@ -167,6 +167,8 @@ struct MBWindowManagerClient unsigned long sig_theme_change_id; int ping_timeout; + Bool is_argb32; + #ifdef ENABLE_COMPOSITE MBWMCompMgrClient *cm_client; #endif @@ -358,4 +360,7 @@ mb_wm_client_get_stacking_layer (MBWindowManagerClient *client); void mb_wm_client_ping_start (MBWindowManagerClient *client); +Bool +mb_wm_client_is_argb32 (MBWindowManagerClient *client); + #endif diff --git a/src/core/mb-wm-object-props.h b/src/core/mb-wm-object-props.h index 96e1439..1f2379f 100644 --- a/src/core/mb-wm-object-props.h +++ b/src/core/mb-wm-object-props.h @@ -85,6 +85,7 @@ typedef enum MBWMObjectProp MBWMObjectPropThemeColorShadow = _MKOPROP(22, void*), MBWMObjectPropThemeShadowType = _MKOPROP(23, int), MBWMObjectPropThemeCompositing = _MKOPROP(24, int), + MBWMObjectPropThemeShaped = _MKOPROP(25, int), _MBWMObjectPropLastGlobal = 0x00fffff0, } diff --git a/src/managers/maemo/theme/background.png b/src/managers/maemo/theme/background.png Binary files differindex b273716..5ebb9be 100644 --- a/src/managers/maemo/theme/background.png +++ b/src/managers/maemo/theme/background.png diff --git a/src/managers/maemo/theme/theme.xml b/src/managers/maemo/theme/theme.xml index 99d8796..f752397 100644 --- a/src/managers/maemo/theme/theme.xml +++ b/src/managers/maemo/theme/theme.xml @@ -1,6 +1,6 @@ <?xml version="1.0"?> <theme name="Mockup Maemo theme" author="Tomas Frydrych, tf@o-hand.com" - desc="" version="1.0" engine-version="2" engine-type="png"> + desc="" version="1.0" engine-version="2" engine-type="png" shaped="yes"> <img src="background.png" /> <client type="app"> <decor type="north" show-title="yes" @@ -18,7 +18,7 @@ </decor> </client> -<client type="dialog"> +<client type="dialog" shaped="yes"> <decor type="north" show-title="yes" x="4" y="66" width="207" height="43" /> <decor type="south" x="4" y="119" width="207" height="5" /> @@ -26,7 +26,7 @@ <decor type="east" x="205" y="109" width="6" height="9" /> </client> -<client type="notification"> +<client type="notification" shaped="yes"> <decor type="north" x="215" y="104" width="207" height="5" /> <decor type="south" x="215" y="119" width="207" height="5" /> diff --git a/src/theme-engines/mb-wm-theme-cairo.c b/src/theme-engines/mb-wm-theme-cairo.c index ad5d901..b045e89 100644 --- a/src/theme-engines/mb-wm-theme-cairo.c +++ b/src/theme-engines/mb-wm-theme-cairo.c @@ -89,6 +89,12 @@ mb_wm_theme_cairo_init (MBWMObject *obj, va_list vap) gtk_widget_ensure_style (gwin); #endif + /* + * We do not support shaped windows, so reset the flag to avoid unnecessary + * ops if the xml theme set this + */ + theme->shaped = False; + return 1; } diff --git a/src/theme-engines/mb-wm-theme-png.c b/src/theme-engines/mb-wm-theme-png.c index c3a091e..cec6313 100644 --- a/src/theme-engines/mb-wm-theme-png.c +++ b/src/theme-engines/mb-wm-theme-png.c @@ -6,6 +6,10 @@ #include <X11/Xft/Xft.h> +#ifdef HAVE_XEXT +#include <X11/extensions/shape.h> +#endif + static int mb_wm_theme_png_ximg (MBWMThemePng * theme, const char * img); @@ -40,12 +44,12 @@ mb_wm_theme_png_class_init (MBWMObjectClass *klass) { MBWMThemeClass *t_class = MB_WM_THEME_CLASS (klass); - t_class->paint_decor = mb_wm_theme_png_paint_decor; - t_class->paint_button = mb_wm_theme_png_paint_button; - t_class->decor_dimensions = mb_wm_theme_png_get_decor_dimensions; - t_class->button_size = mb_wm_theme_png_get_button_size; - t_class->button_position = mb_wm_theme_png_get_button_position; - t_class->create_decor = mb_wm_theme_png_create_decor; + t_class->paint_decor = mb_wm_theme_png_paint_decor; + t_class->paint_button = mb_wm_theme_png_paint_button; + t_class->decor_dimensions = mb_wm_theme_png_get_decor_dimensions; + t_class->button_size = mb_wm_theme_png_get_button_size; + t_class->button_position = mb_wm_theme_png_get_button_position; + t_class->create_decor = mb_wm_theme_png_create_decor; #ifdef MBWM_WANT_DEBUG klass->klass_name = "MBWMThemePng"; @@ -60,6 +64,9 @@ mb_wm_theme_png_destroy (MBWMObject *obj) XRenderFreePicture (dpy, theme->xpic); XFreePixmap (dpy, theme->xdraw); + + if (theme->shape_mask) + XFreePixmap (dpy, theme->shape_mask); } static int @@ -114,6 +121,8 @@ mb_wm_theme_png_class_type () struct DecorData { Pixmap xpix; + Pixmap shape_mask; + GC gc_mask; XftDraw *xftdraw; XftColor clr; XftFont *font; @@ -126,6 +135,13 @@ decordata_free (MBWMDecor * decor, void *data) Display * xdpy = decor->parent_client->wmref->xdpy; XFreePixmap (xdpy, dd->xpix); + + if (dd->shape_mask) + XFreePixmap (xdpy, dd->shape_mask); + + if (dd->gc_mask) + XFreeGC (xdpy, dd->gc_mask); + XftDrawDestroy (dd->xftdraw); if (dd->font) @@ -276,16 +292,32 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) struct DecorData * data = mb_wm_decor_get_theme_data (decor); const char * title; int x, y; + Bool shaped; + +#ifdef HAVE_XEXT + shaped = theme->shaped && c->shaped && !mb_wm_client_is_argb32 (client); +#endif if (!data) { XRenderColor rclr; - data = malloc (sizeof (struct DecorData)); + data = mb_wm_util_malloc0 (sizeof (struct DecorData)); data->xpix = XCreatePixmap(xdpy, decor->xwin, decor->geom.width, decor->geom.height, DefaultDepth(xdpy, xscreen)); + +#ifdef HAVE_XEXT + if (shaped) + { + data->shape_mask = + XCreatePixmap(xdpy, decor->xwin, + decor->geom.width, decor->geom.height, 1); + + data->gc_mask = XCreateGC (xdpy, data->shape_mask, 0, NULL); + } +#endif data->xftdraw = XftDrawCreate (xdpy, data->xpix, DefaultVisual (xdpy, xscreen), DefaultColormap (xdpy, xscreen)); @@ -333,8 +365,6 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) int width2 = decor->geom.width - width1; int x2 = d->x + d->width - width2; - printf ("drawing small decor\n"); - XRenderComposite(xdpy, PictOpSrc, p_theme->xpic, None, @@ -349,18 +379,37 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) x2 , d->y, 0, 0, width1, 0, width2, d->height); + +#ifdef HAVE_XEXT + if (shaped) + { + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, d->y, width1, d->height, 0, 0); + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + x2, d->y, width2, d->height, width1, 0); + } +#endif } else if (decor->geom.width == d->width) { /* Exact match */ - printf ("drawing exact decor\n"); - XRenderComposite(xdpy, PictOpSrc, p_theme->xpic, None, XftDrawPicture (data->xftdraw), d->x, d->y, 0, 0, 0, 0, d->width, d->height); + +#ifdef HAVE_XEXT + if (shaped) + { + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, d->y, d->width, d->height, 0, 0); + } +#endif } else { @@ -375,9 +424,6 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) int width2i= d->width - 2 * strip; int x2i = d->x + strip; - printf ("drawing big decor, d->x %d, d->y %d\n", - d->x, d->y); - XRenderComposite(xdpy, PictOpSrc, p_theme->xpic, None, @@ -404,6 +450,27 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) x3 , d->y, 0, 0, width1 + width2, 0, width3, d->height); + +#ifdef HAVE_XEXT + if (shaped) + { + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, d->y, width1, d->height, 0, 0); + + for (x = width1; x < width1 + width2; x += width2i) + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + x2i, d->y, + (width1 + width2) - x >= width2i ? + width2i : width1 + width2 - x, + d->height, x, 0); + + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + x3, d->y, width3, d->height, width1 + width2, 0); + } +#endif } } else @@ -417,8 +484,6 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) int height2 = decor->geom.height - height1; int y2 = d->y + d->height - height2; - printf ("drawing small vertical decor\n"); - XRenderComposite(xdpy, PictOpSrc, p_theme->xpic, None, @@ -434,12 +499,22 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) d->x , y2, 0, 0, 0, height1, d->width, height2); + +#ifdef HAVE_XEXT + if (shaped) + { + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, d->y, d->width, height1, 0, 0); + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, y2, d->width, height2, 0, height1); + } +#endif } else if (decor->geom.height == d->height) { /* Exact match */ - printf ("drawing exact decor\n"); - XRenderComposite(xdpy, PictOpSrc, p_theme->xpic, None, @@ -447,6 +522,15 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) d->x, d->y, 0, 0, 0, 0, d->width, d->height); + +#ifdef HAVE_XEXT + if (shaped) + { + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, d->y, d->width, d->height, 0, 0); + } +#endif } else { @@ -461,9 +545,6 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) int height2i= d->height - 2 * strip; int y2i = d->y + strip; - printf ("drawing big vertical decor h1 %d, h2 %d, h2i %d\n", - height1, height2, height2i); - XRenderComposite(xdpy, PictOpSrc, p_theme->xpic, None, @@ -487,6 +568,26 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) XftDrawPicture (data->xftdraw), d->x , y3, 0, 0, 0, height1 + height2, d->width, height3); + +#ifdef HAVE_XEXT + if (shaped) + { + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, d->y, d->width, height1, 0, 0); + + for (y = height1; y < height1 + height2; y += height2i) + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, y2i, d->width, + (height1 + height2) - y >= height2i ? + height2i : height1 + height2 - y, 0, y); + + XCopyArea (xdpy, p_theme->shape_mask, data->shape_mask, + data->gc_mask, + d->x, y3, d->width, height3,0, height1 + height2); + } +#endif } } @@ -523,6 +624,20 @@ mb_wm_theme_png_paint_decor (MBWMTheme *theme, MBWMDecor *decor) XftDrawSetClipRectangles (data->xftdraw, 0, 0, &rec, 1); } +#ifdef HAVE_XEXT + if (shaped) + { + XShapeCombineMask (xdpy, decor->xwin, + ShapeBounding, 0, 0, + data->shape_mask, ShapeSet); + + XShapeCombineShape (xdpy, + client->xwin_frame, + ShapeBounding, decor->geom.x, decor->geom.y, + decor->xwin, + ShapeBounding, ShapeUnion); + } +#endif XClearWindow (xdpy, decor->xwin); } } @@ -849,8 +964,8 @@ mb_wm_theme_png_ximg (MBWMThemePng * theme, const char * img) Display * dpy = wm->xdpy; int screen = wm->xscreen; - XImage * ximg; - GC gc; + XImage * ximg, * shape_img; + GC gc, gcm; int x; int y; int width; @@ -859,6 +974,7 @@ mb_wm_theme_png_ximg (MBWMThemePng * theme, const char * img) XRenderPictureAttributes ren_attr; unsigned char * p; unsigned char * png_data = mb_wm_theme_png_load_file (img, &width, &height); + Bool shaped = MB_WM_THEME (theme)->shaped; if (!png_data || !width || !height) return 0; @@ -868,20 +984,36 @@ mb_wm_theme_png_ximg (MBWMThemePng * theme, const char * img) theme->xdraw = XCreatePixmap (dpy, RootWindow(dpy,screen), width, height, ren_fmt->depth); + if (shaped) + theme->shape_mask = + XCreatePixmap (dpy, RootWindow(dpy,screen), width, height, 1); + XSync (dpy, False); ren_attr.dither = True; ren_attr.component_alpha = True; ren_attr.repeat = False; - gc = XCreateGC (dpy, theme->xdraw, 0, NULL); + gc = XCreateGC (dpy, theme->xdraw, 0, NULL); - ximg = XCreateImage(dpy, DefaultVisual (dpy, screen), - ren_fmt->depth, ZPixmap, - 0, NULL, width, height, 32, 0); + if (shaped) + gcm = XCreateGC (dpy, theme->shape_mask, 0, NULL); + + ximg = XCreateImage (dpy, DefaultVisual (dpy, screen), + ren_fmt->depth, ZPixmap, + 0, NULL, width, height, 32, 0); ximg->data = malloc (ximg->bytes_per_line * ximg->height); + if (shaped) + { + shape_img = XCreateImage (dpy, DefaultVisual (dpy, screen), + 1, ZPixmap, + 0, NULL, width, height, 8, 0); + + shape_img->data = malloc (shape_img->bytes_per_line * shape_img->height); + } + p = png_data; for (y = 0; y < height; y++) @@ -892,11 +1024,21 @@ mb_wm_theme_png_ximg (MBWMThemePng * theme, const char * img) r = (r * (a + 1)) / 256; g = (g * (a + 1)) / 256; b = (b * (a + 1)) / 256; - XPutPixel(ximg, x, y, (a << 24) | (r << 16) | (g << 8) | b); + + XPutPixel (ximg, x, y, (a << 24) | (r << 16) | (g << 8) | b); + + if (shaped) + { + XPutPixel (shape_img, x, y, a ? 1 : 0); + } } XPutImage (dpy, theme->xdraw, gc, ximg, 0, 0, 0, 0, width, height); + if (shaped) + XPutImage (dpy, theme->shape_mask, gcm, shape_img, + 0, 0, 0, 0, width, height); + theme->xpic = XRenderCreatePicture (dpy, theme->xdraw, ren_fmt, CPRepeat|CPDither|CPComponentAlpha, &ren_attr); @@ -904,9 +1046,16 @@ mb_wm_theme_png_ximg (MBWMThemePng * theme, const char * img) free (ximg->data); ximg->data = NULL; XDestroyImage (ximg); - XFreeGC (dpy, gc); + if (shaped) + { + free (shape_img->data); + shape_img->data = NULL; + XDestroyImage (shape_img); + XFreeGC (dpy, gcm); + } + free (png_data); return 1; diff --git a/src/theme-engines/mb-wm-theme-png.h b/src/theme-engines/mb-wm-theme-png.h index e454d20..2cd1936 100644 --- a/src/theme-engines/mb-wm-theme-png.h +++ b/src/theme-engines/mb-wm-theme-png.h @@ -41,6 +41,7 @@ struct MBWMThemePng Pixmap xdraw; Picture xpic; + Pixmap shape_mask; }; #endif diff --git a/src/theme-engines/mb-wm-theme-simple.c b/src/theme-engines/mb-wm-theme-simple.c index ea2b4c6..db4df7c 100644 --- a/src/theme-engines/mb-wm-theme-simple.c +++ b/src/theme-engines/mb-wm-theme-simple.c @@ -51,6 +51,13 @@ mb_wm_theme_simple_destroy (MBWMObject *obj) static int mb_wm_theme_simple_init (MBWMObject *obj, va_list vap) { + MBWMTheme *theme = MB_WM_THEME (obj); + + /* + * We do not support shaped windows, so reset the flag to avoid unnecessary + * ops if the xml theme set this + */ + theme->shaped = False; return 1; } diff --git a/src/theme-engines/mb-wm-theme-xml.h b/src/theme-engines/mb-wm-theme-xml.h index e39afbd..b4d7571 100644 --- a/src/theme-engines/mb-wm-theme-xml.h +++ b/src/theme-engines/mb-wm-theme-xml.h @@ -56,6 +56,8 @@ typedef struct Client int width; int height; + Bool shaped; + MBWMList *decors; }MBWMXmlClient; diff --git a/src/theme-engines/mb-wm-theme.c b/src/theme-engines/mb-wm-theme.c index 7aa015d..bf0eb7b 100644 --- a/src/theme-engines/mb-wm-theme.c +++ b/src/theme-engines/mb-wm-theme.c @@ -97,6 +97,9 @@ mb_wm_theme_init (MBWMObject *obj, va_list vap) case MBWMObjectPropThemeCompositing: theme->compositing = va_arg(vap, int); break; + case MBWMObjectPropThemeShaped: + theme->shaped = va_arg(vap, int); + break; default: MBWMO_PROP_EAT (vap, prop); @@ -353,6 +356,7 @@ struct expat_data MBWMColor color_shadow; MBWMCompMgrShadowType shadow_type; Bool compositing; + Bool shaped; }; MBWMTheme * @@ -370,6 +374,7 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) MBWMColor clr_shadow; MBWMCompMgrShadowType shadow_type; Bool compositing; + Bool shaped; /* Attempt to parse the xml theme, if any, retrieving the theme type * @@ -435,8 +440,6 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) XML_SetUserData(par, (void *)&udata); - printf ("========= parsing [%s]\n", path); - while (fgets (buf, sizeof (buf), file) && XML_Parse(par, buf, strlen(buf), 0)); @@ -490,6 +493,7 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) shadow_type = udata.shadow_type; compositing = udata.compositing; + shaped = udata.shaped; xml_stack_free (udata.stack); } @@ -507,6 +511,7 @@ mb_wm_theme_new (MBWindowManager * wm, const char * theme_path) MBWMObjectPropThemeColorShadow, &clr_shadow, MBWMObjectPropThemeShadowType, shadow_type, MBWMObjectPropThemeCompositing, compositing, + MBWMObjectPropThemeShaped, shaped, NULL)); } @@ -589,6 +594,31 @@ mb_wm_theme_get_client_geometry (MBWMTheme * theme, return True; } +Bool +mb_wm_theme_is_client_shaped (MBWMTheme * theme, + MBWindowManagerClient * client) +{ +#ifdef HAVE_XEXT + MBWMXmlClient * c; + MBWMClientType c_type; + + if (!client || !theme || !theme->shaped || client->is_argb32) + return False; + + c_type = MB_WM_CLIENT_CLIENT_TYPE (client); + + if (theme->xml_clients && + (c = mb_wm_xml_client_find_by_type (theme->xml_clients, c_type))) + { + return c->shaped; + } + + return False; +#else + return False +#endif +} + /* * Retrieves color to be used for lowlighting (16-bit rgba) */ @@ -782,6 +812,11 @@ xml_element_start_cb (void *data, const char *tag, const char **expat_attr) exd->theme_type = MB_WM_TYPE_THEME_PNG; #endif } + else if (!strcmp (*p, "shaped")) + { + if (!strcmp (*(p+1), "yes") || !strcmp (*(p+1), "1")) + exd->shaped = 1; + } else if (!strcmp (*p, "clr-shadow")) { mb_wm_xml_clr_from_string (&clr, *(p+1)); @@ -849,6 +884,11 @@ xml_element_start_cb (void *data, const char *tag, const char **expat_attr) else if (!strcmp (*(p+1), "notification")) c->type = MBWMClientTypeNote; } + else if (!strcmp (*p, "shaped")) + { + if (!strcmp (*(p+1), "yes") || !strcmp (*(p+1), "1")) + c->shaped = 1; + } else if (!strcmp (*p, "width")) { c->width = atoi (*(p+1)); diff --git a/src/theme-engines/mb-wm-theme.h b/src/theme-engines/mb-wm-theme.h index c938210..8a1b28a 100644 --- a/src/theme-engines/mb-wm-theme.h +++ b/src/theme-engines/mb-wm-theme.h @@ -56,36 +56,36 @@ enum MBWMThemeCaps struct MBWMThemeClass { - MBWMObjectClass parent; - - void (*paint_decor) (MBWMTheme *theme, - MBWMDecor *decor); - - void (*paint_button) (MBWMTheme *theme, - MBWMDecorButton *button); - - void (*decor_dimensions) (MBWMTheme *theme, - MBWindowManagerClient *client, - int *north, - int *south, - int *west, - int *east); - - void (*button_size) (MBWMTheme *theme, - MBWMDecor *decor, - MBWMDecorButtonType type, - int *width, - int *height); - - void (*button_position) (MBWMTheme *theme, - MBWMDecor *decor, - MBWMDecorButtonType type, - int *x, - int *y); - - MBWMDecor* (*create_decor) (MBWMTheme *theme, - MBWindowManagerClient *client, - MBWMDecorType type); + MBWMObjectClass parent; + + void (*paint_decor) (MBWMTheme *theme, + MBWMDecor *decor); + + void (*paint_button) (MBWMTheme *theme, + MBWMDecorButton *button); + + void (*decor_dimensions) (MBWMTheme *theme, + MBWindowManagerClient *client, + int *north, + int *south, + int *west, + int *east); + + void (*button_size) (MBWMTheme *theme, + MBWMDecor *decor, + MBWMDecorButtonType type, + int *width, + int *height); + + void (*button_position) (MBWMTheme *theme, + MBWMDecor *decor, + MBWMDecorButtonType type, + int *x, + int *y); + + MBWMDecor* (*create_decor) (MBWMTheme *theme, + MBWindowManagerClient *client, + MBWMDecorType type); }; struct MBWMTheme @@ -98,6 +98,7 @@ struct MBWMTheme MBWMList *xml_clients; Bool compositing; + Bool shaped; MBWMColor color_lowlight; MBWMColor color_shadow; MBWMCompMgrShadowType shadow_type; @@ -158,6 +159,10 @@ mb_wm_theme_get_client_geometry (MBWMTheme * theme, MBWindowManagerClient * client, MBGeometry * geom); +Bool +mb_wm_theme_is_client_shaped (MBWMTheme * theme, + MBWindowManagerClient * client); + void mb_wm_theme_get_lowlight_color (MBWMTheme * theme, unsigned int * red, |