ping all the windows every 3 seconds, and show "not responding" if they stop replying for 3 times (9-12 seconds). show [Killing...] in the titlebar when trying to kill an app off

This commit is contained in:
Dana Jansens 2008-01-15 22:34:04 -05:00
parent dbce9ee243
commit 810afd8597
3 changed files with 43 additions and 19 deletions

View file

@ -602,6 +602,9 @@ void client_manage(Window window)
/* update the list hints */ /* update the list hints */
client_set_list(); client_set_list();
/* watch for when the application stops responding */
if (self->ping) ping_start(self, client_ping_event);
/* free the ObAppSettings shallow copy */ /* free the ObAppSettings shallow copy */
g_free(settings); g_free(settings);
@ -683,6 +686,9 @@ void client_unmanage(ObClient *self)
/* remove the window from our save set */ /* remove the window from our save set */
XChangeSaveSet(ob_display, self->window, SetModeDelete); XChangeSaveSet(ob_display, self->window, SetModeDelete);
/* stop pinging the window */
if (self->ping) ping_stop(self);
/* update the focus lists */ /* update the focus lists */
focus_order_remove(self); focus_order_remove(self);
if (client_focused(self)) { if (client_focused(self)) {
@ -1955,7 +1961,10 @@ void client_update_title(ObClient *self)
if (self->not_responding) { if (self->not_responding) {
data = visible; data = visible;
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); if (self->close_tried_term)
visible = g_strdup_printf("%s - [%s]", data, _("Killing..."));
else
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
g_free(data); g_free(data);
} }
@ -1984,7 +1993,10 @@ void client_update_title(ObClient *self)
if (self->not_responding) { if (self->not_responding) {
data = visible; data = visible;
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); if (self->close_tried_term)
visible = g_strdup_printf("%s - [%s]", data, _("Killing..."));
else
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
g_free(data); g_free(data);
} }
@ -3194,6 +3206,14 @@ static void client_ping_event(ObClient *self, gboolean dead)
{ {
self->not_responding = dead; self->not_responding = dead;
client_update_title(self); client_update_title(self);
if (!dead) {
/* the window has started responding again, so don't kill it the first
time they click on close, even if it stops responding again in the
future */
self->close_tried_destroy = FALSE;
self->close_tried_term = FALSE;
}
} }
void client_close(ObClient *self) void client_close(ObClient *self)
@ -3206,20 +3226,14 @@ void client_close(ObClient *self)
/* don't use client_kill(), we should only kill based on PID in /* don't use client_kill(), we should only kill based on PID in
response to a lack of PING replies */ response to a lack of PING replies */
XKillClient(ob_display, self->window); XKillClient(ob_display, self->window);
else if (self->not_responding) else if (self->not_responding && self->close_tried_destroy)
client_kill(self); client_kill(self);
else { else {
PROP_MSG_TO(self->window, self->window, wm_protocols, PROP_MSG_TO(self->window, self->window, wm_protocols,
prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
NoEventMask); NoEventMask);
self->close_tried_destroy = TRUE;
if (self->ping) { self->close_tried_term = FALSE;
/* may have tried to kill it earlier but the window is still
around and started responding again */
self->kill_tried_term = FALSE;
ping_start(self, client_ping_event);
}
} }
} }
@ -3227,12 +3241,20 @@ void client_kill(ObClient *self)
{ {
if (!self->client_machine && self->pid) { if (!self->client_machine && self->pid) {
/* running on the local host */ /* running on the local host */
if (!self->kill_tried_term) { if (!self->close_tried_term) {
ob_debug("killing window 0x%x with pid %lu, with SIGTERM\n",
self->window, self->pid);
kill(self->pid, SIGTERM); kill(self->pid, SIGTERM);
self->kill_tried_term = TRUE; self->close_tried_term = TRUE;
/* show that we're trying to kill it */
client_update_title(self);
} }
else else {
ob_debug("killing window 0x%x with pid %lu, with SIGKILL\n",
self->window, self->pid);
kill(self->pid, SIGKILL); /* kill -9 */ kill(self->pid, SIGKILL); /* kill -9 */
}
} }
else else
XKillClient(ob_display, self->window); XKillClient(ob_display, self->window);

View file

@ -231,8 +231,10 @@ struct _ObClient
/*! Indicates if the client is trying to close but has stopped responding /*! Indicates if the client is trying to close but has stopped responding
to pings */ to pings */
gboolean not_responding; gboolean not_responding;
/*! We tried to kill the client with SIGTERM */ /*! We tried to close the window with a DESTROY message */
gboolean kill_tried_term; gboolean close_tried_destroy;
/*! We tried to close the window with a SIGTERM */
gboolean close_tried_term;
#ifdef SYNC #ifdef SYNC
/*! The client wants to sync during resizes */ /*! The client wants to sync during resizes */

View file

@ -35,7 +35,7 @@ typedef struct _ObPingTarget
static GSList *ping_targets = NULL; static GSList *ping_targets = NULL;
static gboolean active = FALSE; static gboolean active = FALSE;
#define PING_TIMEOUT (G_USEC_PER_SEC * 1) #define PING_TIMEOUT (G_USEC_PER_SEC * 3)
/*! Warn the user after this many PING_TIMEOUT intervals */ /*! Warn the user after this many PING_TIMEOUT intervals */
#define PING_TIMEOUT_WARN 3 #define PING_TIMEOUT_WARN 3
@ -87,7 +87,7 @@ void ping_got_pong(Time timestamp)
for (it = ping_targets; it != NULL; it = g_slist_next(it)) { for (it = ping_targets; it != NULL; it = g_slist_next(it)) {
t = it->data; t = it->data;
if (t->sent == timestamp) { if (t->sent == timestamp) {
ob_debug("Got PONG with timestamp %lu\n", timestamp); /*ob_debug("Got PONG with timestamp %lu\n", timestamp);*/
if (t->waiting > PING_TIMEOUT_WARN) { if (t->waiting > PING_TIMEOUT_WARN) {
/* we had notified that they weren't responding, so now we /* we had notified that they weren't responding, so now we
need to notify that they are again */ need to notify that they are again */
@ -106,7 +106,7 @@ void ping_got_pong(Time timestamp)
static void ping_send(ObPingTarget *t) static void ping_send(ObPingTarget *t)
{ {
t->sent = event_get_server_time(); t->sent = event_get_server_time();
ob_debug("PINGing client 0x%x at %lu\n", t->client->window, t->sent); /*ob_debug("PINGing client 0x%x at %lu\n", t->client->window, t->sent);*/
PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, PROP_MSG_TO(t->client->window, t->client->window, wm_protocols,
prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0,
NoEventMask); NoEventMask);