diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-06-01 00:08:12 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-06-01 00:08:12 -0400 |
commit | 805667388b2f0d0210869daa512598819c7fb1bf (patch) | |
tree | 1384470a5eac4450f640ea9180068d475f8b7b1e | |
parent | a4b3d0ede7fc294597164c9b35a46cd31be5640d (diff) |
xwayland: Handle selection source going away without crashing
-rw-r--r-- | src/xwayland/selection.c | 29 | ||||
-rw-r--r-- | src/xwayland/window-manager.c | 1 | ||||
-rw-r--r-- | src/xwayland/xwayland.h | 1 |
3 files changed, 28 insertions, 3 deletions
diff --git a/src/xwayland/selection.c b/src/xwayland/selection.c index d0105dd..442b373 100644 --- a/src/xwayland/selection.c +++ b/src/xwayland/selection.c @@ -547,10 +547,28 @@ weston_wm_handle_xfixes_selection_notify(struct weston_wm *wm, { xcb_xfixes_selection_notify_event_t *xfixes_selection_notify = (xcb_xfixes_selection_notify_event_t *) event; + struct weston_compositor *compositor; + uint32_t serial; printf("xfixes selection notify event: owner %d\n", xfixes_selection_notify->owner); + if (xfixes_selection_notify->owner == XCB_WINDOW_NONE) { + if (wm->selection_owner != wm->selection_window) { + /* A real X client selection went away, not our + * proxy selection. Clear the wayland selection. */ + compositor = wm->server->compositor; + serial = wl_display_next_serial(compositor->wl_display); + wl_seat_set_selection(&compositor->seat->seat, NULL, serial); + } + + wm->selection_owner = XCB_WINDOW_NONE; + + return; + } + + wm->selection_owner = xfixes_selection_notify->owner; + /* We have to use XCB_TIME_CURRENT_TIME when we claim the * selection, so grab the actual timestamp here so we can * answer TIMESTAMP conversion requests correctly. */ @@ -604,10 +622,17 @@ weston_wm_set_selection(struct wl_listener *listener, void *data) const char **p, **end; int has_text_plain = 0; - if (source->offer_interface == &data_offer_interface) + if (source == NULL) { + if (wm->selection_owner == wm->selection_window) + xcb_set_selection_owner(wm->conn, + XCB_ATOM_NONE, + wm->atom.clipboard, + wm->selection_timestamp); return; + } - fprintf(stderr, "set selection\n"); + if (source->offer_interface == &data_offer_interface) + return; p = source->mime_types.data; end = (const char **) diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index b8be54c..92601e5 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -906,7 +906,6 @@ weston_wm_handle_event(int fd, uint32_t mask, void *data) while (event = xcb_poll_for_event(wm->conn), event != NULL) { if (weston_wm_handle_selection_event(wm, event)) { - fprintf(stderr, "handled by selection code\n"); free(event); count++; continue; diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h index 1b1cdff..5922dda 100644 --- a/src/xwayland/xwayland.h +++ b/src/xwayland/xwayland.h @@ -62,6 +62,7 @@ struct weston_wm { struct wl_listener activate_listener; xcb_window_t selection_window; + xcb_window_t selection_owner; int incr; int data_source_fd; struct wl_event_source *property_source; |