get the offscreen pixmaps for all windows (including their frames)

This commit is contained in:
Dana Jansens 2007-06-20 02:51:42 +00:00
parent 07cabeb946
commit fa6f70ce3a
7 changed files with 89 additions and 41 deletions

View file

@ -164,6 +164,8 @@ openbox_openbox_SOURCES = \
openbox/client_list_combined_menu.h \ openbox/client_list_combined_menu.h \
openbox/client_menu.c \ openbox/client_menu.c \
openbox/client_menu.h \ openbox/client_menu.h \
openbox/composite.c \
openbox/composite.h \
openbox/config.c \ openbox/config.c \
openbox/config.h \ openbox/config.h \
openbox/debug.c \ openbox/debug.c \

View file

@ -84,11 +84,19 @@ void extensions_query_all()
#endif #endif
#ifdef USE_XCOMPOSITE #ifdef USE_XCOMPOSITE
extensions_comp = if (XCompositeQueryExtension(ob_display, &extensions_comp_event_basep,
XRRQueryExtension(ob_display, &extensions_comp_event_basep, &junk))
&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) 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 #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); 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

View file

@ -80,5 +80,5 @@ extern gint extensions_comp_event_basep;
void extensions_query_all(); void extensions_query_all();
void extensions_xinerama_screens(Rect **areas, guint *nxin); void extensions_xinerama_screens(Rect **areas, guint *nxin);
#endif #endif

View file

@ -27,6 +27,7 @@
#include "mainloop.h" #include "mainloop.h"
#include "focus_cycle.h" #include "focus_cycle.h"
#include "focus_cycle_indicator.h" #include "focus_cycle_indicator.h"
#include "composite.h"
#include "moveresize.h" #include "moveresize.h"
#include "screen.h" #include "screen.h"
#include "render/theme.h" #include "render/theme.h"
@ -51,6 +52,8 @@ static void set_theme_statics(ObFrame *self);
static void free_theme_statics(ObFrame *self); static void free_theme_statics(ObFrame *self);
static gboolean frame_animate_iconify(gpointer self); static gboolean frame_animate_iconify(gpointer self);
static void frame_adjust_cursors(ObFrame *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, static Window createWindow(Window parent, Visual *visual,
gulong mask, XSetWindowAttributes *attrib) 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) ObFrame *frame_new(ObClient *client)
{ {
XSetWindowAttributes attrib; XSetWindowAttributes attrib;
gulong mask; gulong mask;
ObFrame *self; ObFrame *self;
Visual *visual; XWindowAttributes wattrib;
Status ret;
self = g_new0(ObFrame, 1); self = g_new0(ObFrame, 1);
self->client = client; 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 */ /* create the non-visible decor windows */
mask = 0; mask = 0;
if (visual) { if (self->has_alpha) {
/* client has a 32-bit visual */ /* the colormap/backpixel/borderpixel are required for supporting
mask |= CWColormap | CWBackPixel | CWBorderPixel; windows with 32bit visuals */
mask = CWColormap | CWBackPixel | CWBorderPixel;
/* create a colormap with the visual */ /* create a colormap with the visual */
self->colormap = attrib.colormap = self->colormap = attrib.colormap =
XCreateColormap(ob_display, XCreateColormap(ob_display,
RootWindow(ob_display, ob_screen), RootWindow(ob_display, ob_screen),
visual, AllocNone); wattrib.visual, AllocNone);
attrib.background_pixel = BlackPixel(ob_display, ob_screen); attrib.background_pixel = BlackPixel(ob_display, ob_screen);
attrib.border_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); mask, &attrib);
/* create the visible decor windows */ /* create the visible decor windows */
mask = 0; mask = 0;
if (visual) { if (self->has_alpha) {
/* client has a 32-bit visual */ /* client has a 32-bit visual */
mask |= CWColormap | CWBackPixel | CWBorderPixel; mask |= CWColormap | CWBackPixel | CWBorderPixel;
attrib.colormap = RrColormap(ob_rr_inst); attrib.colormap = RrColormap(ob_rr_inst);
@ -240,6 +231,7 @@ void frame_free(ObFrame *self)
XDestroyWindow(ob_display, self->window); XDestroyWindow(ob_display, self->window);
if (self->colormap) if (self->colormap)
XFreeColormap(ob_display, self->colormap); XFreeColormap(ob_display, self->colormap);
frame_free_offscreen_buffer(self);
g_free(self); g_free(self);
} }
@ -251,6 +243,8 @@ void frame_show(ObFrame *self)
framerender_frame(self); framerender_frame(self);
XMapWindow(ob_display, self->client->window); XMapWindow(ob_display, self->client->window);
XMapWindow(ob_display, self->window); XMapWindow(ob_display, self->window);
frame_get_offscreen_buffer(self);
} }
} }
@ -260,6 +254,7 @@ void frame_hide(ObFrame *self)
self->visible = FALSE; self->visible = FALSE;
if (!frame_iconify_animating(self)) if (!frame_iconify_animating(self))
XUnmapWindow(ob_display, self->window); XUnmapWindow(ob_display, self->window);
/* we unmap the client itself so that we can get MapRequest /* we unmap the client itself so that we can get MapRequest
events, and because the ICCCM tells us to! */ events, and because the ICCCM tells us to! */
XUnmapWindow(ob_display, self->client->window); XUnmapWindow(ob_display, self->client->window);
@ -317,6 +312,11 @@ void frame_adjust_shape(ObFrame *self)
ShapeBounding, 0, 0, xrect, num, ShapeBounding, 0, 0, xrect, num,
ShapeUnion, Unsorted); ShapeUnion, Unsorted);
} }
if (self->pixmap)
XShapeCombineShape(ob_display, self->pixmap, ShapeBounding,
0, 0, self->window, ShapeBounding, ShapeSet);
#endif #endif
} }
@ -788,6 +788,10 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
self->need_render = TRUE; self->need_render = TRUE;
framerender_frame(self); framerender_frame(self);
frame_adjust_shape(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)) { 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 /* Send a ConfigureNotify when the animation is done, this fixes
KDE's pager showing the window in the wrong place. */ KDE's pager showing the window in the wrong place. */
client_reconfigure(self->client, TRUE); 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 ! */ /* we're not animating any more ! */
@ -1740,3 +1747,26 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
XMapWindow(ob_display, self->window); 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;
}
}

View file

@ -78,6 +78,10 @@ struct _ObFrame
Window window; Window window;
Pixmap pixmap; /* Offscreen buffer of the frame window's contents
when Composite is enabled */
gboolean has_alpha;
Strut size; Strut size;
Rect area; Rect area;
gboolean visible; gboolean visible;

View file

@ -34,6 +34,7 @@
#include "focus_cycle_indicator.h" #include "focus_cycle_indicator.h"
#include "focus_cycle_popup.h" #include "focus_cycle_popup.h"
#include "moveresize.h" #include "moveresize.h"
#include "composite.h"
#include "frame.h" #include "frame.h"
#include "keyboard.h" #include "keyboard.h"
#include "mouse.h" #include "mouse.h"
@ -297,6 +298,7 @@ gint main(gint argc, gchar **argv)
window_startup(reconfigure); window_startup(reconfigure);
sn_startup(reconfigure); sn_startup(reconfigure);
screen_startup(reconfigure); screen_startup(reconfigure);
composite_startup(reconfigure);
grab_startup(reconfigure); grab_startup(reconfigure);
propwin_startup(reconfigure); propwin_startup(reconfigure);
group_startup(reconfigure); group_startup(reconfigure);
@ -362,6 +364,7 @@ gint main(gint argc, gchar **argv)
group_shutdown(reconfigure); group_shutdown(reconfigure);
propwin_shutdown(reconfigure); propwin_shutdown(reconfigure);
grab_shutdown(reconfigure); grab_shutdown(reconfigure);
composite_shutdown(reconfigure);
screen_shutdown(reconfigure); screen_shutdown(reconfigure);
focus_cycle_popup_shutdown(reconfigure); focus_cycle_popup_shutdown(reconfigure);
focus_cycle_indicator_shutdown(reconfigure); focus_cycle_indicator_shutdown(reconfigure);

View file

@ -364,15 +364,6 @@ void screen_startup(gboolean reconfig)
return; 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 */ /* get the initial size */
screen_resize(); screen_resize();
@ -499,6 +490,9 @@ void screen_resize()
for (it = client_list; it; it = g_list_next(it)) for (it = client_list; it; it = g_list_next(it))
client_move_onscreen(it->data, FALSE); 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) void screen_set_num_desktops(guint num)