diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 65eb11a0..f5571a53 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -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; @@ -477,6 +483,25 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve window->y = configure_notify->y - y; } +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) { @@ -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); } diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h index bd127b73..a1ffa2a0 100644 --- a/src/xwayland/xwayland.h +++ b/src/xwayland/xwayland.h @@ -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;