]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
when you close an app and it stops responding.. if you hit close again, it will...
[chaz/openbox] / openbox / client.c
index 0f592ebe72df9595c79d22840252039f124cf171..d768ecc1ff1e06c17f545e7df19affcba45a3ee9 100644 (file)
 #include "keyboard.h"
 #include "mouse.h"
 #include "render/render.h"
+#include "gettext.h"
 
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
 #endif
 
+#ifdef HAVE_SIGNAL_H
+#  include <signal.h> /* for kill() */
+#endif
+
 #include <glib.h>
 #include <X11/Xutil.h>
 
@@ -93,6 +98,7 @@ static GSList *client_search_all_top_parents_internal(ObClient *self,
                                                       gboolean bylayer,
                                                       ObStackingLayer layer);
 static void client_call_notifies(ObClient *self, GSList *list);
+static void client_ping_event(ObClient *self, gboolean dead);
 
 
 void client_startup(gboolean reconfig)
@@ -1947,6 +1953,12 @@ void client_update_title(ObClient *self)
     } else
         visible = data;
 
+    if (self->not_responding) {
+        data = visible;
+        visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
+        g_free(data);
+    }
+
     PROP_SETS(self->window, net_wm_visible_name, visible);
     self->title = visible;
 
@@ -1970,6 +1982,12 @@ void client_update_title(ObClient *self)
     } else
         visible = data;
 
+    if (self->not_responding) {
+        data = visible;
+        visible = g_strdup_printf("%s - [%s]", data, _("Not Responding"));
+        g_free(data);
+    }
+
     PROP_SETS(self->window, net_wm_visible_icon_name, visible);
     self->icon_title = visible;
 }
@@ -2230,6 +2248,7 @@ static void client_get_session_ids(ObClient *self)
 
     if (got) {
         gchar localhost[128];
+        guint32 pid;
 
         gethostname(localhost, 127);
         localhost[127] = '\0';
@@ -2237,6 +2256,11 @@ static void client_get_session_ids(ObClient *self)
             self->client_machine = s;
         else
             g_free(s);
+
+        /* see if it has the PID set too (the PID requires that the
+           WM_CLIENT_MACHINE be set) */
+        if (PROP_GET32(self->window, net_wm_pid, cardinal, &pid))
+            self->pid = pid;
     }
 }
 
@@ -3168,10 +3192,8 @@ void client_shade(ObClient *self, gboolean shade)
 
 static void client_ping_event(ObClient *self, gboolean dead)
 {
-    if (dead)
-        ob_debug("client 0x%x window 0x%x is not responding !!\n");
-    else
-        ob_debug("client 0x%x window 0x%x started responding again..\n");
+    self->not_responding = dead;
+    client_update_title(self);
 }
 
 void client_close(ObClient *self)
@@ -3181,26 +3203,34 @@ void client_close(ObClient *self)
     /* in the case that the client provides no means to requesting that it
        close, we just kill it */
     if (!self->delete_window)
+        /* 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 {
+        PROP_MSG_TO(self->window, self->window, wm_protocols,
+                    prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
+                    NoEventMask);
 
-    /*
-      XXX: itd be cool to do timeouts and shit here for killing the client's
-      process off
-      like... if the window is around after 5 seconds, then the close button
-      turns a nice red, and if this function is called again, the client is
-      explicitly killed.
-    */
-
-    PROP_MSG_TO(self->window, self->window, wm_protocols,
-                prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
-                NoEventMask);
-
-    ping_start(self, client_ping_event);
+        if (self->ping)
+            ping_start(self, client_ping_event);
+    }
 }
 
 void client_kill(ObClient *self)
 {
-    XKillClient(ob_display, self->window);
+    if (!self->client_machine && self->pid) {
+        /* running on the local host */
+        if (!self->kill_tried_term) {
+            kill(self->pid, SIGTERM);
+            self->kill_tried_term = TRUE;
+        }
+        else
+            kill(self->pid, SIGKILL); /* kill -9 */
+    }
+    else
+        XKillClient(ob_display, self->window);
 }
 
 void client_hilite(ObClient *self, gboolean hilite)
This page took 0.033343 seconds and 4 git commands to generate.