summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--openbox/extensions.c23
-rw-r--r--openbox/extensions.h2
-rw-r--r--openbox/frame.c84
-rw-r--r--openbox/frame.h4
-rw-r--r--openbox/openbox.c3
-rw-r--r--openbox/screen.c12
7 files changed, 89 insertions, 41 deletions
diff --git a/Makefile.am b/Makefile.am
index 73a05eee..dbecc434 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -164,6 +164,8 @@ openbox_openbox_SOURCES = \
openbox/client_list_combined_menu.h \
openbox/client_menu.c \
openbox/client_menu.h \
+ openbox/composite.c \
+ openbox/composite.h \
openbox/config.c \
openbox/config.h \
openbox/debug.c \
diff --git a/openbox/extensions.c b/openbox/extensions.c
index 4f3a397c..2fdc6863 100644
--- a/openbox/extensions.c
+++ b/openbox/extensions.c
@@ -84,11 +84,19 @@ void extensions_query_all()
#endif
#ifdef USE_XCOMPOSITE
- extensions_comp =
- XRRQueryExtension(ob_display, &extensions_comp_event_basep,
- &junk);
+ if (XCompositeQueryExtension(ob_display, &extensions_comp_event_basep,
+ &junk))
+ {
+ gint major = 0, minor = 2;
+ XCompositeQueryVersion(ob_display, &major, &minor);
+ /* Version 0.2 is the first version to have the
+ XCompositeNameWindowPixmap() request. */
+ if (major > 0 || minor >= 2)
+ extensions_comp = TRUE;
+ }
if (!extensions_comp)
- ob_debug("X Composite extension is not present on the server\n");
+ ob_debug("X Composite extension is not present on the server or is an "
+ "incompatible version\n");
#endif
}
@@ -138,3 +146,10 @@ void extensions_xinerama_screens(Rect **xin_areas, guint *nxin)
}
RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1);
}
+
+#ifdef USE_XCOMPOSITE
+Picture extensions_create_composite_picture(Window win, Visual *vis,
+ gboolean *has_alpha)
+{
+}
+#endif
diff --git a/openbox/extensions.h b/openbox/extensions.h
index e1070e86..94bf0dbf 100644
--- a/openbox/extensions.h
+++ b/openbox/extensions.h
@@ -80,5 +80,5 @@ extern gint extensions_comp_event_basep;
void extensions_query_all();
void extensions_xinerama_screens(Rect **areas, guint *nxin);
-
+
#endif
diff --git a/openbox/frame.c b/openbox/frame.c
index 9ecee818..d88074c6 100644
--- a/openbox/frame.c
+++ b/openbox/frame.c
@@ -27,6 +27,7 @@
#include "mainloop.h"
#include "focus_cycle.h"
#include "focus_cycle_indicator.h"
+#include "composite.h"
#include "moveresize.h"
#include "screen.h"
#include "render/theme.h"
@@ -51,6 +52,8 @@ static void set_theme_statics(ObFrame *self);
static void free_theme_statics(ObFrame *self);
static gboolean frame_animate_iconify(gpointer self);
static void frame_adjust_cursors(ObFrame *self);
+static void frame_get_offscreen_buffer(ObFrame *self);
+static void frame_free_offscreen_buffer(ObFrame *self);
static Window createWindow(Window parent, Visual *visual,
gulong mask, XSetWindowAttributes *attrib)
@@ -62,58 +65,46 @@ static Window createWindow(Window parent, Visual *visual,
}
-static Visual *check_32bit_client(ObClient *c)
-{
- XWindowAttributes wattrib;
- Status ret;
-
- /* we're already running at 32 bit depth, yay. we don't need to use their
- visual */
- if (RrDepth(ob_rr_inst) == 32)
- return NULL;
-
- ret = XGetWindowAttributes(ob_display, c->window, &wattrib);
- g_assert(ret != BadDrawable);
- g_assert(ret != BadWindow);
-
- if (wattrib.depth == 32)
- return wattrib.visual;
- return NULL;
-}
-
ObFrame *frame_new(ObClient *client)
{
XSetWindowAttributes attrib;
gulong mask;
ObFrame *self;
- Visual *visual;
+ XWindowAttributes wattrib;
+ Status ret;
self = g_new0(ObFrame, 1);
self->client = client;
- visual = check_32bit_client(client);
+ ret = XGetWindowAttributes(ob_display, client->window, &wattrib);
+ g_assert(ret != BadDrawable);
+ g_assert(ret != BadWindow);
+ self->has_alpha = composite_window_has_alpha(wattrib.visual);
/* create the non-visible decor windows */
mask = 0;
- if (visual) {
- /* client has a 32-bit visual */
- mask |= CWColormap | CWBackPixel | CWBorderPixel;
+ if (self->has_alpha) {
+ /* the colormap/backpixel/borderpixel are required for supporting
+ windows with 32bit visuals */
+ mask = CWColormap | CWBackPixel | CWBorderPixel;
/* create a colormap with the visual */
self->colormap = attrib.colormap =
XCreateColormap(ob_display,
RootWindow(ob_display, ob_screen),
- visual, AllocNone);
+ wattrib.visual, AllocNone);
attrib.background_pixel = BlackPixel(ob_display, ob_screen);
attrib.border_pixel = BlackPixel(ob_display, ob_screen);
}
- self->window = createWindow(RootWindow(ob_display, ob_screen), visual,
+
+ self->window = createWindow(RootWindow(ob_display, ob_screen),
+ (self->has_alpha ? wattrib.visual : NULL),
mask, &attrib);
/* create the visible decor windows */
mask = 0;
- if (visual) {
+ if (self->has_alpha) {
/* client has a 32-bit visual */
mask |= CWColormap | CWBackPixel | CWBorderPixel;
attrib.colormap = RrColormap(ob_rr_inst);
@@ -240,6 +231,7 @@ void frame_free(ObFrame *self)
XDestroyWindow(ob_display, self->window);
if (self->colormap)
XFreeColormap(ob_display, self->colormap);
+ frame_free_offscreen_buffer(self);
g_free(self);
}
@@ -251,6 +243,8 @@ void frame_show(ObFrame *self)
framerender_frame(self);
XMapWindow(ob_display, self->client->window);
XMapWindow(ob_display, self->window);
+
+ frame_get_offscreen_buffer(self);
}
}
@@ -260,6 +254,7 @@ void frame_hide(ObFrame *self)
self->visible = FALSE;
if (!frame_iconify_animating(self))
XUnmapWindow(ob_display, self->window);
+
/* we unmap the client itself so that we can get MapRequest
events, and because the ICCCM tells us to! */
XUnmapWindow(ob_display, self->client->window);
@@ -317,6 +312,11 @@ void frame_adjust_shape(ObFrame *self)
ShapeBounding, 0, 0, xrect, num,
ShapeUnion, Unsorted);
}
+
+ if (self->pixmap)
+ XShapeCombineShape(ob_display, self->pixmap, ShapeBounding,
+ 0, 0, self->window, ShapeBounding, ShapeSet);
+
#endif
}
@@ -788,6 +788,10 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
self->need_render = TRUE;
framerender_frame(self);
frame_adjust_shape(self);
+
+ /* the offscreen buffer is invalid when the window is resized */
+ if (self->visible)
+ frame_get_offscreen_buffer(self);
}
if (!STRUT_EQUAL(self->size, oldsize)) {
@@ -1676,6 +1680,9 @@ void frame_end_iconify_animation(ObFrame *self)
/* Send a ConfigureNotify when the animation is done, this fixes
KDE's pager showing the window in the wrong place. */
client_reconfigure(self->client, TRUE);
+
+ /* the offscreen buffer is invalid when the window is resized */
+ frame_get_offscreen_buffer(self);
}
/* we're not animating any more ! */
@@ -1740,3 +1747,26 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
XMapWindow(ob_display, self->window);
}
}
+
+static void frame_get_offscreen_buffer(ObFrame *self)
+{
+ frame_free_offscreen_buffer(self);
+
+ if (self->visible || frame_iconify_animating(self)) {
+ self->pixmap = composite_get_window_pixmap(self->window);
+ /*
+ self->picture = composite_create_picture(self->window,
+ wattrib.visual,
+ &self->has_alpha);
+ */
+ }
+
+}
+
+static void frame_free_offscreen_buffer(ObFrame *self)
+{
+ if (self->pixmap) {
+ XFreePixmap(ob_display, self->pixmap);
+ self->pixmap = None;
+ }
+}
diff --git a/openbox/frame.h b/openbox/frame.h
index cf840bdf..c21860ee 100644
--- a/openbox/frame.h
+++ b/openbox/frame.h
@@ -78,6 +78,10 @@ struct _ObFrame
Window window;
+ Pixmap pixmap; /* Offscreen buffer of the frame window's contents
+ when Composite is enabled */
+ gboolean has_alpha;
+
Strut size;
Rect area;
gboolean visible;
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 1e1e3bf0..ae1232fa 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -34,6 +34,7 @@
#include "focus_cycle_indicator.h"
#include "focus_cycle_popup.h"
#include "moveresize.h"
+#include "composite.h"
#include "frame.h"
#include "keyboard.h"
#include "mouse.h"
@@ -297,6 +298,7 @@ gint main(gint argc, gchar **argv)
window_startup(reconfigure);
sn_startup(reconfigure);
screen_startup(reconfigure);
+ composite_startup(reconfigure);
grab_startup(reconfigure);
propwin_startup(reconfigure);
group_startup(reconfigure);
@@ -362,6 +364,7 @@ gint main(gint argc, gchar **argv)
group_shutdown(reconfigure);
propwin_shutdown(reconfigure);
grab_shutdown(reconfigure);
+ composite_shutdown(reconfigure);
screen_shutdown(reconfigure);
focus_cycle_popup_shutdown(reconfigure);
focus_cycle_indicator_shutdown(reconfigure);
diff --git a/openbox/screen.c b/openbox/screen.c
index 0f42b81c..4abf5b6c 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -364,15 +364,6 @@ void screen_startup(gboolean reconfig)
return;
}
-#ifdef USE_XCOMPOSITE
- if (extensions_comp) {
- /* Redirect window contents to offscreen pixmaps */
- XCompositeRedirectSubwindows(ob_display,
- RootWindow(ob_display, ob_screen),
- CompositeRedirectAutomatic);
- }
-#endif
-
/* get the initial size */
screen_resize();
@@ -499,6 +490,9 @@ void screen_resize()
for (it = client_list; it; it = g_list_next(it))
client_move_onscreen(it->data, FALSE);
+
+ /* this needs to be setup whenever the root window's size changes */
+ composite_setup_root_window();
}
void screen_set_num_desktops(guint num)