X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fclient.c;h=6534e1b35dded385f9d5041dccd336fa8345b0eb;hb=464e4c59cba073a7e8648fe587487c775708f0d7;hp=507c1e713af012d2b4a21ada7c0d3bfaca05e690;hpb=a21840cbb7912c25abc1943c08d6980da7537a6c;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 507c1e71..6534e1b3 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -174,96 +174,16 @@ void client_set_list(void) stacking_set_list(); } -void client_manage_all(void) -{ - guint i, j, nchild; - Window w, *children; - XWMHints *wmhints; - XWindowAttributes attrib; - - XQueryTree(obt_display, RootWindow(obt_display, ob_screen), - &w, &w, &children, &nchild); - - /* remove all icon windows from the list */ - for (i = 0; i < nchild; i++) { - if (children[i] == None) continue; - wmhints = XGetWMHints(obt_display, children[i]); - if (wmhints) { - if ((wmhints->flags & IconWindowHint) && - (wmhints->icon_window != children[i])) - for (j = 0; j < nchild; j++) - if (children[j] == wmhints->icon_window) { - children[j] = None; - break; - } - XFree(wmhints); - } - } - - /* manage windows in reverse order from how they were originally mapped. - this is an attempt to manage children windows before their parents, so - that when the parent is mapped, it can find the child */ - for (i = 0; i < nchild; ++i) { - if (children[i] == None) - continue; - if (XGetWindowAttributes(obt_display, children[i], &attrib)) { - if (attrib.override_redirect) continue; - - if (attrib.map_state != IsUnmapped) - client_manage(children[i]); - } - } - XFree(children); -} - void client_manage(Window window) { ObClient *self; - XEvent e; - XWindowAttributes attrib; XSetWindowAttributes attrib_set; - XWMHints *wmhint; gboolean activate = FALSE; ObAppSettings *settings; gboolean transient = FALSE; Rect place, *monitor; Time launch_time, map_time; - grab_server(TRUE); - - /* check if it has already been unmapped by the time we started - mapping. the grab does a sync so we don't have to here */ - if (XCheckTypedWindowEvent(obt_display, window, DestroyNotify, &e) || - XCheckTypedWindowEvent(obt_display, window, UnmapNotify, &e)) - { - XPutBackEvent(obt_display, &e); - - ob_debug("Trying to manage unmapped window. Aborting that.\n"); - grab_server(FALSE); - return; /* don't manage it */ - } - - /* make sure it isn't an override-redirect window */ - if (!XGetWindowAttributes(obt_display, window, &attrib) || - attrib.override_redirect) - { - grab_server(FALSE); - return; /* don't manage it */ - } - - /* is the window a docking app */ - if ((wmhint = XGetWMHints(obt_display, window))) { - if ((wmhint->flags & StateHint) && - wmhint->initial_state == WithdrawnState) - { - dock_add(window, wmhint); - grab_server(FALSE); - XFree(wmhint); - return; - } - XFree(wmhint); - } - ob_debug("Managing window: 0x%lx", window); map_time = event_get_server_time(); @@ -625,8 +545,6 @@ void client_manage(Window window) ob_debug("Managed window 0x%lx plate 0x%x (%s)", window, self->frame->window, self->class); - - return; } @@ -992,6 +910,7 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, gint fw, fh; Rect desired; guint i; + gboolean found_mon; RECT_SET(desired, *x, *y, w, h); frame_rect_to_frame(self->frame, &desired); @@ -1041,18 +960,26 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, rudeb = TRUE; } + /* we iterate through every monitor that the window is at least partially + on, to make sure it is obeying the rules on them all + + if the window does not appear on any monitors, then use the first one + */ + found_mon = FALSE; for (i = 0; i < screen_num_monitors; ++i) { Rect *a; if (!screen_physical_area_monitor_contains(i, &desired)) { - if (i < screen_num_monitors - 1) + if (i < screen_num_monitors - 1 || found_mon) continue; /* the window is not inside any monitor! so just use the first one */ a = screen_area(self->desktop, 0, NULL); - } else + } else { + found_mon = TRUE; a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired); + } /* This makes sure windows aren't entirely outside of the screen so you can't see them at all. @@ -2466,7 +2393,15 @@ static ObStackingLayer calc_layer(ObClient *self) (self->decorations == 0 && !(self->max_horz && self->max_vert) && RECT_EQUAL(self->area, *monitor))) && - (client_focused(self) || client_search_focus_tree(self))) + /* you are fullscreen while you or your children are focused.. */ + (client_focused(self) || client_search_focus_tree(self) || + /* you can be fullscreen if you're on another desktop */ + (self->desktop != screen_desktop && + self->desktop != DESKTOP_ALL) || + /* and you can also be fullscreen if the focused client is on + another monitor, or nothing else is focused */ + (!focus_client || + client_monitor(focus_client) != client_monitor(self)))) l = OB_STACKING_LAYER_FULLSCREEN; else if (self->above) l = OB_STACKING_LAYER_ABOVE; else if (self->below) l = OB_STACKING_LAYER_BELOW; @@ -2492,23 +2427,54 @@ static void client_calc_layer_recursive(ObClient *self, ObClient *orig, stacking_add_nonintrusive(CLIENT_AS_WINDOW(self)); } + /* we've been restacked */ + self->visited = TRUE; + for (it = self->transients; it; it = g_slist_next(it)) client_calc_layer_recursive(it->data, orig, self->layer); } +static void client_calc_layer_internal(ObClient *self) +{ + GSList *sit; + + /* transients take on the layer of their parents */ + sit = client_search_all_top_parents(self); + + for (; sit; sit = g_slist_next(sit)) + client_calc_layer_recursive(sit->data, self, 0); +} + void client_calc_layer(ObClient *self) { - ObClient *orig; - GSList *it; + GList *it; - orig = self; + /* skip over stuff above fullscreen layer */ + for (it = stacking_list; it; it = g_list_next(it)) + if (window_layer(it->data) <= OB_STACKING_LAYER_FULLSCREEN) break; - /* transients take on the layer of their parents */ - it = client_search_all_top_parents(self); + /* find the windows in the fullscreen layer, and mark them not-visited */ + for (; it; it = g_list_next(it)) { + if (window_layer(it->data) < OB_STACKING_LAYER_FULLSCREEN) break; + else if (WINDOW_IS_CLIENT(it->data)) + WINDOW_AS_CLIENT(it->data)->visited = FALSE; + } + + client_calc_layer_internal(self); - for (; it; it = g_slist_next(it)) - client_calc_layer_recursive(it->data, orig, 0); + /* skip over stuff above fullscreen layer */ + for (it = stacking_list; it; it = g_list_next(it)) + if (window_layer(it->data) <= OB_STACKING_LAYER_FULLSCREEN) break; + + /* now recalc any windows in the fullscreen layer which have not + had their layer recalced already */ + for (; it; it = g_list_next(it)) { + if (window_layer(it->data) < OB_STACKING_LAYER_FULLSCREEN) break; + else if (WINDOW_IS_CLIENT(it->data) && + !WINDOW_AS_CLIENT(it->data)->visited) + client_calc_layer_internal(it->data); + } } gboolean client_should_show(ObClient *self) @@ -2926,6 +2892,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, void client_configure(ObClient *self, gint x, gint y, gint w, gint h, gboolean user, gboolean final, gboolean force_reply) { + Rect oldframe; gint oldw, oldh; gboolean send_resize_client; gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE; @@ -2948,6 +2915,7 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, oldw = self->area.width; oldh = self->area.height; + oldframe = self->frame->area; RECT_SET(self->area, x, y, w, h); /* for app-requested resizes, always resize if 'resized' is true. @@ -3052,6 +3020,14 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, } XFlush(obt_display); + + /* if it moved between monitors, then this can affect the stacking + layer of this window or others - for fullscreen windows */ + if (screen_find_monitor(&self->frame->area) != + screen_find_monitor(&oldframe)) + { + client_calc_layer(self); + } } void client_fullscreen(ObClient *self, gboolean fs)