X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=aad9202918238ceb29191660dd3c080f8f9aeefc;hb=0e9cfd7c77d8608a4be29f43413575d9553bf21c;hp=b1b5e8a3c0be6726973e8f1531f44db391486c91;hpb=5563e251c36a1fbda703cf4bc3c8c6ae543829bd;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index b1b5e8a3..aad92029 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -29,6 +29,7 @@ #include "session.h" #include "event.h" #include "grab.h" +#include "prompt.h" #include "focus.h" #include "stacking.h" #include "openbox.h" @@ -174,7 +175,7 @@ void client_set_list(void) stacking_set_list(); } -void client_manage(Window window) +void client_manage(Window window, ObPrompt *prompt) { ObClient *self; XSetWindowAttributes attrib_set; @@ -188,8 +189,10 @@ void client_manage(Window window) map_time = event_get_server_time(); - /* choose the events we want to receive on the CLIENT window */ - attrib_set.event_mask = CLIENT_EVENTMASK; + /* choose the events we want to receive on the CLIENT window + (ObPrompt windows can request events too) */ + attrib_set.event_mask = CLIENT_EVENTMASK | + (prompt ? prompt->event_mask : 0); attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK; XChangeWindowAttributes(obt_display, window, CWEventMask|CWDontPropagate, &attrib_set); @@ -199,6 +202,7 @@ void client_manage(Window window) self = g_new0(ObClient, 1); self->obwin.type = OB_WINDOW_CLASS_CLIENT; self->window = window; + self->prompt = prompt; /* non-zero defaults */ self->wmstate = WithdrawnState; /* make sure it gets updated first time */ @@ -218,7 +222,8 @@ void client_manage(Window window) /* specify that if we exit, the window should not be destroyed and should be reparented back to root automatically */ - XChangeSaveSet(obt_display, window, SetModeInsert); + if (!self->prompt) + XChangeSaveSet(obt_display, window, SetModeInsert); /* create the decoration frame for the client window */ self->frame = frame_new(self); @@ -617,7 +622,8 @@ void client_unmanage(ObClient *self) mouse_grab_for_client(self, FALSE); /* remove the window from our save set */ - XChangeSaveSet(obt_display, self->window, SetModeDelete); + if (!self->prompt) + XChangeSaveSet(obt_display, self->window, SetModeDelete); /* update the focus lists */ focus_order_remove(self); @@ -2393,7 +2399,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; @@ -2419,23 +2433,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); + + /* 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; - for (; it; it = g_slist_next(it)) - client_calc_layer_recursive(it->data, orig, 0); + /* 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) @@ -2853,6 +2898,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; @@ -2875,6 +2921,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. @@ -2979,6 +3026,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) @@ -3201,6 +3256,11 @@ void client_close(ObClient *self) { if (!(self->functions & OB_CLIENT_FUNC_CLOSE)) return; + if (self->prompt) { + prompt_cancel(self->prompt); + return; + } + /* in the case that the client provides no means to requesting that it close, we just kill it */ if (!self->delete_window)