[RFC] Add support sub transient window moving followed with main window

yan.wang at linux.intel.com yan.wang at linux.intel.com
Thu Mar 22 00:44:44 PDT 2012


From: yanwang <yan.wang at linux.intel.com>

For supportng sub transient window moving followed with main window:
1. In shell_surface_set_transient() record parent/child relationship
of weston_surface into wl_list.
2. Reset position transient windows recursively in move_grab_motion()
callback function.
3. Restack layer of transient windows to keep them above main window
in weston_surface_restack().
---
 src/compositor.c |   20 ++++++++++++++++++++
 src/compositor.h |    4 ++++
 src/shell.c      |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index c8ac59c..142ef0f 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -211,6 +211,7 @@ weston_surface_create(struct weston_compositor *compositor)
 	wl_list_init(&surface->surface.resource.destroy_listener_list);
 
 	wl_list_init(&surface->link);
+	wl_list_init(&surface->child_list);
 	wl_list_init(&surface->layer_link);
 	wl_list_init(&surface->buffer_link);
 
@@ -820,13 +821,32 @@ out:
 	pixman_region32_fini(&repaint);
 }
 
+/* Restack transient window and tranverse all sub transient windows. */
+static void
+weston_surface_restack_transient(struct weston_surface *surface, struct wl_list *below)
+{
+	struct weston_surface *child;
+	weston_surface_restack(surface, below);
+
+	wl_list_for_each(child, &surface->child_list, child_link) {
+		weston_surface_restack_transient(child, below);
+	}
+}
+
 WL_EXPORT void
 weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
 {
+	struct weston_surface *child;
+
 	wl_list_remove(&surface->layer_link);
 	wl_list_insert(below, &surface->layer_link);
 	weston_surface_damage_below(surface);
 	weston_surface_damage(surface);
+	
+	/* Tranverse all sub transient windows. */
+	wl_list_for_each(child, &surface->child_list, child_link) {
+		weston_surface_restack_transient(child, below);
+	}
 }
 
 WL_EXPORT void
diff --git a/src/compositor.h b/src/compositor.h
index ae680ed..fc22c0e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -289,6 +289,10 @@ struct weston_surface {
 	GLfloat color[4];
 	uint32_t alpha;
 
+	/* They are used for keep transint (sub) windows. */
+	struct wl_list child_link;
+	struct wl_list child_list;
+
 	/* Surface geometry state, mutable.
 	 * If you change anything, set dirty = 1.
 	 * That includes the transformations referenced from the list.
diff --git a/src/shell.c b/src/shell.c
index fa51922..db76f7d 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -179,6 +179,24 @@ noop_grab_focus(struct wl_pointer_grab *grab, uint32_t time,
 	grab->focus = NULL;
 }
 
+/* Set transient new position and tranverse all sub transient windows. */
+static void
+move_grab_motion_transient(struct weston_surface *es, 
+		uint32_t time, int32_t x, int32_t y)
+{
+	struct weston_surface *child;
+	int32_t old_x = es->geometry.x;
+	int32_t old_y = es->geometry.y;
+
+	weston_surface_set_position(es, x, y);
+
+	wl_list_for_each(child, &es->child_list, child_link) {
+		move_grab_motion_transient(child, time,
+				child->geometry.x - old_x + x,
+				child->geometry.y - old_y + y);
+	}	
+}
+
 static void
 move_grab_motion(struct wl_pointer_grab *grab,
 		 uint32_t time, int32_t x, int32_t y)
@@ -186,11 +204,22 @@ move_grab_motion(struct wl_pointer_grab *grab,
 	struct weston_move_grab *move = (struct weston_move_grab *) grab;
 	struct wl_input_device *device = grab->input_device;
 	struct weston_surface *es = move->surface;
+	struct weston_surface *child;
+	/* Record old position for calculate offset of transient window position. */
+	int32_t old_x = es->geometry.x;
+	int32_t old_y = es->geometry.y;
 
 	weston_surface_configure(es,
 				 device->x + move->dx,
 				 device->y + move->dy,
 				 es->geometry.width, es->geometry.height);
+
+	/* Tranverse all sub transient windows. */
+	wl_list_for_each(child, &es->child_list, child_link) {
+		move_grab_motion_transient(child, time, 
+			child->geometry.x - old_x + device->x + move->dx,
+			child->geometry.y - old_y + device->y + move->dy);
+	}
 }
 
 static void
@@ -452,6 +481,15 @@ shell_surface_set_transient(struct wl_client *client,
 					pes->geometry.y + y);
 
 	shsurf->type = SHELL_SURFACE_TRANSIENT;
+	/* Record parent-child transient relationship. */
+	if(shsurf->parent != parent_resource->data)
+	{
+		if(shsurf->parent)
+			wl_list_remove(&es->child_link);
+
+		shsurf->parent = parent_resource->data;
+		wl_list_insert(pes->child_list.prev, &es->child_link);
+	}
 }
 
 static struct wl_shell *
-- 
1.7.7.6



More information about the wayland-devel mailing list