X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fframe.c;h=3304f4b57be2b03fa89f055734284c330d59ef8a;hb=c38a756ae50616b1431e3137141189a5588654a0;hp=8f947e49d49e289aea1bf48f2564b899fe0cdf43;hpb=7d3e3ff6dfda1fa87165d9823e47cd2c9dd9f57e;p=chaz%2Fopenbox diff --git a/openbox/frame.c b/openbox/frame.c index 8f947e49..3304f4b5 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -22,12 +22,12 @@ #include "openbox.h" #include "extensions.h" #include "prop.h" +#include "grab.h" #include "config.h" #include "framerender.h" #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" @@ -52,8 +52,6 @@ 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,7 +60,26 @@ static Window createWindow(Window parent, Visual *visual, (visual ? 32 : RrDepth(ob_rr_inst)), InputOutput, (visual ? visual : RrVisual(ob_rr_inst)), mask, attrib); - + +} + +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) @@ -70,41 +87,34 @@ ObFrame *frame_new(ObClient *client) XSetWindowAttributes attrib; gulong mask; ObFrame *self; - XWindowAttributes wattrib; - Status ret; + Visual *visual; self = g_new0(ObFrame, 1); self->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); + visual = check_32bit_client(client); /* create the non-visible decor windows */ mask = 0; - if (self->has_alpha) { - /* the colormap/backpixel/borderpixel are required for supporting - windows with 32bit visuals */ - mask = CWColormap | CWBackPixel | CWBorderPixel; + if (visual) { + /* client has a 32-bit visual */ + mask |= CWColormap | CWBackPixel | CWBorderPixel; /* create a colormap with the visual */ self->colormap = attrib.colormap = XCreateColormap(ob_display, RootWindow(ob_display, ob_screen), - wattrib.visual, AllocNone); + 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), - (self->has_alpha ? wattrib.visual : NULL), + self->window = createWindow(RootWindow(ob_display, ob_screen), visual, mask, &attrib); /* create the visible decor windows */ mask = 0; - if (self->has_alpha) { + if (visual) { /* client has a 32-bit visual */ mask |= CWColormap | CWBackPixel | CWBorderPixel; attrib.colormap = RrColormap(ob_rr_inst); @@ -120,6 +130,11 @@ ObFrame *frame_new(ObClient *client) self->innerright = createWindow(self->window, NULL, mask, &attrib); self->innerbottom = createWindow(self->window, NULL, mask, &attrib); + self->innerblb = createWindow(self->innerbottom, NULL, mask, &attrib); + self->innerbrb = createWindow(self->innerbottom, NULL, mask, &attrib); + self->innerbll = createWindow(self->innerleft, NULL, mask, &attrib); + self->innerbrr = createWindow(self->innerright, 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); @@ -147,7 +162,7 @@ ObFrame *frame_new(ObClient *client) self->handle = createWindow(self->window, NULL, mask, &attrib); self->lgrip = createWindow(self->handle, NULL, mask, &attrib); - self->rgrip = createWindow(self->handle, NULL, mask, &attrib); + self->rgrip = createWindow(self->handle, NULL, mask, &attrib); self->handleleft = createWindow(self->handle, NULL, mask, &attrib); self->handleright = createWindow(self->handle, NULL, mask, &attrib); @@ -168,9 +183,9 @@ ObFrame *frame_new(ObClient *client) XMapWindow(ob_display, self->backback); XMapWindow(ob_display, self->backfront); - self->max_press = self->close_press = self->desk_press = + self->max_press = self->close_press = self->desk_press = self->iconify_press = self->shade_press = FALSE; - self->max_hover = self->close_hover = self->desk_hover = + self->max_hover = self->close_hover = self->desk_hover = self->iconify_hover = self->shade_hover = FALSE; set_theme_statics(self); @@ -201,27 +216,10 @@ static void set_theme_statics(ObFrame *self) ob_rr_theme->paddingx + 1, ob_rr_theme->title_height); XResizeWindow(ob_display, self->trrresize, ob_rr_theme->paddingx + 1, ob_rr_theme->title_height); - - /* set up the dynamic appearances */ - self->a_unfocused_title = RrAppearanceCopy(ob_rr_theme->a_unfocused_title); - self->a_focused_title = RrAppearanceCopy(ob_rr_theme->a_focused_title); - self->a_unfocused_label = RrAppearanceCopy(ob_rr_theme->a_unfocused_label); - self->a_focused_label = RrAppearanceCopy(ob_rr_theme->a_focused_label); - self->a_unfocused_handle = - RrAppearanceCopy(ob_rr_theme->a_unfocused_handle); - self->a_focused_handle = RrAppearanceCopy(ob_rr_theme->a_focused_handle); - self->a_icon = RrAppearanceCopy(ob_rr_theme->a_icon); } static void free_theme_statics(ObFrame *self) { - RrAppearanceFree(self->a_unfocused_title); - RrAppearanceFree(self->a_focused_title); - RrAppearanceFree(self->a_unfocused_label); - RrAppearanceFree(self->a_focused_label); - RrAppearanceFree(self->a_unfocused_handle); - RrAppearanceFree(self->a_focused_handle); - RrAppearanceFree(self->a_icon); } void frame_free(ObFrame *self) @@ -231,7 +229,6 @@ 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); } @@ -241,10 +238,13 @@ void frame_show(ObFrame *self) if (!self->visible) { self->visible = TRUE; framerender_frame(self); + /* Grab the server to make sure that the frame window is mapped before + the client gets its MapNotify, i.e. to make sure the client is + _visible_ when it gets MapNotify. */ + grab_server(TRUE); XMapWindow(ob_display, self->client->window); XMapWindow(ob_display, self->window); - - frame_get_offscreen_buffer(self); + grab_server(FALSE); } } @@ -254,7 +254,6 @@ 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); @@ -313,9 +312,6 @@ void frame_adjust_shape(ObFrame *self) ShapeUnion, Unsorted); } #endif - - /* the offscreen buffer's shape needs to match */ - frame_get_offscreen_buffer(self); } void frame_adjust_area(ObFrame *self, gboolean moved, @@ -364,10 +360,12 @@ void frame_adjust_area(ObFrame *self, gboolean moved, STRUT_SET(self->size, self->cbwidth_l + (!self->max_horz ? self->bwidth : 0), - self->cbwidth_t + self->bwidth, + self->cbwidth_t + + (!self->max_horz || !self->max_vert || + !self->client->undecorated ? self->bwidth : 0), 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; @@ -376,10 +374,13 @@ void frame_adjust_area(ObFrame *self, gboolean moved, { self->size.bottom += ob_rr_theme->handle_height + self->bwidth; } - + /* position/size and map/unmap all the windows */ if (!fake) { + gint innercornerheight = + ob_rr_theme->grip_width - self->size.bottom; + if (self->cbwidth_l) { XMoveResizeWindow(ob_display, self->innerleft, self->size.left - self->cbwidth_l, @@ -390,6 +391,19 @@ void frame_adjust_area(ObFrame *self, gboolean moved, } else XUnmapWindow(ob_display, self->innerleft); + if (self->cbwidth_l && innercornerheight > 0) { + XMoveResizeWindow(ob_display, self->innerbll, + 0, + self->client->area.height - + (ob_rr_theme->grip_width - + self->size.bottom), + self->cbwidth_l, + ob_rr_theme->grip_width - self->size.bottom); + + XMapWindow(ob_display, self->innerbll); + } else + XUnmapWindow(ob_display, self->innerbll); + if (self->cbwidth_r) { XMoveResizeWindow(ob_display, self->innerright, self->size.left + self->client->area.width, @@ -400,6 +414,19 @@ void frame_adjust_area(ObFrame *self, gboolean moved, } else XUnmapWindow(ob_display, self->innerright); + if (self->cbwidth_r && innercornerheight > 0) { + XMoveResizeWindow(ob_display, self->innerbrr, + 0, + self->client->area.height - + (ob_rr_theme->grip_width - + self->size.bottom), + self->cbwidth_r, + ob_rr_theme->grip_width - self->size.bottom); + + XMapWindow(ob_display, self->innerbrr); + } else + XUnmapWindow(ob_display, self->innerbrr); + if (self->cbwidth_t) { XMoveResizeWindow(ob_display, self->innertop, self->size.left - self->cbwidth_l, @@ -420,9 +447,26 @@ void frame_adjust_area(ObFrame *self, gboolean moved, self->cbwidth_l + self->cbwidth_r, self->cbwidth_b); + XMoveResizeWindow(ob_display, self->innerblb, + 0, 0, + ob_rr_theme->grip_width + self->bwidth, + self->cbwidth_b); + XMoveResizeWindow(ob_display, self->innerbrb, + self->client->area.width + + self->cbwidth_l + self->cbwidth_r - + (ob_rr_theme->grip_width + self->bwidth), + 0, + ob_rr_theme->grip_width + self->bwidth, + self->cbwidth_b); + XMapWindow(ob_display, self->innerbottom); - } else + XMapWindow(ob_display, self->innerblb); + XMapWindow(ob_display, self->innerbrb); + } else { XUnmapWindow(ob_display, self->innerbottom); + XUnmapWindow(ob_display, self->innerblb); + XUnmapWindow(ob_display, self->innerbrb); + } if (self->bwidth) { gint titlesides; @@ -546,7 +590,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, sidebwidth) * 2, self->bwidth); - + if (sidebwidth) { XMoveResizeWindow(ob_display, self->lgripleft, 0, @@ -590,7 +634,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, self->bwidth); XMoveResizeWindow(ob_display, self->rgripbottom, self->size.left + self->client->area.width + - self->size.right - self->bwidth - sidebwidth - + self->size.right - self->bwidth - sidebwidth- ob_rr_theme->grip_width, self->size.top + self->client->area.height + self->size.bottom - self->bwidth, @@ -709,7 +753,10 @@ void frame_adjust_area(ObFrame *self, gboolean moved, XUnmapWindow(ob_display, self->handle); } - if (self->bwidth && !self->max_horz) { + if (self->bwidth && !self->max_horz && + (self->client->area.height + self->size.top + + self->size.bottom) > ob_rr_theme->grip_width * 2) + { XMoveResizeWindow(ob_display, self->left, 0, self->bwidth + ob_rr_theme->grip_width, @@ -722,10 +769,13 @@ void frame_adjust_area(ObFrame *self, gboolean moved, } else XUnmapWindow(ob_display, self->left); - if (self->bwidth && !self->max_horz) { + if (self->bwidth && !self->max_horz && + (self->client->area.height + self->size.top + + self->size.bottom) > ob_rr_theme->grip_width * 2) + { XMoveResizeWindow(ob_display, self->right, - self->client->area.width + - self->cbwidth_l + self->cbwidth_r + self->bwidth, + self->client->area.width + self->cbwidth_l + + self->cbwidth_r + self->bwidth, self->bwidth + ob_rr_theme->grip_width, self->bwidth, self->client->area.height + @@ -757,16 +807,14 @@ 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) { if (!frame_iconify_animating(self)) /* move and resize the top level frame. shading can change without being moved or resized. - + but don't do this during an iconify animation. it will be reflected afterwards. */ @@ -786,7 +834,6 @@ void frame_adjust_area(ObFrame *self, gboolean moved, if (resized) { self->need_render = TRUE; framerender_frame(self); - /* this also updates the offscreen buffer */ frame_adjust_shape(self); } @@ -865,12 +912,16 @@ static void frame_adjust_cursors(ObFrame *self) XChangeWindowAttributes(ob_display, self->lgripleft, CWCursor, &a); XChangeWindowAttributes(ob_display, self->lgriptop, CWCursor, &a); XChangeWindowAttributes(ob_display, self->lgripbottom, CWCursor, &a); + XChangeWindowAttributes(ob_display, self->innerbll, CWCursor, &a); + XChangeWindowAttributes(ob_display, self->innerblb, CWCursor, &a); a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHEAST : OB_CURSOR_NONE); XChangeWindowAttributes(ob_display, self->rgrip, CWCursor, &a); XChangeWindowAttributes(ob_display, self->handleright, CWCursor, &a); XChangeWindowAttributes(ob_display, self->rgripright, CWCursor, &a); XChangeWindowAttributes(ob_display, self->rgriptop, CWCursor, &a); XChangeWindowAttributes(ob_display, self->rgripbottom, CWCursor, &a); + XChangeWindowAttributes(ob_display, self->innerbrr, CWCursor, &a); + XChangeWindowAttributes(ob_display, self->innerbrb, CWCursor, &a); } } @@ -918,9 +969,6 @@ 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 @@ -942,6 +990,10 @@ void frame_grab_client(ObFrame *self) g_hash_table_insert(window_map, &self->innertop, self->client); g_hash_table_insert(window_map, &self->innerright, self->client); g_hash_table_insert(window_map, &self->innerbottom, self->client); + g_hash_table_insert(window_map, &self->innerblb, self->client); + g_hash_table_insert(window_map, &self->innerbll, self->client); + g_hash_table_insert(window_map, &self->innerbrb, self->client); + g_hash_table_insert(window_map, &self->innerbrr, self->client); g_hash_table_insert(window_map, &self->title, self->client); g_hash_table_insert(window_map, &self->label, self->client); g_hash_table_insert(window_map, &self->max, self->client); @@ -1022,6 +1074,10 @@ void frame_release_client(ObFrame *self) g_hash_table_remove(window_map, &self->innertop); g_hash_table_remove(window_map, &self->innerright); g_hash_table_remove(window_map, &self->innerbottom); + g_hash_table_remove(window_map, &self->innerblb); + g_hash_table_remove(window_map, &self->innerbll); + g_hash_table_remove(window_map, &self->innerbrb); + g_hash_table_remove(window_map, &self->innerbrr); g_hash_table_remove(window_map, &self->title); g_hash_table_remove(window_map, &self->label); g_hash_table_remove(window_map, &self->max); @@ -1373,9 +1429,9 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y) if (win == self->lgripbottom) return OB_FRAME_CONTEXT_BLCORNER; if (win == self->handleright) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->rgrip) return OB_FRAME_CONTEXT_BRCORNER; - if (win == self->rgripright) return OB_FRAME_CONTEXT_BLCORNER; - if (win == self->rgriptop) return OB_FRAME_CONTEXT_BLCORNER; - if (win == self->rgripbottom) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->rgripright) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->rgriptop) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->rgripbottom) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->title) return OB_FRAME_CONTEXT_TITLEBAR; if (win == self->titlebottom) return OB_FRAME_CONTEXT_TITLEBAR; if (win == self->titleleft) return OB_FRAME_CONTEXT_TLCORNER; @@ -1394,6 +1450,10 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y) if (win == self->innerleft) return OB_FRAME_CONTEXT_LEFT; if (win == self->innerbottom) return OB_FRAME_CONTEXT_BOTTOM; if (win == self->innerright) return OB_FRAME_CONTEXT_RIGHT; + if (win == self->innerbll) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->innerblb) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->innerbrr) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->innerbrb) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->max) return OB_FRAME_CONTEXT_MAXIMIZE; if (win == self->iconify) return OB_FRAME_CONTEXT_ICONIFY; if (win == self->close) return OB_FRAME_CONTEXT_CLOSE; @@ -1404,7 +1464,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) { @@ -1467,7 +1527,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) { @@ -1528,7 +1588,14 @@ 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); +} + +void frame_rect_to_client(ObFrame *self, Rect *r) +{ + r->width -= self->size.left + self->size.right; + r->height -= self->size.top + self->size.bottom; + frame_frame_gravity(self, &r->x, &r->y); } static void flash_done(gpointer data) @@ -1575,7 +1642,7 @@ void frame_flash_start(ObFrame *self) flash_done); g_get_current_time(&self->flash_end); g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5); - + self->flashing = TRUE; } @@ -1626,8 +1693,8 @@ static gboolean frame_animate_iconify(gpointer p) /* how far do we have left to go ? */ g_get_current_time(&now); time = frame_animate_iconify_time_left(self, &now); - - if (time == 0 || iconifying) { + + if ((time > 0 && iconifying) || (time == 0 && !iconifying)) { /* start where the frame is supposed to be */ x = self->area.x; y = self->area.y; @@ -1658,12 +1725,11 @@ static gboolean frame_animate_iconify(gpointer p) h = self->size.top; /* just the titlebar */ } + XMoveResizeWindow(ob_display, self->window, x, y, w, h); + XFlush(ob_display); + if (time == 0) frame_end_iconify_animation(self); - else { - XMoveResizeWindow(ob_display, self->window, x, y, w, h); - XFlush(ob_display); - } return time > 0; /* repeat until we're out of time */ } @@ -1677,11 +1743,11 @@ void frame_end_iconify_animation(ObFrame *self) XUnmapWindow(ob_display, self->window); else { /* 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. since the + window is mapped at a different location and is then moved, we + need to send the synthetic configurenotify, since apps may have + read the position when the client mapped, apparently. */ 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 ! */ @@ -1746,34 +1812,3 @@ 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; - } -}