X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fframe.c;h=d88074c6aaf8dca3a7189529a093333c1841f495;hb=fa6f70ce3a1e5aff0cdafb4b641128f360278f2a;hp=aab30f1f182ae6791d318ce0fe28adfc3d75a03c;hpb=44bc0dab886c924b6aac1d3f1eaf4cc0164950c9;p=chaz%2Fopenbox diff --git a/openbox/frame.c b/openbox/frame.c index aab30f1f..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); @@ -124,6 +115,11 @@ ObFrame *frame_new(ObClient *client) mask |= CWEventMask; attrib.event_mask = ELEMENT_EVENTMASK; + self->innerleft = createWindow(self->window, NULL, mask, &attrib); + self->innertop = createWindow(self->window, NULL, mask, &attrib); + self->innerright = createWindow(self->window, NULL, mask, &attrib); + self->innerbottom = createWindow(self->window, NULL, mask, &attrib); + self->title = createWindow(self->window, NULL, mask, &attrib); self->titleleft = createWindow(self->window, NULL, mask, &attrib); self->titletop = createWindow(self->window, NULL, mask, &attrib); @@ -141,11 +137,6 @@ ObFrame *frame_new(ObClient *client) self->left = createWindow(self->window, NULL, mask, &attrib); self->right = createWindow(self->window, NULL, mask, &attrib); - self->innerleft = createWindow(self->window, NULL, mask, &attrib); - self->innertop = createWindow(self->window, NULL, mask, &attrib); - self->innerright = createWindow(self->window, NULL, mask, &attrib); - self->innerbottom = createWindow(self->window, NULL, mask, &attrib); - self->label = createWindow(self->title, NULL, mask, &attrib); self->max = createWindow(self->title, NULL, mask, &attrib); self->close = createWindow(self->title, NULL, mask, &attrib); @@ -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 } @@ -352,7 +352,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, if (self->max_horz) { self->cbwidth_l = self->cbwidth_r = 0; - self->width = self->client->area.width - self->bwidth * 2; + self->width = self->client->area.width; if (self->max_vert) self->cbwidth_b = 0; } else @@ -429,9 +429,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, gint titlesides; /* height of titleleft and titleright */ - titlesides = (!self->max_horz ? - ob_rr_theme->grip_width : - self->size.top - self->bwidth); + titlesides = (!self->max_horz ? ob_rr_theme->grip_width : 0); XMoveResizeWindow(ob_display, self->titletop, ob_rr_theme->grip_width + self->bwidth, 0, @@ -476,7 +474,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, if (self->decorations & OB_FRAME_DECOR_TITLEBAR) { XMoveResizeWindow(ob_display, self->titlebottom, - self->bwidth, + (self->max_horz ? 0 : self->bwidth), ob_rr_theme->title_height + self->bwidth, self->width, self->bwidth); @@ -496,7 +494,8 @@ void frame_adjust_area(ObFrame *self, gboolean moved, if (self->decorations & OB_FRAME_DECOR_TITLEBAR) { XMoveResizeWindow(ob_display, self->title, - self->bwidth, self->bwidth, + (self->max_horz ? 0 : self->bwidth), + self->bwidth, self->width, ob_rr_theme->title_height); XMapWindow(ob_display, self->title); @@ -536,49 +535,63 @@ void frame_adjust_area(ObFrame *self, gboolean moved, layout_title(self); if (!fake) { + gint sidebwidth = self->max_horz ? 0 : self->bwidth; + if (self->bwidth && self->size.bottom) { XMoveResizeWindow(ob_display, self->handlebottom, ob_rr_theme->grip_width + - self->bwidth * 2, + self->bwidth + sidebwidth, self->size.top + self->client->area.height + self->size.bottom - self->bwidth, self->width - (ob_rr_theme->grip_width + - self->bwidth) * 2, + sidebwidth) * 2, self->bwidth); - XMoveResizeWindow(ob_display, self->lgripleft, - 0, - self->size.top + self->client->area.height + - self->size.bottom - - (!self->max_horz ? - ob_rr_theme->grip_width : - self->size.bottom - self->cbwidth_b), - self->bwidth, - (!self->max_horz ? - ob_rr_theme->grip_width : - self->size.bottom - self->cbwidth_b)); - XMoveResizeWindow(ob_display, self->rgripright, - self->size.left + self->client->area.width + - self->size.right - self->bwidth, - self->size.top + self->client->area.height + - self->size.bottom - - (!self->max_horz ? - ob_rr_theme->grip_width : - self->size.bottom - self->cbwidth_b), - self->bwidth, - (!self->max_horz ? - ob_rr_theme->grip_width : - self->size.bottom - self->cbwidth_b)); + + if (sidebwidth) { + XMoveResizeWindow(ob_display, self->lgripleft, + 0, + self->size.top + + self->client->area.height + + self->size.bottom - + (!self->max_horz ? + ob_rr_theme->grip_width : + self->size.bottom - self->cbwidth_b), + self->bwidth, + (!self->max_horz ? + ob_rr_theme->grip_width : + self->size.bottom - self->cbwidth_b)); + XMoveResizeWindow(ob_display, self->rgripright, + self->size.left + + self->client->area.width + + self->size.right - self->bwidth, + self->size.top + + self->client->area.height + + self->size.bottom - + (!self->max_horz ? + ob_rr_theme->grip_width : + self->size.bottom - self->cbwidth_b), + self->bwidth, + (!self->max_horz ? + ob_rr_theme->grip_width : + self->size.bottom - self->cbwidth_b)); + + XMapWindow(ob_display, self->lgripleft); + XMapWindow(ob_display, self->rgripright); + } else { + XUnmapWindow(ob_display, self->lgripleft); + XUnmapWindow(ob_display, self->rgripright); + } XMoveResizeWindow(ob_display, self->lgripbottom, - self->bwidth, + sidebwidth, self->size.top + self->client->area.height + self->size.bottom - self->bwidth, ob_rr_theme->grip_width + self->bwidth, self->bwidth); XMoveResizeWindow(ob_display, self->rgripbottom, self->size.left + self->client->area.width + - self->size.right - self->bwidth * 2 - + self->size.right - self->bwidth - sidebwidth - ob_rr_theme->grip_width, self->size.top + self->client->area.height + self->size.bottom - self->bwidth, @@ -586,8 +599,6 @@ void frame_adjust_area(ObFrame *self, gboolean moved, self->bwidth); XMapWindow(ob_display, self->handlebottom); - XMapWindow(ob_display, self->lgripleft); - XMapWindow(ob_display, self->rgripright); XMapWindow(ob_display, self->lgripbottom); XMapWindow(ob_display, self->rgripbottom); @@ -596,10 +607,10 @@ void frame_adjust_area(ObFrame *self, gboolean moved, { XMoveResizeWindow(ob_display, self->handletop, ob_rr_theme->grip_width + - self->bwidth * 2, + self->bwidth + sidebwidth, FRAME_HANDLE_Y(self), self->width - (ob_rr_theme->grip_width + - self->bwidth) * 2, + sidebwidth) * 2, self->bwidth); XMapWindow(ob_display, self->handletop); @@ -618,7 +629,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, ob_rr_theme->handle_height); XMoveResizeWindow(ob_display, self->lgriptop, - self->bwidth, + sidebwidth, FRAME_HANDLE_Y(self), ob_rr_theme->grip_width + self->bwidth, @@ -626,8 +637,8 @@ void frame_adjust_area(ObFrame *self, gboolean moved, XMoveResizeWindow(ob_display, self->rgriptop, self->size.left + self->client->area.width + - self->size.right - self->bwidth * 2 - - ob_rr_theme->grip_width, + self->size.right - self->bwidth - + sidebwidth - ob_rr_theme->grip_width, FRAME_HANDLE_Y(self), ob_rr_theme->grip_width + self->bwidth, @@ -670,7 +681,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, ob_rr_theme->handle_height > 0) { XMoveResizeWindow(ob_display, self->handle, - self->bwidth, + sidebwidth, FRAME_HANDLE_Y(self) + self->bwidth, self->width, ob_rr_theme->handle_height); XMapWindow(ob_display, self->handle); @@ -777,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)) { @@ -1664,7 +1679,10 @@ void frame_end_iconify_animation(ObFrame *self) else { /* Send a ConfigureNotify when the animation is done, this fixes KDE's pager showing the window in the wrong place. */ - client_reconfigure(self->client); + 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 ! */ @@ -1729,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; + } +}