summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-06-01 00:08:12 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-06-01 00:08:12 -0400
commit805667388b2f0d0210869daa512598819c7fb1bf (patch)
tree1384470a5eac4450f640ea9180068d475f8b7b1e
parenta4b3d0ede7fc294597164c9b35a46cd31be5640d (diff)
xwayland: Handle selection source going away without crashing
-rw-r--r--src/xwayland/selection.c29
-rw-r--r--src/xwayland/window-manager.c1
-rw-r--r--src/xwayland/xwayland.h1
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;