[RFC weston] compositor: Use ordered layers

Kristian Høgsberg hoegsberg at gmail.com
Wed May 22 13:05:50 PDT 2013


On Tue, May 21, 2013 at 06:26:53PM +0200, Quentin Glidic wrote:
> 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?

I think it's better to change shell.c to not pull out and add back all
layers when the screensaver triggers.  I thought it was a cool idea at
the time since if the other surfaces aren't even in the scenegraph,
there's no way they can steal focus from the screen lock dialog.

At this point, I think it's cleaner to just add a lock-screen layer
that we can put the unlock dialog into and perhaps a lock screen
background surface.

Kristian

>  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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list