From fa6f70ce3a1e5aff0cdafb4b641128f360278f2a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 20 Jun 2007 02:51:42 +0000 Subject: [PATCH] get the offscreen pixmaps for all windows (including their frames) --- Makefile.am | 2 ++ openbox/extensions.c | 23 +++++++++--- openbox/extensions.h | 2 +- openbox/frame.c | 84 ++++++++++++++++++++++++++++++-------------- openbox/frame.h | 4 +++ openbox/openbox.c | 3 ++ openbox/screen.c | 12 ++----- 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) -- 2.44.0