[RFC weston] compositor: Use ordered layers

Quentin Glidic sardemff7+wayland at sardemff7.net
Tue May 21 09:26:53 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>
---

This change is incomplete but the desktop shell works fine with it.

The idea is to allow other modules to use layers without breaking the shell.
Using relative layers like the old patch did is not flexible enough, since 
modules could want to put layers *between* the shell’s ones.

Comments?

 src/compositor.c    | 39 +++++++++++++++++++++++++++++++-------
 src/compositor.h    | 18 ++++++++++++++++--
 src/shell.c         | 54 ++++++++++++++++++++++++++---------------------------
 src/tablet-shell.c  | 13 +++++++++----
 tests/weston-test.c |  3 ++-
 5 files changed, 85 insertions(+), 42 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 9fefb77..46bd370 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1318,11 +1318,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
@@ -2779,8 +2801,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);
 
@@ -2878,7 +2903,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));
 
@@ -3151,7 +3176,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 318fc0d..afdd9d8 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>
@@ -183,7 +184,7 @@ struct weston_output {
 	char *make, *model, *serial_number;
 	uint32_t subpixel;
 	uint32_t transform;
-	
+
 	struct weston_mode *current;
 	struct weston_mode *origin;
 	struct wl_list mode_list;
@@ -456,8 +457,10 @@ enum {
 };
 
 struct weston_layer {
+	struct weston_compositor *compositor;
 	struct wl_list surface_list;
 	struct wl_list link;
+	int32_t order;
 };
 
 struct weston_plane {
@@ -835,8 +838,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 f5d5bff..c2ac8e6 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -573,7 +573,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);
@@ -609,7 +609,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;
 }
@@ -2505,19 +2505,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));
 
@@ -2977,13 +2971,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);
 
@@ -3113,8 +3107,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) {
@@ -4328,11 +4322,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 cae8acf..552a03c 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -567,12 +567,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 b629c86..29e9b21 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -236,7 +236,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_display_add_global(ec->wl_display, &wl_test_interface,
 				  test, bind_test) == NULL)
-- 
1.8.2.3



More information about the wayland-devel mailing list