[PATCH 3/6] desktop-shell: Allow multiple active fullscreen windows on multi-display setup.

Derek Foreman derekf at osg.samsung.com
Thu Apr 16 09:55:09 PDT 2015


On 02/04/15 12:10 AM, Mario Kleiner wrote:
> Desktop shell demoted all fullscreen shell surfaces on all active
> outputs of a multi-display setup whenever any shell surface was
> activated anywhere. This made it impossible to have multiple
> fullscreen windows on separate outputs active at the same
> time, as creating or activating any shell surface would disable
> fullscreen status for all existing fullscreen surfaces.
> 
> Make lower_fullscreen_layer() more selective, so on request it
> only demotes fullscreen surfaces on a specified weston_output.
> 
> The activate() method for a specific surface will now only request
> demotion of fullscreen surfaces on the target output of the activated
> surface, but leave fullscreen surfaces on unrelated outputs alone.
> 
> Desktop wide acting functions like the window switcher or exposay
> will still demote all fullscreen surfaces on all outputs to
> implement their effect as before.
> 
> Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
> ---

Looks sensible to me

Reviewed-By: Derek Foreman <derekf at osg.samsung.com>

>  desktop-shell/exposay.c |  2 +-
>  desktop-shell/shell.c   | 47 +++++++++++++++++++++++++++++++++++------------
>  desktop-shell/shell.h   |  3 ++-
>  3 files changed, 38 insertions(+), 14 deletions(-)
> 
> diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c
> index 4b65cbd..a15fc7a 100644
> --- a/desktop-shell/exposay.c
> +++ b/desktop-shell/exposay.c
> @@ -563,7 +563,7 @@ exposay_transition_active(struct desktop_shell *shell)
>  	shell->exposay.clicked = NULL;
>  	wl_list_init(&shell->exposay.surface_list);
>  
> -	lower_fullscreen_layer(shell);
> +	lower_fullscreen_layer(shell, NULL);
>  	shell->exposay.grab_kbd.interface = &exposay_kbd_grab;
>  	weston_keyboard_start_grab(seat->keyboard,
>  	                           &shell->exposay.grab_kbd);
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index f7c928e..7d0e403 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -303,17 +303,29 @@ static bool
>  shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
>  {
>  	struct desktop_shell *shell;
> -	struct weston_view *top_fs_ev;
> +	struct weston_view *view;
> +	struct shell_surface *top_fs_shsurf = NULL;
>  
>  	shell = shell_surface_get_shell(shsurf);
>  
>  	if (wl_list_empty(&shell->fullscreen_layer.view_list.link))
>  		return false;
>  
> -	top_fs_ev = container_of(shell->fullscreen_layer.view_list.link.next,
> -			         struct weston_view,
> -				 layer_link.link);
> -	return (shsurf == get_shell_surface(top_fs_ev->surface));
> +	/* Find topmost shsurf on the same fullscreen output on which shsurf
> +	 * is displaying. We don't care about other outputs.
> +	 */
> +	wl_list_for_each(view, &shell->fullscreen_layer.view_list.link,
> +					 layer_link.link) {
> +		struct shell_surface *cand_shsurf = get_shell_surface(view->surface);
> +
> +		if (cand_shsurf &&
> +			(cand_shsurf->fullscreen_output == shsurf->fullscreen_output)) {
> +			top_fs_shsurf = cand_shsurf;
> +			break;
> +		}
> +	}
> +
> +	return (shsurf == top_fs_shsurf);
>  }
>  
>  static void
> @@ -5000,10 +5012,14 @@ rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
>   * and this is reversed when such a surface is re-configured, see
>   * shell_configure_fullscreen() and shell_ensure_fullscreen_black_view().
>   *
> + * lowering_output = NULL - Lower on all outputs, else only lower on the
> + *                   specified output.
> + *
>   * This should be used when implementing shell-wide overlays, such as
>   * the alt-tab switcher, which need to de-promote fullscreen layers. */
>  void
> -lower_fullscreen_layer(struct desktop_shell *shell)
> +lower_fullscreen_layer(struct desktop_shell *shell,
> +					   struct weston_output *lowering_output)
>  {
>  	struct workspace *ws;
>  	struct weston_view *view, *prev;
> @@ -5017,6 +5033,12 @@ lower_fullscreen_layer(struct desktop_shell *shell)
>  		if (!shsurf)
>  			continue;
>  
> +		/* Only lower surfaces which have lowering_output as their fullscreen
> +		 * output, unless a NULL output asks for lowering on all outputs.
> +		 */
> +		if (lowering_output && (shsurf->fullscreen_output != lowering_output))
> +			continue;
> +
>  		/* We can have a non-fullscreen popup for a fullscreen surface
>  		 * in the fullscreen layer. */
>  		if (shsurf->state.fullscreen) {
> @@ -5047,9 +5069,13 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
>  	struct weston_surface *old_es;
>  	struct shell_surface *shsurf;
>  
> -	lower_fullscreen_layer(shell);
> -
>  	main_surface = weston_surface_get_main_surface(es);
> +	shsurf = get_shell_surface(main_surface);
> +	assert(shsurf);
> +
> +	/* Only demote fullscreen surfaces on the output of activated shsurf.
> +	 * Leave fullscreen surfaces on unrelated outputs alone. */
> +	lower_fullscreen_layer(shell, shsurf->output);
>  
>  	weston_surface_activate(es, seat);
>  
> @@ -5060,9 +5086,6 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
>  	old_es = state->keyboard_focus;
>  	focus_state_set_focus(state, es);
>  
> -	shsurf = get_shell_surface(main_surface);
> -	assert(shsurf);
> -
>  	if (shsurf->state.fullscreen && configure)
>  		shell_configure_fullscreen(shsurf);
>  	else
> @@ -6119,7 +6142,7 @@ switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  	wl_array_init(&switcher->minimized_array);
>  
>  	restore_all_output_modes(shell->compositor);
> -	lower_fullscreen_layer(switcher->shell);
> +	lower_fullscreen_layer(switcher->shell, NULL);
>  	switcher->grab.interface = &switcher_grab;
>  	weston_keyboard_start_grab(seat->keyboard, &switcher->grab);
>  	weston_keyboard_set_focus(seat->keyboard, NULL);
> diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
> index 2cfd1d6..0f8e16d 100644
> --- a/desktop-shell/shell.h
> +++ b/desktop-shell/shell.h
> @@ -227,7 +227,8 @@ struct workspace *
>  get_current_workspace(struct desktop_shell *shell);
>  
>  void
> -lower_fullscreen_layer(struct desktop_shell *shell);
> +lower_fullscreen_layer(struct desktop_shell *shell,
> +					   struct weston_output *lowering_output);
>  
>  void
>  activate(struct desktop_shell *shell, struct weston_surface *es,
> 



More information about the wayland-devel mailing list