X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=ed2e5b561e1c75a214de30b36817a967ee445bb6;hb=7b4556b2111b03dcdca4a58e1bde94a66ba86806;hp=1eba49f82e3c9c9c929b8bb075a21b8f3310e61b;hpb=457fdc5ccbb65dc4b5e6cd972e048e3218527b91;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 1eba49f8..ed2e5b56 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -105,6 +105,7 @@ static GSList *client_search_all_top_parents_internal(ObClient *self, ObStackingLayer layer); static void client_call_notifies(ObClient *self, GSList *list); static void client_ping_event(ObClient *self, gboolean dead); +static void client_prompt_kill(ObClient *self); void client_startup(gboolean reconfig) @@ -270,8 +271,10 @@ void client_manage(Window window, ObPrompt *prompt) 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(ob_display, window, CWEventMask|CWDontPropagate, &attrib_set); @@ -300,7 +303,8 @@ void client_manage(Window window, ObPrompt *prompt) client_setup_decor_and_functions(self, FALSE); /* specify that if we exit, the window should not be destroyed and - should be reparented back to root automatically */ + should be reparented back to root automatically, unless we are managing + an internal ObPrompt window */ if (!self->prompt) XChangeSaveSet(ob_display, window, SetModeInsert); @@ -702,7 +706,8 @@ void client_unmanage(ObClient *self) mouse_grab_for_client(self, FALSE); - /* remove the window from our save set */ + /* remove the window from our save set, unless we are managing an internal + ObPrompt window */ if (!self->prompt) XChangeSaveSet(ob_display, self->window, SetModeDelete); @@ -713,6 +718,10 @@ void client_unmanage(ObClient *self) focus_client = NULL; } + /* if we're prompting to kill the client, close that */ + prompt_unref(self->kill_prompt); + self->kill_prompt = NULL; + client_list = g_list_remove(client_list, self); stacking_remove(self); g_hash_table_remove(window_map, &self->window); @@ -811,6 +820,7 @@ void client_unmanage(ObClient *self) g_free(self->wm_command); g_free(self->title); g_free(self->icon_title); + g_free(self->original_title); g_free(self->name); g_free(self->class); g_free(self->role); @@ -1965,6 +1975,7 @@ void client_update_title(ObClient *self) gchar *visible = NULL; g_free(self->title); + g_free(self->original_title); /* try netwm */ if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) { @@ -1981,6 +1992,7 @@ void client_update_title(ObClient *self) data = g_strdup("Unnamed Window"); } } + self->original_title = g_strdup(data); if (self->client_machine) { visible = g_strdup_printf("%s (%s)", data, self->client_machine); @@ -1990,7 +2002,7 @@ void client_update_title(ObClient *self) if (self->not_responding) { data = visible; - if (self->close_tried_term) + if (self->kill_level > 0) visible = g_strdup_printf("%s - [%s]", data, _("Killing...")); else visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); @@ -2022,7 +2034,7 @@ void client_update_title(ObClient *self) if (self->not_responding) { data = visible; - if (self->close_tried_term) + if (self->kill_level > 0) visible = g_strdup_printf("%s - [%s]", data, _("Killing...")); else visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); @@ -3336,9 +3348,14 @@ static void client_ping_event(ObClient *self, gboolean dead) client_update_title(self); if (!dead) { - /* try kill it nicely the first time again, if it started responding - at some point */ - self->close_tried_term = FALSE; + /* it came back to life ! */ + + if (self->kill_prompt) { + prompt_unref(self->kill_prompt); + self->kill_prompt = NULL; + } + + self->kill_level = 0; } } @@ -3347,7 +3364,7 @@ void client_close(ObClient *self) if (!(self->functions & OB_CLIENT_FUNC_CLOSE)) return; if (self->prompt) { - prompt_hide(self); + prompt_cancel(self->prompt); return; } @@ -3357,24 +3374,67 @@ void client_close(ObClient *self) /* don't use client_kill(), we should only kill based on PID in response to a lack of PING replies */ XKillClient(ob_display, self->window); - else if (self->not_responding) - client_kill(self); - else + else { /* request the client to close with WM_DELETE_WINDOW */ PROP_MSG_TO(self->window, self->window, wm_protocols, prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, NoEventMask); + + if (self->not_responding) + client_prompt_kill(self); + } +} + +#define OB_KILL_RESULT_NO 0 +#define OB_KILL_RESULT_YES 1 + +static void client_kill_requested(ObPrompt *p, gint result, gpointer data) +{ + ObClient *self = data; + + if (result == OB_KILL_RESULT_YES) + client_kill(self); + + prompt_unref(self->kill_prompt); + self->kill_prompt = NULL; +} + +static void client_prompt_kill(ObClient *self) +{ + /* check if we're already prompting */ + if (!self->kill_prompt) { + ObPromptAnswer answers[] = { + { _("No"), OB_KILL_RESULT_NO }, + { _("Yes"), OB_KILL_RESULT_YES } + }; + gchar *m; + + m = g_strdup_printf + (_("The window \"%s\" does not seem to be responding. Do you want to force it to exit?"), self->original_title); + + self->kill_prompt = prompt_new(m, answers, + sizeof(answers)/sizeof(answers[0]), + OB_KILL_RESULT_NO, /* default = no */ + OB_KILL_RESULT_NO, /* cancel = no */ + client_kill_requested, self); + g_free(m); + } + + prompt_show(self->kill_prompt, self); } void client_kill(ObClient *self) { + /* don't kill our own windows */ + if (self->prompt) return; + if (!self->client_machine && self->pid) { /* running on the local host */ - if (!self->close_tried_term) { - ob_debug("killing window 0x%x with pid %lu, with SIGTERM\n", + if (self->kill_level == 0) { + ob_debug("killing window 0x%x with pid %lu, with SIGTERM", self->window, self->pid); kill(self->pid, SIGTERM); - self->close_tried_term = TRUE; + ++self->kill_level; /* show that we're trying to kill it */ client_update_title(self); @@ -3385,8 +3445,10 @@ void client_kill(ObClient *self) kill(self->pid, SIGKILL); /* kill -9 */ } } - else + else { + /* running on a remote host */ XKillClient(ob_display, self->window); + } } void client_hilite(ObClient *self, gboolean hilite)