when you close an app and it stops responding.. if you hit close again, it will...
authorDana Jansens <danakj@orodu.net>
Wed, 16 Jan 2008 03:13:16 +0000 (22:13 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 16 Jan 2008 03:13:16 +0000 (22:13 -0500)
openbox/client.c
openbox/client.h
openbox/prop.c
openbox/prop.h

index 517482c..d768ecc 100644 (file)
 #  include <unistd.h>
 #endif
 
+#ifdef HAVE_SIGNAL_H
+#  include <signal.h> /* for kill() */
+#endif
+
 #include <glib.h>
 #include <X11/Xutil.h>
 
@@ -2244,6 +2248,7 @@ static void client_get_session_ids(ObClient *self)
 
     if (got) {
         gchar localhost[128];
+        guint32 pid;
 
         gethostname(localhost, 127);
         localhost[127] = '\0';
@@ -2251,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;
     }
 }
 
@@ -3193,9 +3203,10 @@ 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)
-        client_kill(self);
-
-    if (self->not_responding)
+        /* 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,
@@ -3209,7 +3220,17 @@ void client_close(ObClient *self)
 
 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)
index 672b382..f568b00 100644 (file)
 #include <glib.h>
 #include <X11/Xlib.h>
 
+#ifdef HAVE_SYS_TYPES_H
+#  include <sys/types.h> /* for pid_t */
+#endif
+
 struct _ObFrame;
 struct _ObGroup;
 struct _ObSessionState;
@@ -115,6 +119,8 @@ struct _ObClient
     gchar *client_machine;
     /*! The command used to run the program. Pre-XSMP window identification. */
     gchar *wm_command;
+    /*! The PID of the process which owns the window */
+    pid_t pid;
 
     /*! The application that created the window */
     gchar *name;
@@ -225,6 +231,8 @@ struct _ObClient
     /*! Indicates if the client is trying to close but has stopped responding
       to pings */
     gboolean not_responding;
+    /*! We tried to kill the client with SIGTERM */
+    gboolean kill_tried_term;
 
 #ifdef SYNC
     /*! The client wants to sync during resizes */
index b43dcd1..c4b8bae 100644 (file)
@@ -91,7 +91,7 @@ void prop_startup(void)
     CREATE(net_wm_strut_partial, "_NET_WM_STRUT_PARTIAL");
     CREATE(net_wm_icon, "_NET_WM_ICON");
     CREATE(net_wm_icon_geometry, "_NET_WM_ICON_GEOMETRY");
-/*   CREATE(net_wm_pid, "_NET_WM_PID"); */
+    CREATE(net_wm_pid, "_NET_WM_PID");
     CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS");
     CREATE(net_wm_user_time, "_NET_WM_USER_TIME");
 /*    CREATE(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW"); */
index 13c338e..9288414 100644 (file)
@@ -129,7 +129,7 @@ typedef struct Atoms {
     Atom net_wm_strut_partial;
     Atom net_wm_icon;
     Atom net_wm_icon_geometry;
-/*  Atom net_wm_pid; */
+    Atom net_wm_pid;
     Atom net_wm_allowed_actions;
     Atom net_wm_user_time;
 /*  Atom net_wm_user_time_window; */