aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog35
-rw-r--r--configure.ac13
-rw-r--r--doc/MBWM2-Overview.xml142
-rw-r--r--src/core/mb-wm-client-base.c38
-rw-r--r--src/core/mb-wm-client.c24
-rw-r--r--src/core/mb-wm-client.h5
-rw-r--r--src/core/mb-wm-object-props.h1
-rw-r--r--src/managers/maemo/theme/background.pngbin21886 -> 24222 bytes
-rw-r--r--src/managers/maemo/theme/theme.xml6
-rw-r--r--src/theme-engines/mb-wm-theme-cairo.c6
-rw-r--r--src/theme-engines/mb-wm-theme-png.c207
-rw-r--r--src/theme-engines/mb-wm-theme-png.h1
-rw-r--r--src/theme-engines/mb-wm-theme-simple.c7
-rw-r--r--src/theme-engines/mb-wm-theme-xml.h2
-rw-r--r--src/theme-engines/mb-wm-theme.c44
-rw-r--r--src/theme-engines/mb-wm-theme.h65
16 files changed, 497 insertions, 99 deletions
diff --git a/ChangeLog b/ChangeLog
index aad3525..aef253b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index b273716..5ebb9be 100644
--- a/src/managers/maemo/theme/background.png
+++ b/src/managers/maemo/theme/background.png
Binary files differ
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,