X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=11e42a0eb9a6cd48b30cd2ef518c42f29645268c;hb=34e819738b344a992a1dbfd6cdd165e0c8ddb3a9;hp=6d5893e244542add42539fe3757cf09a35e7a309;hpb=43d109dd062483154f00712a23b00494b0a13355;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 6d5893e2..11e42a0e 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -288,12 +288,12 @@ void client_manage(Window window) stacking_add(CLIENT_AS_WINDOW(self)); } - screen_update_struts(); + dispatch_client(Event_Client_New, self, 0, 0); /* make sure the window is visible */ client_move_onscreen(self); - dispatch_client(Event_Client_New, self, 0, 0); + screen_update_areas(); client_showhide(self); @@ -347,7 +347,7 @@ void client_unmanage(Client *self) /* once the client is out of the list, update the struts to remove it's influence */ - screen_update_struts(); + screen_update_areas(); /* tell our parent(s) that we're gone */ if (self->transient_for == TRAN_GROUP) { /* transient of group */ @@ -440,6 +440,7 @@ void client_move_onscreen(Client *self) Rect *a; int x = self->frame->area.x, y = self->frame->area.y; + /* XXX watch for xinerama dead areas */ a = screen_area(self->desktop); if (x >= a->x + a->width - 1) x = a->x + a->width - self->frame->area.width; @@ -587,12 +588,13 @@ static void client_get_area(Client *self) static void client_get_desktop(Client *self) { - guint32 d; + guint32 d = screen_num_desktops; /* an always-invalid value */ if (PROP_GET32(self->window, net_wm_desktop, cardinal, &d)) { if (d >= screen_num_desktops && d != DESKTOP_ALL) - d = screen_num_desktops - 1; - self->desktop = d; + self->desktop = screen_num_desktops - 1; + else + self->desktop = d; } else { gboolean trdesk = FALSE; @@ -616,6 +618,8 @@ static void client_get_desktop(Client *self) /* defaults to the current desktop */ self->desktop = screen_desktop; + } + if (self->desktop != d) { /* set the desktop hint, to make sure that it always exists */ PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop); } @@ -1027,10 +1031,7 @@ void client_setup_decor_and_functions(Client *self) if (self->type == Type_Desktop && self->desktop != DESKTOP_ALL) client_set_desktop(self, DESKTOP_ALL, FALSE); - /* change the decors on the frame, and with more/less decorations, - we may also need to be repositioned */ - frame_adjust_area(self->frame, TRUE, TRUE); - /* with new decor, the window's maximized size may change */ + /* adjust the client's decorations, etc. */ client_reconfigure(self); } else { /* this makes sure that these windows appear on all desktops */ @@ -1091,8 +1092,11 @@ static void client_change_allowed_actions(Client *self) void client_reconfigure(Client *self) { + /* by making this pass FALSE for user, we avoid the emacs event storm where + every configurenotify causes an update in its normal hints, i think this + is generally what we want anyways... */ client_configure(self, Corner_TopLeft, self->area.x, self->area.y, - self->area.width, self->area.height, TRUE, TRUE); + self->area.width, self->area.height, FALSE, TRUE); } void client_update_wmhints(Client *self) @@ -1294,7 +1298,7 @@ void client_update_strut(Client *self) /* updating here is pointless while we're being mapped cuz we're not in the client list yet */ if (self->frame) - screen_update_struts(); + screen_update_areas(); } void client_update_icons(Client *self) @@ -1333,17 +1337,17 @@ void client_update_icons(Client *self) if (w*h == 0) continue; - self->icons[j].data = g_new(pixel32, w * h); + self->icons[j].data = g_new(RrPixel32, w * h); for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) { if (x >= w) { x = 0; ++y; } self->icons[j].data[t] = - (((data[i] >> 24) & 0xff) << default_alpha_offset) + - (((data[i] >> 16) & 0xff) << default_red_offset) + - (((data[i] >> 8) & 0xff) << default_green_offset) + - (((data[i] >> 0) & 0xff) << default_blue_offset); + (((data[i] >> 24) & 0xff) << RrDefaultAlphaOffset) + + (((data[i] >> 16) & 0xff) << RrDefaultRedOffset) + + (((data[i] >> 8) & 0xff) << RrDefaultGreenOffset) + + (((data[i] >> 0) & 0xff) << RrDefaultBlueOffset); } g_assert(i <= num); } @@ -1355,10 +1359,11 @@ void client_update_icons(Client *self) self->nicons++; self->icons = g_new(Icon, self->nicons); xerror_set_ignore(TRUE); - if (!render_pixmap_to_rgba(data[0], data[1], - &self->icons[self->nicons-1].width, - &self->icons[self->nicons-1].height, - &self->icons[self->nicons-1].data)) { + if (!RrPixmapToRGBA(ob_rr_inst, + data[0], data[1], + &self->icons[self->nicons-1].width, + &self->icons[self->nicons-1].height, + &self->icons[self->nicons-1].data)) { g_free(&self->icons[self->nicons-1]); self->nicons--; } @@ -1373,12 +1378,13 @@ void client_update_icons(Client *self) self->nicons++; self->icons = g_new(Icon, self->nicons); xerror_set_ignore(TRUE); - if (!render_pixmap_to_rgba(hints->icon_pixmap, - (hints->flags & IconMaskHint ? - hints->icon_mask : None), - &self->icons[self->nicons-1].width, - &self->icons[self->nicons-1].height, - &self->icons[self->nicons-1].data)){ + if (!RrPixmapToRGBA(ob_rr_inst, + hints->icon_pixmap, + (hints->flags & IconMaskHint ? + hints->icon_mask : None), + &self->icons[self->nicons-1].width, + &self->icons[self->nicons-1].height, + &self->icons[self->nicons-1].data)){ g_free(&self->icons[self->nicons-1]); self->nicons--; } @@ -1502,8 +1508,11 @@ static void calc_recursive(Client *self, Client *orig, StackLayer l, calc_recursive(it->data, orig, l, raised ? raised : l != old); if (!raised && l != old) - if (orig->frame) /* only restack if the original window is managed */ - stacking_raise(CLIENT_AS_WINDOW(self)); + if (orig->frame) { /* only restack if the original window is managed */ + /* XXX add_non_intrusive ever? */ + stacking_remove(CLIENT_AS_WINDOW(self)); + stacking_add(CLIENT_AS_WINDOW(self)); + } } void client_calc_layer(Client *self) @@ -1612,33 +1621,47 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, #ifdef VIDMODE int dot; XF86VidModeModeLine mode; +#endif + Rect *a; + guint i; + + i = client_xinerama_area(self); + a = screen_physical_area_xinerama(i); - if (XF86VidModeGetModeLine(ob_display, ob_screen, &dot, &mode)) { +#ifdef VIDMODE + if (i == 0 && /* primary head */ + extensions_vidmode && + XF86VidModeGetViewPort(ob_display, ob_screen, &x, &y) && + /* get the mode last so the mode.privsize isnt freed incorrectly */ + XF86VidModeGetModeLine(ob_display, ob_screen, &dot, &mode)) { + x += a->x; + y += a->y; w = mode.hdisplay; h = mode.vdisplay; if (mode.privsize) XFree(mode.private); - } else { -#else - w = screen_physical_size.width; - h = screen_physical_size.height; -#endif -#ifdef VIDMODE - } - if (!XF86VidModeGetViewPort(ob_display, ob_screen, &x, &y)) { - x = y = 0; + } else #endif + { + x = a->x; + y = a->y; + w = a->width; + h = a->height; } + user = FALSE; /* ignore that increment etc shit when in fullscreen */ } else { + Rect *a; + + a = screen_area_xinerama(self->desktop, client_xinerama_area(self)); + /* set the size and position if maximized */ if (self->max_horz) { - x = screen_area(self->desktop)->x - self->frame->size.left; - w = screen_area(self->desktop)->width; + x = a->x - self->frame->size.left; + w = a->width; } if (self->max_vert) { - y = screen_area(self->desktop)->y; - h = screen_area(self->desktop)->height - - self->frame->size.top - self->frame->size.bottom; + y = a->y; + h = a->height - self->frame->size.top - self->frame->size.bottom; } } @@ -1677,16 +1700,13 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, minh = self->base_size.height; } - w -= basew; - h -= baseh; - if (user) { /* for interactive resizing. have to move half an increment in each direction. */ /* how far we are towards the next size inc */ - int mw = w % self->size_inc.width; - int mh = h % self->size_inc.height; + int mw = (w - basew) % self->size_inc.width; + int mh = (h - baseh) % self->size_inc.height; /* amount to add */ int aw = self->size_inc.width / 2; int ah = self->size_inc.height / 2; @@ -1708,6 +1728,9 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, if (h < minh) h = minh; } + w -= basew; + h -= baseh; + /* keep to the increments */ w /= self->size_inc.width; h /= self->size_inc.height; @@ -1761,11 +1784,18 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, RECT_SET(self->area, x, y, w, h); - if (final || (resized && config_opaque_resize)) + /* for app-requested resizes, always resize if 'resized' is true. + for user-requested ones, only resize if final is true, or when + resizing in opaque mode */ + if ((!user && resized) || + (user && (final || (resized && config_opaque_resize)))) XResizeWindow(ob_display, self->window, w, h); /* move/resize the frame to match the request */ if (self->frame) { + if (self->decorations != self->frame->decorations) + moved = resized = TRUE; + if (moved || resized) frame_adjust_area(self->frame, moved, resized); @@ -1773,7 +1803,7 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, clients (emacs) freaking out, cuz they send back a configure every time they receive this event, which resends them this event... etc. */ - if ((moved || resized) && (!user || final)) { + if ((!user && moved) || (user && final)) { XEvent event; event.type = ConfigureNotify; event.xconfigure.display = ob_display; @@ -1824,14 +1854,14 @@ void client_fullscreen(Client *self, gboolean fs, gboolean savearea) } else { guint num; gint32 *dimensions; + Rect *a; /* pick some fallbacks... */ - x = screen_area(self->desktop)->x + - screen_area(self->desktop)->width / 4; - y = screen_area(self->desktop)->y + - screen_area(self->desktop)->height / 4; - w = screen_area(self->desktop)->width / 2; - h = screen_area(self->desktop)->height / 2; + a = screen_area_xinerama(self->desktop, 0); + x = a->x + a->width / 4; + y = a->y + a->height / 4; + w = a->width / 2; + h = a->height / 2; if (PROP_GETA32(self->window, openbox_premax, cardinal, (guint32**)&dimensions, &num)) { @@ -1913,7 +1943,7 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk) } client_change_state(self); client_showhide(self); - screen_update_struts(); + screen_update_areas(); dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped, self, 0, 0); @@ -1981,17 +2011,17 @@ void client_maximize(Client *self, gboolean max, int dir, gboolean savearea) } else { guint num; gint32 *dimensions; + Rect *a; /* pick some fallbacks... */ + a = screen_area_xinerama(self->desktop, 0); if (dir == 0 || dir == 1) { /* horz */ - x = screen_area(self->desktop)->x + - screen_area(self->desktop)->width / 4; - w = screen_area(self->desktop)->width / 2; + x = a->x + a->width / 4; + w = a->width / 2; } if (dir == 0 || dir == 2) { /* vert */ - y = screen_area(self->desktop)->y + - screen_area(self->desktop)->height / 4; - h = screen_area(self->desktop)->height / 2; + y = a->y + a->height / 4; + h = a->height / 2; } if (PROP_GETA32(self->window, openbox_premax, cardinal, @@ -2095,7 +2125,7 @@ void client_set_desktop(Client *self, guint target, gboolean donthide) /* raise if it was not already on the desktop */ if (old != DESKTOP_ALL) stacking_raise(CLIENT_AS_WINDOW(self)); - screen_update_struts(); + screen_update_areas(); /* add to the new desktop(s) */ if (config_focus_new) @@ -2531,3 +2561,17 @@ void client_set_layer(Client *self, int layer) client_calc_layer(self); client_change_state(self); /* reflect this in the state hints */ } + +guint client_xinerama_area(Client *self) +{ + guint i; + + for (i = 0; i < screen_num_xin_areas; ++i) { + Rect *area = screen_physical_area_xinerama(i); + if (RECT_INTERSECTS_RECT(*area, self->frame->area)) + break; + } + if (i == screen_num_xin_areas) i = 0; + g_assert(i < screen_num_xin_areas); + return i; +}