X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fclient.c;h=78af988fcefb15ffc12d7d36f47cbc40f2b8c2e8;hb=c9233ddb23ee71de0e1fde8eb031d241cbaec8ef;hp=cc438b0f26f6ee81ae6f5da8530dba3570032d74;hpb=c8678108eb876bbe78649569dabb3b3ee5e595aa;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index cc438b0f..78af988f 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -346,7 +346,11 @@ void client_manage(Window window) client_find_onscreen(self, &x, &y, self->frame->area.width, self->frame->area.height, - client_normal(self)); + /* non-normal clients has less rules, and + windows that are being restored from a session + do also. we can assume you want it back where + you saved it */ + client_normal(self) && !self->session); if (x != ox || y != oy) client_move(self, x, y); @@ -489,10 +493,9 @@ void client_unmanage(ObClient *self) PROP_ERASE(self->window, net_wm_state); PROP_ERASE(self->window, wm_state); } else { - /* if we're left in an iconic state, the client wont be mapped. this is - bad, since we will no longer be managing the window on restart */ - if (self->iconic) - XMapWindow(ob_display, self->window); + /* if we're left in an unmapped state, the client wont be mapped. this + is bad, since we will no longer be managing the window on restart */ + XMapWindow(ob_display, self->window); } @@ -533,12 +536,14 @@ static void client_restore_session_state(ObClient *self) self->session = it->data; - RECT_SET(self->area, self->session->x, self->session->y, - self->session->w, self->session->h); + RECT_SET_POINT(self->area, self->session->x, self->session->y); self->positioned = TRUE; - if (self->session->w > 0 && self->session->h > 0) - XResizeWindow(ob_display, self->window, - self->session->w, self->session->h); + if (self->session->w > 0) + self->area.width = self->session->w; + if (self->session->h > 0) + self->area.height = self->session->h; + XResizeWindow(ob_display, self->window, + self->area.width, self->area.height); self->desktop = (self->session->desktop == DESKTOP_ALL ? self->session->desktop : @@ -843,6 +848,37 @@ static void client_get_state(ObClient *self) g_free(state); } + + if (!(self->above || self->below)) { + if (self->group) { + /* apply stuff from the group */ + GSList *it; + gint layer = -2; + + for (it = self->group->members; it; it = g_slist_next(it)) { + ObClient *c = it->data; + if (c != self && !client_search_transient(self, c)) + { + layer = MAX(layer, + (c->above ? 1 : (c->below ? -1 : 0))); + } + } + switch (layer) { + case -1: + self->below = TRUE; + break; + case -2: + case 0: + break; + case 1: + self->above = TRUE; + break; + default: + g_assert_not_reached(); + break; + } + } + } } static void client_get_shaped(ObClient *self) @@ -1059,6 +1095,9 @@ void client_update_normal_hints(ObClient *self) /* get the hints from the window */ if (XGetWMNormalHints(ob_display, self->window, &size, &ret)) { + /* normal windows can't request placement! har har + if (!client_normal(self)) + */ self->positioned = !!(size.flags & (PPosition|USPosition)); if (size.flags & PWinGravity) { @@ -1501,10 +1540,19 @@ void client_update_strut(ObClient *self) if (!got && PROP_GETA32(self->window, net_wm_strut, cardinal, &data, &num)) { if (num == 4) { + const Rect *a; + got = TRUE; + + /* use the screen's width/height */ + a = screen_physical_area(); + STRUT_PARTIAL_SET(strut, data[0], data[2], data[1], data[3], - 0, 0, 0, 0, 0, 0, 0, 0); + a->y, a->y + a->height - 1, + a->x, a->x + a->width - 1, + a->y, a->y + a->height - 1, + a->x, a->x + a->width - 1); } g_free(data); } @@ -1737,7 +1785,6 @@ static void client_calc_layer_recursive(ObClient *self, ObClient *orig, if (!raised && l != old) 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)); } @@ -1760,12 +1807,31 @@ void client_calc_layer(ObClient *self) gboolean client_should_show(ObClient *self) { - if (self->iconic) return FALSE; - else if (!(self->desktop == screen_desktop || - self->desktop == DESKTOP_ALL)) return FALSE; - else if (client_normal(self) && screen_showing_desktop) return FALSE; + if (self->iconic) + return FALSE; + if (client_normal(self) && screen_showing_desktop) + return FALSE; + /* + if (self->transient_for) { + if (self->transient_for != OB_TRAN_GROUP) + return client_should_show(self->transient_for); + else { + GSList *it; + + for (it = self->group->members; it; it = g_slist_next(it)) { + ObClient *c = it->data; + if (c != self && !c->transient_for) { + if (client_should_show(c)) + return TRUE; + } + } + } + } + */ + if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) + return TRUE; - return TRUE; + return FALSE; } static void client_showhide(ObClient *self) @@ -2136,11 +2202,6 @@ static void client_iconify_recursive(ObClient *self, PROP_MSG(self->window, kde_wm_change_state, self->wmstate, 1, 0, 0); - self->ignore_unmaps++; - /* we unmap the client itself so that we can get MapRequest - events, and because the ICCCM tells us to! */ - XUnmapWindow(ob_display, self->window); - /* update the focus lists.. iconic windows go to the bottom of the list, put the new iconic window at the 'top of the bottom'. */ @@ -2160,8 +2221,6 @@ static void client_iconify_recursive(ObClient *self, PROP_MSG(self->window, kde_wm_change_state, self->wmstate, 1, 0, 0); - XMapWindow(ob_display, self->window); - /* this puts it after the current focused window */ focus_order_remove(self); focus_order_add_new(self); @@ -2435,6 +2494,7 @@ void client_set_state(ObClient *self, Atom action, long data1, long data2) gboolean undecorated = self->undecorated; gboolean max_horz = self->max_horz; gboolean max_vert = self->max_vert; + gboolean modal = self->modal; int i; if (!(action == prop_atoms.net_wm_state_add || @@ -2451,7 +2511,7 @@ void client_set_state(ObClient *self, Atom action, long data1, long data2) /* if toggling, then pick whether we're adding or removing */ if (action == prop_atoms.net_wm_state_toggle) { if (state == prop_atoms.net_wm_state_modal) - action = self->modal ? prop_atoms.net_wm_state_remove : + action = modal ? prop_atoms.net_wm_state_remove : prop_atoms.net_wm_state_add; else if (state == prop_atoms.net_wm_state_maximized_vert) action = self->max_vert ? prop_atoms.net_wm_state_remove : @@ -2487,8 +2547,7 @@ void client_set_state(ObClient *self, Atom action, long data1, long data2) if (action == prop_atoms.net_wm_state_add) { if (state == prop_atoms.net_wm_state_modal) { - /* XXX raise here or something? */ - self->modal = TRUE; + modal = TRUE; } else if (state == prop_atoms.net_wm_state_maximized_vert) { max_vert = TRUE; } else if (state == prop_atoms.net_wm_state_maximized_horz) { @@ -2511,7 +2570,7 @@ void client_set_state(ObClient *self, Atom action, long data1, long data2) } else { /* action == prop_atoms.net_wm_state_remove */ if (state == prop_atoms.net_wm_state_modal) { - self->modal = FALSE; + modal = FALSE; } else if (state == prop_atoms.net_wm_state_maximized_vert) { max_vert = FALSE; } else if (state == prop_atoms.net_wm_state_maximized_horz) { @@ -2558,6 +2617,12 @@ void client_set_state(ObClient *self, Atom action, long data1, long data2) client_shade(self, shaded); if (undecorated != self->undecorated) client_set_undecorated(self, undecorated); + if (modal != self->modal) { + self->modal = modal; + /* when a window changes modality, then its stacking order with its + transients needs to change */ + client_raise(self); + } client_calc_layer(self); client_change_state(self); /* change the hint to reflect these changes */ } @@ -2895,15 +2960,25 @@ void client_set_undecorated(ObClient *self, gboolean undecorated) guint client_monitor(ObClient *self) { guint i; + guint most = 0; + guint mostv = 0; for (i = 0; i < screen_num_monitors; ++i) { Rect *area = screen_physical_area_monitor(i); - if (RECT_INTERSECTS_RECT(*area, self->frame->area)) - break; + if (RECT_INTERSECTS_RECT(*area, self->frame->area)) { + Rect r; + guint v; + + RECT_SET_INTERSECTION(r, *area, self->frame->area); + v = r.width * r.height; + + if (v > mostv) { + mostv = v; + most = i; + } + } } - if (i == screen_num_monitors) i = 0; - g_assert(i < screen_num_monitors); - return i; + return most; } ObClient *client_search_top_transient(ObClient *self)