[PATCH weston] compositor: Use ordered layers

Quentin Glidic sardemff7+wayland at sardemff7.net
Wed Jul 10 09:10:49 PDT 2013


From: Quentin Glidic <sardemff7+git at sardemff7.net>

It allows a more generic layer management that several modules can use
at the same time without breaking each others’ layers.

Signed-off-by: Quentin Glidic <sardemff7+git at sardemff7.net>
---
 src/compositor.c    | 39 +++++++++++++++++++++++++++++++-------
 src/compositor.h    | 16 +++++++++++++++-
 src/shell.c         | 54 ++++++++++++++++++++++++++---------------------------
 src/tablet-shell.c  | 13 +++++++++----
 tests/weston-test.c |  3 ++-
 5 files changed, 84 insertions(+), 41 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index e9e1166..1267a50 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1384,11 +1384,33 @@ idle_repaint(void *data)
 }
 
 WL_EXPORT void
-weston_layer_init(struct weston_layer *layer, struct wl_list *below)
+weston_layer_init(struct weston_layer *layer, int32_t order)
 {
 	wl_list_init(&layer->surface_list);
-	if (below != NULL)
-		wl_list_insert(below, &layer->link);
+	layer->order = order;
+}
+
+WL_EXPORT void
+weston_layer_order(struct weston_layer *layer, struct weston_compositor *compositor, bool use_layer)
+{
+	if (!use_layer) {
+		wl_list_remove(&layer->link);
+		return;
+	}
+
+	if (wl_list_empty(&compositor->layer_list)) {
+		wl_list_insert(&compositor->layer_list, &layer->link);
+		return;
+	}
+
+	struct weston_layer *l;
+	wl_list_for_each_reverse(l, &compositor->layer_list, link) {
+		if (layer->order >= l->order) {
+			wl_list_insert(&l->link, &layer->link);
+			return;
+		}
+	}
+	wl_list_insert(&compositor->layer_list, &layer->link);
 }
 
 WL_EXPORT void
@@ -2878,8 +2900,11 @@ weston_compositor_init(struct weston_compositor *ec,
 
 	ec->input_loop = wl_event_loop_create();
 
-	weston_layer_init(&ec->fade_layer, &ec->layer_list);
-	weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
+	weston_layer_init(&ec->fade_layer, WESTON_LAYER_ORDER_BASE);
+	weston_layer_init(&ec->cursor_layer, WESTON_LAYER_ORDER_BASE);
+
+	weston_layer_order(&ec->fade_layer, ec, true);
+	weston_layer_order(&ec->cursor_layer, ec, true);
 
 	weston_compositor_schedule_repaint(ec);
 
@@ -3000,7 +3025,7 @@ print_backtrace(void)
 			filename = dlinfo.dli_fname;
 		else
 			filename = "?";
-		
+
 		weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
 			   ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
 
@@ -3289,7 +3314,7 @@ int main(int argc, char *argv[])
 	}
 
 	weston_log_file_open(log);
-	
+
 	weston_log("%s\n"
 		   STAMP_SPACE "%s\n"
 		   STAMP_SPACE "Bug reports to: %s\n"
diff --git a/src/compositor.h b/src/compositor.h
index 84f39e2..3562323 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -28,6 +28,7 @@
 extern "C" {
 #endif
 
+#include <stdbool.h>
 #include <pixman.h>
 #include <xkbcommon/xkbcommon.h>
 #include <wayland-server.h>
@@ -481,8 +482,10 @@ enum {
 };
 
 struct weston_layer {
+	struct weston_compositor *compositor;
 	struct wl_list surface_list;
 	struct wl_list link;
+	int32_t order;
 };
 
 struct weston_plane {
@@ -899,8 +902,19 @@ void
 notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
 	     wl_fixed_t x, wl_fixed_t y, int touch_type);
 
+enum weston_layer_order {
+	WESTON_LAYER_ORDER_BASE = 0,
+	WESTON_LAYER_ORDER_LOCK = INT8_MAX >> 4,
+	WESTON_LAYER_ORDER_FULLSCREEN = INT8_MAX,
+	WESTON_LAYER_ORDER_UI = INT16_MAX,
+	WESTON_LAYER_ORDER_NORMAL = INT32_MAX >> 8, /* INT24 */
+	WESTON_LAYER_ORDER_BACKGROUND = INT32_MAX
+};
+
+void
+weston_layer_init(struct weston_layer *layer, int32_t order);
 void
-weston_layer_init(struct weston_layer *layer, struct wl_list *below);
+weston_layer_order(struct weston_layer *layer, struct weston_compositor *compositor, bool use_layer);
 
 void
 weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y);
diff --git a/src/shell.c b/src/shell.c
index 69345b0..391c2e5 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -578,7 +578,7 @@ workspace_create(void)
 	if (ws == NULL)
 		return NULL;
 
-	weston_layer_init(&ws->layer, NULL);
+	weston_layer_init(&ws->layer, WESTON_LAYER_ORDER_NORMAL);
 
 	wl_list_init(&ws->focus_list);
 	wl_list_init(&ws->seat_destroyed_listener.link);
@@ -614,7 +614,7 @@ activate_workspace(struct desktop_shell *shell, unsigned int index)
 	struct workspace *ws;
 
 	ws = get_workspace(shell, index);
-	wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
+	weston_layer_order(&ws->layer, shell->compositor, true);
 
 	shell->workspaces.current = index;
 }
@@ -2560,19 +2560,13 @@ resume_desktop(struct desktop_shell *shell)
 
 	terminate_screensaver(shell);
 
-	wl_list_remove(&shell->lock_layer.link);
-	wl_list_insert(&shell->compositor->cursor_layer.link,
-		       &shell->fullscreen_layer.link);
-	wl_list_insert(&shell->fullscreen_layer.link,
-		       &shell->panel_layer.link);
-	if (shell->showing_input_panels) {
-		wl_list_insert(&shell->panel_layer.link,
-			       &shell->input_panel_layer.link);
-		wl_list_insert(&shell->input_panel_layer.link,
-			       &ws->layer.link);
-	} else {
-		wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
-	}
+	weston_layer_order(&shell->lock_layer, shell->compositor, false);
+
+	weston_layer_order(&shell->fullscreen_layer, shell->compositor, true);
+	weston_layer_order(&shell->panel_layer, shell->compositor, true);
+	if (shell->showing_input_panels)
+		weston_layer_order(&shell->input_panel_layer, shell->compositor, true);
+	weston_layer_order(&ws->layer, shell->compositor, true);
 
 	restore_focus_state(shell, get_current_workspace(shell));
 
@@ -3042,13 +3036,13 @@ lock(struct desktop_shell *shell)
 	 * toplevel layers.  This way nothing else can show or receive
 	 * input events while we are locked. */
 
-	wl_list_remove(&shell->panel_layer.link);
-	wl_list_remove(&shell->fullscreen_layer.link);
+	weston_layer_order(&shell->fullscreen_layer, shell->compositor, false);
+	weston_layer_order(&shell->panel_layer, shell->compositor, false);
 	if (shell->showing_input_panels)
-		wl_list_remove(&shell->input_panel_layer.link);
-	wl_list_remove(&ws->layer.link);
-	wl_list_insert(&shell->compositor->cursor_layer.link,
-		       &shell->lock_layer.link);
+		weston_layer_order(&shell->input_panel_layer, shell->compositor, false);
+	weston_layer_order(&ws->layer, shell->compositor, false);
+
+	weston_layer_order(&shell->lock_layer, shell->compositor, true);
 
 	launch_screensaver(shell);
 
@@ -3249,8 +3243,8 @@ show_input_panels(struct wl_listener *listener, void *data)
 	shell->showing_input_panels = true;
 
 	if (!shell->locked)
-		wl_list_insert(&shell->panel_layer.link,
-			       &shell->input_panel_layer.link);
+		weston_layer_order(&shell->input_panel_layer,
+				   shell->compositor, true);
 
 	wl_list_for_each_safe(surface, next,
 			      &shell->input_panel.surfaces, link) {
@@ -4481,11 +4475,15 @@ module_init(struct weston_compositor *ec,
 
 	wl_list_init(&shell->input_panel.surfaces);
 
-	weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
-	weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
-	weston_layer_init(&shell->background_layer, &shell->panel_layer.link);
-	weston_layer_init(&shell->lock_layer, NULL);
-	weston_layer_init(&shell->input_panel_layer, NULL);
+	weston_layer_init(&shell->lock_layer, WESTON_LAYER_ORDER_LOCK);
+	weston_layer_init(&shell->fullscreen_layer, WESTON_LAYER_ORDER_FULLSCREEN);
+	weston_layer_init(&shell->panel_layer, WESTON_LAYER_ORDER_UI);
+	weston_layer_init(&shell->background_layer, WESTON_LAYER_ORDER_BACKGROUND);
+	weston_layer_init(&shell->input_panel_layer, WESTON_LAYER_ORDER_UI);
+
+	weston_layer_order(&shell->fullscreen_layer, ec, true);
+	weston_layer_order(&shell->panel_layer, ec, true);
+	weston_layer_order(&shell->background_layer, ec, true);
 
 	wl_array_init(&shell->workspaces.array);
 	wl_list_init(&shell->workspaces.client_list);
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index ca63b97..1acc01b 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -562,12 +562,17 @@ module_init(struct weston_compositor *compositor,
 	weston_compositor_add_key_binding(compositor, KEY_COMPOSE, 0,
 					  menu_key_binding, shell);
 
+	weston_layer_init(&shell->lockscreen_layer,
+			  WESTON_LAYER_ORDER_LOCK);
 	weston_layer_init(&shell->homescreen_layer,
-			  &compositor->cursor_layer.link);
+			  WESTON_LAYER_ORDER_BASE);
 	weston_layer_init(&shell->application_layer,
-			  &compositor->cursor_layer.link);
-	weston_layer_init(&shell->lockscreen_layer,
-			  &compositor->cursor_layer.link);
+			  WESTON_LAYER_ORDER_BASE);
+
+	weston_layer_order(&shell->lockscreen_layer, compositor, true);
+	weston_layer_order(&shell->homescreen_layer, compositor, true);
+	weston_layer_order(&shell->application_layer, compositor, true);
+
 	launch_ux_daemon(shell);
 
 	tablet_shell_set_state(shell, STATE_STARTING);
diff --git a/tests/weston-test.c b/tests/weston-test.c
index b625f42..e05cd00 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -238,7 +238,8 @@ module_init(struct weston_compositor *ec,
 
 	memset(test, 0, sizeof *test);
 	test->compositor = ec;
-	weston_layer_init(&test->layer, &ec->cursor_layer.link);
+	weston_layer_init(&test->layer, WESTON_LAYER_ORDER_NORMAL);
+	weston_layer_order(&test->layer, ec, true);
 
 	if (wl_global_create(ec->wl_display, &wl_test_interface, 1,
 			     test, bind_test) == NULL)
-- 
1.8.3.2



More information about the wayland-devel mailing list