X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=e9443d4914e256ac5647e7ef2dafd261c7ca13b8;hb=4b5373f609e6462995a38cc4f0f50b17cbc8f835;hp=7c23e8e0a160d78d6ab0dfd7864f56d9658281b2;hpb=435df32acc55a3bc4cc8f9ba954ae21b65c7c69d;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 7c23e8e0..e9443d49 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -414,6 +414,12 @@ void client_manage(Window window, ObPrompt *prompt) activate ? "yes" : "no"); if (activate) { gboolean raise = FALSE; + gboolean relative_focused = FALSE; + + relative_focused = (focus_client != NULL && + client_search_focus_tree_full(self) != NULL && + client_search_focus_group_full(self) != NULL); + /* This is focus stealing prevention */ ob_debug_type(OB_DEBUG_FOCUS, @@ -444,10 +450,8 @@ void client_manage(Window window, ObPrompt *prompt) "Not focusing the window because its on another " "desktop"); } - /* If something is focused, and it's not our relative... */ - else if (focus_client && client_search_focus_tree_full(self) == NULL && - client_search_focus_group_full(self) == NULL) - { + /* If something is focused... */ + else if (focus_client) { /* If the user is working in another window right now, then don't steal focus */ if (event_last_user_time && launch_time && @@ -461,8 +465,9 @@ void client_manage(Window window, ObPrompt *prompt) "Not focusing the window because the user is " "working in another window"); } - /* If it's a transient (and its parents aren't focused) */ - else if (client_has_parent(self)) { + /* If the new window is a transient (and its relatives aren't + focused) */ + else if (client_has_parent(self) && !relative_focused) { activate = FALSE; ob_debug_type(OB_DEBUG_FOCUS, "Not focusing the window because it is a " @@ -488,8 +493,11 @@ void client_manage(Window window, ObPrompt *prompt) "Not focusing the window because another window " "would get the focus anyway"); } + /* Don't move focus if the window is not visible on the current + desktop and none of its relatives are focused */ else if (!(self->desktop == screen_desktop || - self->desktop == DESKTOP_ALL)) + self->desktop == DESKTOP_ALL) && + !relative_focused) { activate = FALSE; raise = TRUE; @@ -562,7 +570,7 @@ void client_manage(Window window, ObPrompt *prompt) ob_debug("Managed window 0x%lx plate 0x%x (%s)", window, self->frame->window, self->class); - hooks_run(OB_HOOK_WIN_NEW, self); + hooks_queue(OB_HOOK_WIN_NEW, self); } @@ -638,6 +646,7 @@ void client_unmanage(ObClient *self) if (!self->prompt) XChangeSaveSet(obt_display, self->window, SetModeDelete); + /* this can't be queued to run later */ hooks_run(OB_HOOK_WIN_CLOSE, self); /* update the focus lists */ @@ -2525,7 +2534,7 @@ gboolean client_show(ObClient *self) */ client_change_wm_state(self); - hooks_run(OB_HOOK_WIN_VISIBLE, self); + hooks_queue(OB_HOOK_WIN_VISIBLE, self); } return show; } @@ -2565,7 +2574,7 @@ gboolean client_hide(ObClient *self) */ client_change_wm_state(self); - hooks_run(OB_HOOK_WIN_INVISIBLE, self); + hooks_queue(OB_HOOK_WIN_INVISIBLE, self); } return hide; } @@ -3162,7 +3171,8 @@ static void client_iconify_recursive(ObClient *self, /* do this after starting the animation so it doesn't flash */ client_showhide(self); - hooks_run((iconic ? OB_HOOK_WIN_ICONIC : OB_HOOK_WIN_UNICONIC), self); + hooks_queue((iconic ? OB_HOOK_WIN_ICONIC : OB_HOOK_WIN_UNICONIC), + self); } /* iconify all direct transients, and deiconify all transients @@ -3251,7 +3261,7 @@ void client_maximize(ObClient *self, gboolean max, gint dir) client_setup_decor_and_functions(self, FALSE); client_move_resize(self, x, y, w, h); - hooks_run((max ? OB_HOOK_WIN_MAX : OB_HOOK_WIN_UNMAX), self); + hooks_queue((max ? OB_HOOK_WIN_MAX : OB_HOOK_WIN_UNMAX), self); } void client_shade(ObClient *self, gboolean shade) @@ -3266,7 +3276,7 @@ void client_shade(ObClient *self, gboolean shade) /* resize the frame to just the titlebar */ frame_adjust_area(self->frame, FALSE, TRUE, FALSE); - hooks_run((shade ? OB_HOOK_WIN_SHADE : OB_HOOK_WIN_UNSHADE), self); + hooks_queue((shade ? OB_HOOK_WIN_SHADE : OB_HOOK_WIN_UNSHADE), self); } static void client_ping_event(ObClient *self, gboolean dead) @@ -3329,12 +3339,20 @@ void client_close(ObClient *self) #define OB_KILL_RESULT_NO 0 #define OB_KILL_RESULT_YES 1 -static void client_kill_requested(ObPrompt *p, gint result, gpointer data) +static gboolean client_kill_requested(ObPrompt *p, gint result, gpointer data) { ObClient *self = data; if (result == OB_KILL_RESULT_YES) client_kill(self); + return TRUE; /* call the cleanup func */ +} + +static void client_kill_cleanup(ObPrompt *p, gpointer data) +{ + ObClient *self = data; + + g_assert(p == self->kill_prompt); prompt_unref(self->kill_prompt); self->kill_prompt = NULL; @@ -3381,11 +3399,13 @@ static void client_prompt_kill(ObClient *self) answers[0].text = _("Cancel"); /* "no" */ answers[1].text = y; /* "yes" */ - self->kill_prompt = prompt_new(m, answers, + self->kill_prompt = prompt_new(m, NULL, answers, sizeof(answers)/sizeof(answers[0]), OB_KILL_RESULT_NO, /* default = no */ OB_KILL_RESULT_NO, /* cancel = no */ - client_kill_requested, self); + client_kill_requested, + client_kill_cleanup, + self); g_free(m); } @@ -3470,7 +3490,7 @@ static void client_set_desktop_recursive(ObClient *self, client_reconfigure(self, FALSE); if (old != self->desktop) - hooks_run(OB_HOOK_WIN_DESK_CHANGE, self); + hooks_queue(OB_HOOK_WIN_DESK_CHANGE, self); } /* move all transients */ @@ -3874,8 +3894,8 @@ void client_set_undecorated(ObClient *self, gboolean undecorated) client_setup_decor_and_functions(self, TRUE); client_change_state(self); /* reflect this in the state hints */ - hooks_run((undecorated ? - OB_HOOK_WIN_UNDECORATED : OB_HOOK_WIN_DECORATED), self); + hooks_queue((undecorated ? + OB_HOOK_WIN_UNDECORATED : OB_HOOK_WIN_DECORATED), self); } }