get the offscreen pixmaps for all windows (including their frames)
This commit is contained in:
parent
07cabeb946
commit
fa6f70ce3a
7 changed files with 89 additions and 41 deletions
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue