]> Dogcows Code - chaz/openbox/blobdiff - openbox/frame.c
action.h not needed here
[chaz/openbox] / openbox / frame.c
index 55a28413275dd8098b3c1d999be730bee741fceb..9e176a5079cc6e28a7384dfcd5b464d1ba3df9bd 100644 (file)
@@ -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"
@@ -50,7 +51,10 @@ static void layout_title(ObFrame *self);
 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_shape(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,
                            gulong mask, XSetWindowAttributes *attrib)
@@ -62,58 +66,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 +232,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 +244,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 +255,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);
@@ -368,7 +364,8 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
                   self->cbwidth_l + (!self->max_horz ? self->bwidth : 0),
                   self->cbwidth_t + self->bwidth,
                   self->cbwidth_r + (!self->max_horz ? self->bwidth : 0),
-                  self->cbwidth_b + (!self->max_horz || !self->max_vert ? self->bwidth : 0));
+                  self->cbwidth_b + (!self->max_horz || !self->max_vert ?
+                                     self->bwidth : 0));
 
         if (self->decorations & OB_FRAME_DECOR_TITLEBAR)
             self->size.top += ob_rr_theme->title_height + self->bwidth;
@@ -758,9 +755,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
            frame_client_gravity. */
         self->area.x = self->client->area.x;
         self->area.y = self->client->area.y;
-        frame_client_gravity(self, &self->area.x, &self->area.y,
-                             self->client->area.width,
-                             self->client->area.height);
+        frame_client_gravity(self, &self->area.x, &self->area.y);
     }
 
     if (!fake) {
@@ -788,6 +783,9 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
             self->need_render = TRUE;
             framerender_frame(self);
             frame_adjust_shape(self);
+
+            /* the offscreen buffer's shape needs to match */
+            frame_get_offscreen_buffer(self);
         }
 
         if (!STRUT_EQUAL(self->size, oldsize)) {
@@ -918,6 +916,9 @@ void frame_grab_client(ObFrame *self)
     /* reparent the client to the frame */
     XReparentWindow(ob_display, self->client->window, self->window, 0, 0);
 
+    /* enable the offscreen composite buffer for the client window */
+    composite_enable_for_window(self->client->window);
+
     /*
       When reparenting the client window, it is usually not mapped yet, since
       this occurs from a MapRequest. However, in the case where Openbox is
@@ -1401,7 +1402,7 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y)
     return OB_FRAME_CONTEXT_NONE;
 }
 
-void frame_client_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
+void frame_client_gravity(ObFrame *self, gint *x, gint *y)
 {
     /* horizontal */
     switch (self->client->gravity) {
@@ -1464,7 +1465,7 @@ void frame_client_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
     }
 }
 
-void frame_frame_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
+void frame_frame_gravity(ObFrame *self, gint *x, gint *y)
 {
     /* horizontal */
     switch (self->client->gravity) {
@@ -1525,7 +1526,7 @@ void frame_rect_to_frame(ObFrame *self, Rect *r)
 {
     r->width += self->size.left + self->size.right;
     r->height += self->size.top + self->size.bottom;
-    frame_client_gravity(self, &r->x, &r->y, r->width, r->height);
+    frame_client_gravity(self, &r->x, &r->y);
 }
 
 static void flash_done(gpointer data)
@@ -1675,7 +1676,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 ! */
@@ -1740,3 +1744,34 @@ 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->client->window);
+
+#ifdef SHAPE
+        /* shape the offscreen buffer to match the window */
+        XShapeCombineShape(ob_display, self->pixmap, ShapeBounding,
+                           0, 0, self->client->window,
+                           ShapeBounding, ShapeSet);
+#endif
+
+        /*
+          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;
+    }
+}
This page took 0.028993 seconds and 4 git commands to generate.