X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=e06fa2916fd404a83751154c6a4b5eff7391518e;hb=0fedacf700e9f8af32a8fdda91a369b5562ab4ba;hp=aac52e2dc338bcff8e7dd8096ba9b2f5c2f2182e;hpb=cdb108c76d20e8272bfbd15919e32e609d685322;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index aac52e2d..e06fa291 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -32,6 +32,7 @@ #include "event.h" #include "grab.h" #include "focus.h" +#include "propwin.h" #include "stacking.h" #include "openbox.h" #include "group.h" @@ -62,23 +63,19 @@ typedef struct } ClientCallback; GList *client_list = NULL; -GHashTable *client_user_time_window_map; static GSList *client_destructors = NULL; -static void client_get_all(ObClient *self); +static void client_get_all(ObClient *self, gboolean real); static void client_toggle_border(ObClient *self, gboolean show); static void client_get_startup_id(ObClient *self); static void client_get_session_ids(ObClient *self); static void client_get_area(ObClient *self); static void client_get_desktop(ObClient *self); static void client_get_state(ObClient *self); -static void client_get_layer(ObClient *self); static void client_get_shaped(ObClient *self); static void client_get_mwm_hints(ObClient *self); -static void client_get_gravity(ObClient *self); static void client_get_colormap(ObClient *self); -static void client_get_transientness(ObClient *self); static void client_change_allowed_actions(ObClient *self); static void client_change_state(ObClient *self); static void client_change_wm_state(ObClient *self); @@ -95,23 +92,16 @@ static GSList *client_search_all_top_parents_internal(ObClient *self, gboolean bylayer, ObStackingLayer layer); -static guint window_hash(Window *w) { return *w; } -static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; } - void client_startup(gboolean reconfig) { if (reconfig) return; - client_user_time_window_map = g_hash_table_new((GHashFunc)window_hash, - (GEqualFunc)window_comp); client_set_list(); } void client_shutdown(gboolean reconfig) { if (reconfig) return; - - g_hash_table_destroy(client_user_time_window_map); } void client_add_destructor(ObClientCallback func, gpointer data) @@ -243,8 +233,8 @@ void client_manage(Window window) 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 */ + /* 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(ob_display, window, DestroyNotify, &e) || XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e)) { @@ -284,7 +274,6 @@ void client_manage(Window window) XChangeWindowAttributes(ob_display, window, CWEventMask|CWDontPropagate, &attrib_set); - /* create the ObClient struct, and populate it from the hints on the window */ self = g_new0(ObClient, 1); @@ -293,47 +282,52 @@ void client_manage(Window window) /* non-zero defaults */ self->wmstate = WithdrawnState; /* make sure it gets updated first time */ - self->layer = -1; + self->gravity = NorthWestGravity; self->desktop = screen_num_desktops; /* always an invalid value */ self->user_time = focus_client ? focus_client->user_time : CurrentTime; - client_get_all(self); - /* per-app settings override stuff, and return the settings for other - uses too */ + /* get all the stuff off the window */ + client_get_all(self, TRUE); + + /* specify that if we exit, the window should not be destroyed and + should be reparented back to root automatically */ + XChangeSaveSet(ob_display, window, SetModeInsert); + + /* create the decoration frame for the client window */ + self->frame = frame_new(self); + + frame_grab_client(self->frame); + + /* we've grabbed everything and set everything that we need to at mapping + time now */ + grab_server(FALSE); + + /* per-app settings override stuff from client_get_all, and return the + settings for other uses too */ settings = client_get_settings_state(self); - /* the session should get the last say */ + /* the session should get the last say thought */ client_restore_session_state(self); - client_calc_layer(self); + /* now we have all of the window's information so we can set this up */ + client_setup_decor_and_functions(self); + /* remove the client's border (and adjust re gravity) */ + client_toggle_border(self, FALSE); + { Time t = sn_app_started(self->startup_id, self->class); if (t) self->user_time = t; } - /* update the focus lists, do this before the call to change_state or - it can end up in the list twice! */ - focus_order_add_new(self); - - /* remove the client's border (and adjust re gravity) */ - client_toggle_border(self, FALSE); - - /* specify that if we exit, the window should not be destroyed and should - be reparented back to root automatically */ - XChangeSaveSet(ob_display, window, SetModeInsert); - - /* create the decoration frame for the client window */ - self->frame = frame_new(self); - - frame_grab_client(self->frame, self); - /* do this after we have a frame.. it uses the frame to help determine the WM_STATE to apply. */ client_change_state(self); - grab_server(FALSE); + /* add ourselves to the focus order */ + focus_order_add_new(self); - stacking_add_nonintrusive(CLIENT_AS_WINDOW(self)); + /* do this to add ourselves to the stacking list in a non-intrusive way */ + client_calc_layer(self); /* focus the new window? */ if (ob_state() != OB_STATE_STARTING && @@ -461,9 +455,12 @@ void client_manage(Window window) raised to the top. Legacy begets legacy I guess? */ if (!client_restore_session_stacking(self)) - client_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); } + /* adjust the frame to the client's size before showing the window */ + frame_adjust_area(self->frame, FALSE, TRUE, FALSE); + /* this has to happen before we try focus the window, but we want it to happen after the client's stacking has been determined or it looks bad */ @@ -491,6 +488,34 @@ void client_manage(Window window) client_set_list(); ob_debug("Managed window 0x%lx (%s)\n", window, self->class); + + return; +} + + +ObClient *client_fake_manage(Window window) +{ + ObClient *self; + ObAppSettings *settings; + + ob_debug("Pretend-managing window: %lx\n", window); + + /* do this minimal stuff to figure out the client's decorations */ + + self = g_new0(ObClient, 1); + self->window = window; + + client_get_all(self, FALSE); + /* per-app settings override stuff, and return the settings for other + uses too */ + settings = client_get_settings_state(self); + + client_setup_decor_and_functions(self); + + /* create the decoration frame for the client window and adjust its size */ + self->frame = frame_new(self); + frame_adjust_area(self->frame, FALSE, TRUE, TRUE); + return self; } void client_unmanage_all() @@ -504,24 +529,21 @@ void client_unmanage(ObClient *self) guint j; GSList *it; - ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window, self->class, - self->title ? self->title : ""); + ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window, + self->class, self->title ? self->title : ""); g_assert(self != NULL); /* we dont want events no more. do this before hiding the frame so we don't generate more events */ XSelectInput(ob_display, self->window, NoEventMask); - if (self->user_time_window) { - XSelectInput(ob_display, self->user_time_window, NoEventMask); - g_hash_table_remove(client_user_time_window_map, &w); - } frame_hide(self->frame); /* flush to send the hide to the server quickly */ XFlush(ob_display); - /* ignore enter events from the unmap so it doesnt mess with the focus */ + /* ignore enter events from the unmap so it doesnt mess with the + focus */ event_ignore_queued_enters(); mouse_grab_for_client(self, FALSE); @@ -529,6 +551,9 @@ void client_unmanage(ObClient *self) /* remove the window from our save set */ XChangeSaveSet(ob_display, self->window, SetModeDelete); + /* kill the property windows */ + propwin_remove(self->user_time_window, OB_PROPWIN_USER_TIME, self); + /* update the focus lists */ focus_order_remove(self); if (client_focused(self)) { @@ -555,7 +580,7 @@ void client_unmanage(ObClient *self) for (it = self->group->members; it; it = g_slist_next(it)) if (it->data != self) ((ObClient*)it->data)->transients = - g_slist_remove(((ObClient*)it->data)->transients, self); + g_slist_remove(((ObClient*)it->data)->transients,self); } else if (self->transient_for) { /* transient of window */ self->transient_for->transients = g_slist_remove(self->transient_for->transients, self); @@ -577,7 +602,12 @@ void client_unmanage(ObClient *self) /* restore the window's original geometry so it is not lost */ { - Rect a = self->area; + Rect a; + + /* give the client its border back */ + client_toggle_border(self, TRUE); + + a = self->area; if (self->fullscreen) a = self->pre_fullscreen_area; @@ -592,9 +622,6 @@ void client_unmanage(ObClient *self) } } - /* give the client its border back */ - client_toggle_border(self, TRUE); - self->fullscreen = self->max_horz = self->max_vert = FALSE; self->decorations = 0; /* unmanaged windows have no decor */ @@ -602,7 +629,8 @@ void client_unmanage(ObClient *self) } /* reparent the window out of the frame, and free the frame */ - frame_release_client(self->frame, self); + frame_release_client(self->frame); + frame_free(self->frame); self->frame = NULL; if (ob_state() != OB_STATE_EXITING) { @@ -612,11 +640,15 @@ 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 unmapped state, the client wont be mapped. this - is bad, since we will no longer be managing the window on restart */ + /* 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); } + /* update the list hints */ + client_set_list(); + ob_debug("Unmanaged window 0x%lx\n", self->window); /* free all data allocated in the client struct */ @@ -634,9 +666,14 @@ void client_unmanage(ObClient *self) g_free(self->client_machine); g_free(self->sm_client_id); g_free(self); - - /* update the list hints */ - client_set_list(); +} + +void client_fake_unmanage(ObClient *self) +{ + /* this is all that got allocated to get the decorations */ + + frame_free(self->frame); + g_free(self); } static ObAppSettings *client_get_settings_state(ObClient *self) @@ -957,35 +994,39 @@ static void client_toggle_border(ObClient *self, gboolean show) } -static void client_get_all(ObClient *self) +static void client_get_all(ObClient *self, gboolean real) { + /* this is needed for the frame to set itself up */ client_get_area(self); + + /* these things can change the decor and functions of the window */ + client_get_mwm_hints(self); + /* this can change the mwmhints for special cases */ + client_get_type_and_transientness(self); + client_get_state(self); + client_update_normal_hints(self); - /* The transient-ness of a window is used to pick a type, but the type can - also affect transiency. + /* get the session related properties, these can change decorations + from per-app settings */ + client_get_session_ids(self); - Dialogs are always made transients for their group if they have one. + /* now we got everything that can affect the decorations */ + if (!real) + return; - I also have made non-application type windows be transients for their - group (eg utility windows). - */ - client_get_transientness(self); - client_get_type(self);/* this can change the mwmhints for special cases */ - client_get_state(self); + client_update_protocols(self); client_update_wmhints(self); /* this may have already been called from client_update_wmhints */ if (self->transient_for == NULL) client_update_transient_for(self); + client_get_startup_id(self); client_get_desktop(self);/* uses transient data/group/startup id if a desktop is not specified */ client_get_shaped(self); - client_get_layer(self); /* if layer hasn't been specified, get it from - other sources if possible */ - { /* a couple type-based defaults for new windows */ @@ -993,24 +1034,11 @@ static void client_get_all(ObClient *self) if (self->type == OB_CLIENT_TYPE_DESKTOP) self->desktop = DESKTOP_ALL; } - - client_update_protocols(self); - - client_get_gravity(self); /* get the attribute gravity */ - client_update_normal_hints(self); /* this may override the attribute - gravity */ - - /* got the type, the mwmhints, the protocols, and the normal hints - (min/max sizes), so we're ready to set up the decorations/functions */ - client_setup_decor_and_functions(self); #ifdef SYNC client_update_sync_request_counter(self); #endif - /* get the session related properties */ - client_get_session_ids(self); - client_get_colormap(self); client_update_title(self); client_update_strut(self); @@ -1086,41 +1114,6 @@ static void client_get_desktop(ObClient *self) } } -static void client_get_layer(ObClient *self) -{ - 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) && - client_normal(self) && client_normal(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_state(ObClient *self) { guint32 *state; @@ -1178,20 +1171,12 @@ static void client_get_shaped(ObClient *self) #endif } -void client_get_transientness(ObClient *self) -{ - Window t; - if (XGetTransientForHint(ob_display, self->window, &t)) - self->transient = TRUE; -} - void client_update_transient_for(ObClient *self) { Window t = None; ObClient *target = NULL; if (XGetTransientForHint(ob_display, self->window, &t)) { - self->transient = TRUE; if (t != self->window) { /* cant be transient to itself! */ target = g_hash_table_lookup(window_map, &t); /* if this happens then we need to check for it*/ @@ -1228,16 +1213,8 @@ void client_update_transient_for(ObClient *self) } } } - } else if (self->type == OB_CLIENT_TYPE_DIALOG || - self->type == OB_CLIENT_TYPE_TOOLBAR || - self->type == OB_CLIENT_TYPE_MENU || - self->type == OB_CLIENT_TYPE_UTILITY) - { - self->transient = TRUE; - if (self->group) - target = OB_TRAN_GROUP; - } else - self->transient = FALSE; + } else if (self->transient && self->group) + target = OB_TRAN_GROUP; client_update_transient_tree(self, self->group, self->group, self->transient_for, target); @@ -1372,12 +1349,14 @@ static void client_get_mwm_hints(ObClient *self) } } -void client_get_type(ObClient *self) +void client_get_type_and_transientness(ObClient *self) { guint num, i; guint32 *val; + Window t; self->type = -1; + self->transient = FALSE; if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) { /* use the first value that we know about in the array */ @@ -1411,7 +1390,10 @@ void client_get_type(ObClient *self) } g_free(val); } - + + if (XGetTransientForHint(ob_display, self->window, &t)) + self->transient = TRUE; + if (self->type == (ObClientType) -1) { /*the window type hint was not set, which means we either classify ourself as a normal window or a dialog, depending on if we are a @@ -1421,6 +1403,15 @@ void client_get_type(ObClient *self) else self->type = OB_CLIENT_TYPE_NORMAL; } + + /* then, based on our type, we can update our transientness.. */ + if (self->type == OB_CLIENT_TYPE_DIALOG || + self->type == OB_CLIENT_TYPE_TOOLBAR || + self->type == OB_CLIENT_TYPE_MENU || + self->type == OB_CLIENT_TYPE_UTILITY) + { + self->transient = TRUE; + } } void client_update_protocols(ObClient *self) @@ -1464,16 +1455,6 @@ void client_update_sync_request_counter(ObClient *self) } #endif -static void client_get_gravity(ObClient *self) -{ - XWindowAttributes wattrib; - Status ret; - - ret = XGetWindowAttributes(ob_display, self->window, &wattrib); - g_assert(ret != BadWindow); - self->gravity = wattrib.win_gravity; -} - void client_get_colormap(ObClient *self) { XWindowAttributes wa; @@ -1657,7 +1638,7 @@ void client_setup_decor_and_functions(ObClient *self) /* kill the handle on fully maxed windows */ if (self->max_vert && self->max_horz) - self->decorations &= ~OB_FRAME_DECOR_HANDLE; + self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS); /* finally, the user can have requested no decorations, which overrides everything (but doesnt give it a border if it doesnt have one) */ @@ -1723,7 +1704,7 @@ static void client_change_allowed_actions(ObClient *self) else self->shaded = FALSE; } if (!(self->functions & OB_CLIENT_FUNC_ICONIFY) && self->iconic) { - if (self->frame) client_iconify(self, FALSE, TRUE); + if (self->frame) client_iconify(self, FALSE, TRUE, FALSE); else self->iconic = FALSE; } if (!(self->functions & OB_CLIENT_FUNC_FULLSCREEN) && self->fullscreen) { @@ -2058,17 +2039,14 @@ void client_update_user_time(ObClient *self) void client_update_user_time_window(ObClient *self) { guint32 w; - ObClient *c; if (!PROP_GET32(self->window, net_wm_user_time_window, window, &w)) w = None; if (w != self->user_time_window) { - if (self->user_time_window) { - XSelectInput(ob_display, self->user_time_window, NoEventMask); - g_hash_table_remove(client_user_time_window_map, &w); - self->user_time_window = None; - } + /* remove the old window */ + propwin_remove(self->user_time_window, OB_PROPWIN_USER_TIME, self); + self->user_time_window = None; if (self->group && self->group->leader == w) { ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its " @@ -2080,20 +2058,12 @@ void client_update_user_time_window(ObClient *self) "_NET_WM_USER_TIME_WINDOW to itself\n"); w = None; /* don't do it */ } - else if (((c = g_hash_table_lookup(client_user_time_window_map,&w)))) { - ob_debug_type(OB_DEBUG_APP_BUGS, "Client %s is trying to use " - "the _NET_WM_USER_TIME_WINDOW of %s\n", - self->title, c->title); - w = None; /* don't do it */ - } + /* add the new window */ + propwin_add(w, OB_PROPWIN_USER_TIME, self); self->user_time_window = w; - if (self->user_time_window != None) { - XSelectInput(ob_display,self->user_time_window,PropertyChangeMask); - g_hash_table_insert(client_user_time_window_map, - &self->user_time_window, self); - } + /* and update from it */ client_update_user_time(self); } } @@ -2203,6 +2173,8 @@ static void client_get_session_ids(ObClient *self) localhost[127] = '\0'; if (strcmp(localhost, s) != 0) self->client_machine = s; + else + g_free(s); } } @@ -2334,7 +2306,7 @@ static ObStackingLayer calc_layer(ObClient *self) } static void client_calc_layer_recursive(ObClient *self, ObClient *orig, - ObStackingLayer min, gboolean raised) + ObStackingLayer min) { ObStackingLayer old, own; GSList *it; @@ -2343,16 +2315,14 @@ static void client_calc_layer_recursive(ObClient *self, ObClient *orig, own = calc_layer(self); self->layer = MAX(own, min); + if (self->layer != old) { + stacking_remove(CLIENT_AS_WINDOW(self)); + stacking_add_nonintrusive(CLIENT_AS_WINDOW(self)); + } + for (it = self->transients; it; it = g_slist_next(it)) client_calc_layer_recursive(it->data, orig, - self->layer, - raised ? raised : self->layer != old); - - if (!raised && self->layer != old) - if (orig->frame) { /* only restack if the original window is managed */ - stacking_remove(CLIENT_AS_WINDOW(self)); - stacking_add(CLIENT_AS_WINDOW(self)); - } + self->layer); } void client_calc_layer(ObClient *self) @@ -2366,7 +2336,7 @@ void client_calc_layer(ObClient *self) it = client_search_all_top_parents(self); for (; it; it = g_slist_next(it)) - client_calc_layer_recursive(it->data, orig, 0, FALSE); + client_calc_layer_recursive(it->data, orig, 0); } gboolean client_should_show(ObClient *self) @@ -2472,7 +2442,7 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y) if (self->iconic) { self->iconic = FALSE; - client_iconify(self, TRUE, FALSE); + client_iconify(self, TRUE, FALSE, TRUE); } if (self->fullscreen) { self->fullscreen = FALSE; @@ -2697,12 +2667,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, - gboolean user, gboolean final, - gboolean force_reply) + gboolean user, gboolean final) { - gint oldw, oldh, oldrx, oldry; + gint oldw, oldh; gboolean send_resize_client; - gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE; + gboolean moved = FALSE, resized = FALSE; guint fdecor = self->frame->decorations; gboolean fhorz = self->frame->max_horz; gint logicalw, logicalh; @@ -2742,17 +2711,7 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, if (moved || resized) frame_adjust_area(self->frame, moved, resized, FALSE); - /* find the client's position relative to the root window */ - oldrx = self->root_pos.x; - oldry = self->root_pos.y; - rootmoved = (oldrx != (signed)(self->frame->area.x + - self->frame->size.left - - self->border_width) || - oldry != (signed)(self->frame->area.y + - self->frame->size.top - - self->border_width)); - - if (force_reply || ((!user || (user && final)) && rootmoved)) + if ((!user || (user && final)) && !resized) { XEvent event; @@ -2767,6 +2726,9 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, event.xconfigure.event = self->window; event.xconfigure.window = self->window; + ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d\n", + self->title, self->root_pos.x, self->root_pos.y, w, h); + /* root window real coords */ event.xconfigure.x = self->root_pos.x; event.xconfigure.y = self->root_pos.y; @@ -2847,7 +2809,8 @@ void client_fullscreen(ObClient *self, gboolean fs) } static void client_iconify_recursive(ObClient *self, - gboolean iconic, gboolean curdesk) + gboolean iconic, gboolean curdesk, + gboolean hide_animation) { GSList *it; gboolean changed = FALSE; @@ -2887,7 +2850,7 @@ static void client_iconify_recursive(ObClient *self, if (changed) { client_change_state(self); - if (ob_state() != OB_STATE_STARTING && config_animate_iconify) + if (config_animate_iconify && !hide_animation) frame_begin_iconify_animation(self->frame, iconic); /* do this after starting the animation so it doesn't flash */ client_showhide(self); @@ -2898,15 +2861,17 @@ static void client_iconify_recursive(ObClient *self, for (it = self->transients; it; it = g_slist_next(it)) if (it->data != self) if (client_is_direct_child(self, it->data) || !iconic) - client_iconify_recursive(it->data, iconic, curdesk); + client_iconify_recursive(it->data, iconic, curdesk, + hide_animation); } -void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk) +void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk, + gboolean hide_animation) { if (self->functions & OB_CLIENT_FUNC_ICONIFY || !iconic) { /* move up the transient chain as far as possible first */ self = client_search_top_normal_parent(self); - client_iconify_recursive(self, iconic, curdesk); + client_iconify_recursive(self, iconic, curdesk, hide_animation); } } @@ -3079,7 +3044,7 @@ void client_set_desktop_recursive(ObClient *self, client_showhide(self); /* raise if it was not already on the desktop */ if (old != DESKTOP_ALL) - client_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); if (STRUT_EXISTS(self->strut)) screen_update_areas(); } @@ -3140,10 +3105,10 @@ void client_set_wm_state(ObClient *self, glong state) switch (state) { case IconicState: - client_iconify(self, TRUE, TRUE); + client_iconify(self, TRUE, TRUE, FALSE); break; case NormalState: - client_iconify(self, FALSE, TRUE); + client_iconify(self, FALSE, TRUE, FALSE); break; } } @@ -3304,10 +3269,10 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) self->modal = modal; /* when a window changes modality, then its stacking order with its transients needs to change */ - client_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); } if (iconic != self->iconic) - client_iconify(self, iconic, FALSE); + client_iconify(self, iconic, FALSE, FALSE); if (demands_attention != self->demands_attention) client_hilite(self, demands_attention); @@ -3430,9 +3395,9 @@ static void client_present(ObClient *self, gboolean here, gboolean raise) event_halt_focus_delay(); if (client_normal(self) && screen_showing_desktop) - screen_show_desktop(FALSE, FALSE); + screen_show_desktop(FALSE, self); if (self->iconic) - client_iconify(self, FALSE, here); + client_iconify(self, FALSE, here, FALSE); if (self->desktop != DESKTOP_ALL && self->desktop != screen_desktop) { @@ -3446,17 +3411,10 @@ static void client_present(ObClient *self, gboolean here, gboolean raise) return; if (self->shaded) client_shade(self, FALSE); + if (raise) + stacking_raise(CLIENT_AS_WINDOW(self)); client_focus(self); - - if (raise) { - /* we do this as an action here. this is rather important. this is - because we want the results from the focus change to take place - BEFORE we go about raising the window. when a fullscreen window - loses focus, we need this or else the raise wont be able to raise - above the to-lose-focus fullscreen window. */ - client_raise(self); - } } void client_activate(ObClient *self, gboolean here, gboolean user) @@ -3512,16 +3470,6 @@ void client_bring_helper_windows(ObClient *self) client_bring_helper_windows_recursive(self, self->desktop); } -void client_raise(ObClient *self) -{ - action_run_string("Raise", self, CurrentTime); -} - -void client_lower(ObClient *self) -{ - action_run_string("Lower", self, CurrentTime); -} - gboolean client_focused(ObClient *self) { return self == focus_client;