xwm: Handle reparenting windows
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 8d4c976..de17c4e 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -655,12 +655,44 @@
 }
 
 static void
+weston_wm_window_create(struct weston_wm *wm,
+			xcb_window_t id, int width, int height)
+{
+	struct weston_wm_window *window;
+	uint32_t values[1];
+
+	window = malloc(sizeof *window);
+	if (window == NULL) {
+		fprintf(stderr, "failed to allocate window\n");
+		return;
+	}
+
+	values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
+	xcb_change_window_attributes(wm->conn, id, XCB_CW_EVENT_MASK, values);
+
+	memset(window, 0, sizeof *window);
+	window->wm = wm;
+	window->id = id;
+	window->properties_dirty = 1;
+
+	window->width = width;
+	window->height = height;
+
+	hash_table_insert(wm->window_hash, id, window);
+}
+
+static void
+weston_wm_window_destroy(struct weston_wm_window *window)
+{
+	hash_table_remove(window->wm->window_hash, window->id);
+	free(window);
+}
+
+static void
 weston_wm_handle_create_notify(struct weston_wm *wm, xcb_generic_event_t *event)
 {
 	xcb_create_notify_event_t *create_notify =
 		(xcb_create_notify_event_t *) event;
-	struct weston_wm_window *window;
-	uint32_t values[1];
 
 	fprintf(stderr,
 		"XCB_CREATE_NOTIFY (window %d, width %d, height %d%s%s)\n",
@@ -672,25 +704,8 @@
 	if (our_resource(wm, create_notify->window))
 		return;
 
-	window = malloc(sizeof *window);
-	if (window == NULL) {
-		fprintf(stderr, "failed to allocate window\n");
-		return;
-	}
-
-	values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
-	xcb_change_window_attributes(wm->conn, create_notify->window,
-				     XCB_CW_EVENT_MASK, values);
-
-	memset(window, 0, sizeof *window);
-	window->wm = wm;
-	window->id = create_notify->window;
-	window->properties_dirty = 1;
-
-	window->width = create_notify->width;
-	window->height = create_notify->height;
-
-	hash_table_insert(wm->window_hash, window->id, window);
+	weston_wm_window_create(wm, create_notify->window,
+				create_notify->width, create_notify->height);
 }
 
 static void
@@ -709,10 +724,29 @@
 		return;
 
 	window = hash_table_lookup(wm->window_hash, destroy_notify->window);
+	weston_wm_window_destroy(window);
+}
 
-	hash_table_remove(wm->window_hash, window->id);
+static void
+weston_wm_handle_reparent_notify(struct weston_wm *wm, xcb_generic_event_t *event)
+{
+	xcb_reparent_notify_event_t *reparent_notify =
+		(xcb_reparent_notify_event_t *) event;
+	struct weston_wm_window *window;
 
-	free(window);
+	fprintf(stderr,
+		"XCB_REPARENT_NOTIFY (window %d, parent %d, event %d)\n",
+		reparent_notify->window,
+		reparent_notify->parent,
+		reparent_notify->event);
+
+	if (reparent_notify->parent == wm->screen->root) {
+		weston_wm_window_create(wm, reparent_notify->window, 10, 10);
+	} else if (!our_resource(wm, reparent_notify->parent)) {
+		window = hash_table_lookup(wm->window_hash,
+					   reparent_notify->window);
+		weston_wm_window_destroy(window);
+	}
 }
 
 static void
@@ -862,6 +896,9 @@
 		case XCB_UNMAP_NOTIFY:
 			weston_wm_handle_unmap_notify(wm, event);
 			break;
+		case XCB_REPARENT_NOTIFY:
+			weston_wm_handle_reparent_notify(wm, event);
+			break;
 		case XCB_CONFIGURE_REQUEST:
 			weston_wm_handle_configure_request(wm, event);
 			break;