xwm: Plug kill signal for killing X apps
authorTiago Vignatti <tiago.vignatti@intel.com>
Thu, 27 Sep 2012 14:48:37 +0000 (17:48 +0300)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 4 Oct 2012 15:07:50 +0000 (11:07 -0400)
Xeyes is the counter-example that fails on that heuristic and won't be caught
on kill binding. This and the last two patches should fix:

    https://bugs.freedesktop.org/show_bug.cgi?id=53679

Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
src/xwayland/window-manager.c
src/xwayland/xwayland.h

index 65eb11a..f5571a5 100644 (file)
@@ -102,6 +102,8 @@ struct weston_wm_window {
        struct wl_event_source *repaint_source;
        struct wl_event_source *configure_source;
        int properties_dirty;
+       int pid;
+       char *machine;
        char *class;
        char *name;
        struct weston_wm_window *transient_for;
@@ -300,7 +302,9 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
                { wm->atom.wm_protocols, TYPE_WM_PROTOCOLS, F(protocols) },
                { wm->atom.net_wm_window_type, XCB_ATOM_ATOM, F(type) },
                { wm->atom.net_wm_name, XCB_ATOM_STRING, F(name) },
+               { wm->atom.net_wm_pid, XCB_ATOM_CARDINAL, F(pid) },
                { wm->atom.motif_wm_hints, TYPE_MOTIF_WM_HINTS, 0 },
+               { wm->atom.wm_client_machine, XCB_ATOM_WM_CLIENT_MACHINE, F(machine) },
        };
 #undef F
 
@@ -338,6 +342,7 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
                p = ((char *) window + props[i].offset);
 
                switch (props[i].type) {
+               case XCB_ATOM_WM_CLIENT_MACHINE:
                case XCB_ATOM_STRING:
                        /* FIXME: We're using this for both string and
                           utf8_string */
@@ -353,6 +358,7 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
                        *(struct weston_wm_window **) p =
                                hash_table_lookup(wm->window_hash, *xid);
                        break;
+               case XCB_ATOM_CARDINAL:
                case XCB_ATOM_ATOM:
                        atom = xcb_get_property_value(reply);
                        *(xcb_atom_t *) p = *atom;
@@ -478,6 +484,25 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve
 }
 
 static void
+weston_wm_kill_client(struct wl_listener *listener, void *data)
+{
+       struct weston_surface *surface = data;
+       struct weston_wm_window *window = get_wm_window(surface);
+       char name[1024];
+
+       if (!window)
+               return;
+
+       gethostname(name, 1024);
+
+       /* this is only one heuristic to guess the PID of a client is valid,
+        * assuming it's compliant with icccm and ewmh. Non-compliants and
+        * remote applications of course fail. */
+       if (!strcmp(window->machine, name) && window->pid != 0)
+               kill(window->pid, SIGKILL);
+}
+
+static void
 weston_wm_window_activate(struct wl_listener *listener, void *data)
 {
        struct weston_surface *surface = data;
@@ -1232,7 +1257,9 @@ wxs_wm_get_resources(struct weston_wm *wm)
                { "WM_DELETE_WINDOW",   F(atom.wm_delete_window) },
                { "WM_STATE",           F(atom.wm_state) },
                { "WM_S0",              F(atom.wm_s0) },
+               { "WM_CLIENT_MACHINE",  F(atom.wm_client_machine) },
                { "_NET_WM_NAME",       F(atom.net_wm_name) },
+               { "_NET_WM_PID",        F(atom.net_wm_pid) },
                { "_NET_WM_ICON",       F(atom.net_wm_icon) },
                { "_NET_WM_STATE",      F(atom.net_wm_state) },
                { "_NET_WM_STATE_FULLSCREEN", F(atom.net_wm_state_fullscreen) },
@@ -1469,6 +1496,9 @@ weston_wm_create(struct weston_xserver *wxs)
        wm->activate_listener.notify = weston_wm_window_activate;
        wl_signal_add(&wxs->compositor->activate_signal,
                      &wm->activate_listener);
+       wm->kill_listener.notify = weston_wm_kill_client;
+       wl_signal_add(&wxs->compositor->kill_signal,
+                     &wm->kill_listener);
 
        weston_wm_create_cursors(wm);
        weston_wm_window_set_cursor(wm, wm->screen->root, XWM_CURSOR_LEFT_PTR);
@@ -1488,6 +1518,7 @@ weston_wm_destroy(struct weston_wm *wm)
        wl_event_source_remove(wm->source);
        wl_list_remove(&wm->selection_listener.link);
        wl_list_remove(&wm->activate_listener.link);
+       wl_list_remove(&wm->kill_listener.link);
 
        free(wm);
 }
index bd127b7..a1ffa2a 100644 (file)
@@ -63,6 +63,7 @@ struct weston_wm {
        int last_cursor;
        xcb_render_pictforminfo_t format_rgb, format_rgba;
        struct wl_listener activate_listener;
+       struct wl_listener kill_listener;
 
        xcb_window_t selection_window;
        xcb_window_t selection_owner;
@@ -85,7 +86,9 @@ struct weston_wm {
                xcb_atom_t               wm_delete_window;
                xcb_atom_t               wm_state;
                xcb_atom_t               wm_s0;
+               xcb_atom_t               wm_client_machine;
                xcb_atom_t               net_wm_name;
+               xcb_atom_t               net_wm_pid;
                xcb_atom_t               net_wm_icon;
                xcb_atom_t               net_wm_state;
                xcb_atom_t               net_wm_state_fullscreen;