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:
parent
dbce9ee243
commit
810afd8597
3 changed files with 43 additions and 19 deletions
|
@ -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,6 +1961,9 @@ void client_update_title(ObClient *self)
|
||||||
|
|
||||||
if (self->not_responding) {
|
if (self->not_responding) {
|
||||||
data = visible;
|
data = visible;
|
||||||
|
if (self->close_tried_term)
|
||||||
|
visible = g_strdup_printf("%s - [%s]", data, _("Killing..."));
|
||||||
|
else
|
||||||
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
|
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
@ -1984,6 +1993,9 @@ void client_update_title(ObClient *self)
|
||||||
|
|
||||||
if (self->not_responding) {
|
if (self->not_responding) {
|
||||||
data = visible;
|
data = visible;
|
||||||
|
if (self->close_tried_term)
|
||||||
|
visible = g_strdup_printf("%s - [%s]", data, _("Killing..."));
|
||||||
|
else
|
||||||
visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
|
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,13 +3241,21 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue