[PATCH weston v2 09/24] xwm: detect legacy fullscreen on MapRequest

Quentin Glidic sardemff7+wayland at sardemff7.net
Sun Jan 15 13:44:05 UTC 2017


On 21/12/2016 15:40, Pekka Paalanen wrote:
> From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
> 
> The legacy fullscreen state needs to be detected at MapRequest time,
> because that is when the X11 client has alredy set up the initial window
> state.
> 
> Doing it at xserver_map_shell_surface() meant that it would be done as a
> response to Xwayland creating the wl_surface and XWM receiving the
> WL_SURFACE_ID ClientMessage, whichever came later. At that point the X11
> client might still be setting things up in theory, though in practice
> most of the X11 communication has already happened when
> xserver_map_shell_surface() gets called.
> 
> The real reason for this is to clean up xserver_map_shell_surface() from
> everything that would affect drawing the decorations. This patch is one
> part of that clean-up.
> 
> The weston_output_weak_ref logic is not put into compositor.h, because
> there are no other users for it at this time. We need to protect against
> the output going away.

Just to be clear: “protect” here means “not segfault”, just passing NULL 
if the output got away in the meantime, right?


> 
> A side-effect of this patch is that saved_width and saved_height will
> now get overwritten also for legacy fullscreen windows. Previously, they
> were left to zero as far as I could tell.
> 
> NOTE: This stops override-redirect legacy fullscreen windows from being
> detected as fullscreen. MapRequest processing does not happen for OR
> windows. These windows get detected as type XWAYLAND instead.
> 
> Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

Nice way to do it:
Reviewed-by: Quentin Glidic <sardemff7+git at sardemff7.net>


> ---
>   xwayland/window-manager.c | 70 +++++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 65 insertions(+), 5 deletions(-)
> 
> diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
> index 10bb390..02a44a7 100644
> --- a/xwayland/window-manager.c
> +++ b/xwayland/window-manager.c
> @@ -36,6 +36,7 @@
>   #include <unistd.h>
>   #include <signal.h>
>   #include <limits.h>
> +#include <assert.h>
>   #include <X11/Xcursor/Xcursor.h>
>   #include <linux/input.h>
>   
> @@ -126,6 +127,11 @@ struct motif_wm_hints {
>   #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10   /* move via keyboard */
>   #define _NET_WM_MOVERESIZE_CANCEL           11   /* cancel operation */
>   
> +struct weston_output_weak_ref {
> +	struct weston_output *output;
> +	struct wl_listener destroy_listener;
> +};
> +
>   struct weston_wm_window {
>   	struct weston_wm *wm;
>   	xcb_window_t id;
> @@ -152,6 +158,7 @@ struct weston_wm_window {
>   	bool pos_dirty;
>   	int map_request_x;
>   	int map_request_y;
> +	struct weston_output_weak_ref legacy_fullscreen_output;
>   	int saved_width, saved_height;
>   	int decorate;
>   	int override_redirect;
> @@ -174,6 +181,11 @@ weston_wm_set_net_active_window(struct weston_wm *wm, xcb_window_t window);
>   static void
>   weston_wm_window_schedule_repaint(struct weston_wm_window *window);
>   
> +static int
> +legacy_fullscreen(struct weston_wm *wm,
> +		  struct weston_wm_window *window,
> +		  struct weston_output **output_ret);
> +
>   static void
>   xserver_map_shell_surface(struct weston_wm_window *window,
>   			  struct weston_surface *surface);
> @@ -212,6 +224,47 @@ wm_log_continue(const char *fmt, ...)
>   #endif
>   }
>   
> +static void
> +weston_output_weak_ref_init(struct weston_output_weak_ref *ref)
> +{
> +	ref->output = NULL;
> +}
> +
> +static void
> +weston_output_weak_ref_clear(struct weston_output_weak_ref *ref)
> +{
> +	if (!ref->output)
> +		return;
> +
> +	wl_list_remove(&ref->destroy_listener.link);
> +	ref->output = NULL;
> +}
> +
> +static void
> +weston_output_weak_ref_handle_destroy(struct wl_listener *listener, void *data)
> +{
> +	struct weston_output_weak_ref *ref;
> +
> +	ref = wl_container_of(listener, ref, destroy_listener);
> +	assert(ref->output == data);
> +
> +	weston_output_weak_ref_clear(ref);
> +}
> +
> +static void
> +weston_output_weak_ref_set(struct weston_output_weak_ref *ref,
> +			   struct weston_output *output)
> +{
> +	weston_output_weak_ref_clear(ref);
> +
> +	if (!output)
> +		return;
> +
> +	ref->destroy_listener.notify = weston_output_weak_ref_handle_destroy;
> +	wl_signal_add(&output->destroy_signal, &ref->destroy_listener);
> +	ref->output = output;
> +}
> +
>   static bool __attribute__ ((warn_unused_result))
>   wm_lookup_window(struct weston_wm *wm, xcb_window_t hash,
>   		 struct weston_wm_window **window)
> @@ -955,6 +1008,7 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
>   	xcb_map_request_event_t *map_request =
>   		(xcb_map_request_event_t *) event;
>   	struct weston_wm_window *window;
> +	struct weston_output *output;
>   
>   	if (our_resource(wm, map_request->window)) {
>   		wm_log("XCB_MAP_REQUEST (window %d, ours)\n",
> @@ -982,6 +1036,12 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
>   	weston_wm_window_set_net_wm_state(window);
>   	weston_wm_window_set_virtual_desktop(window, 0);
>   
> +	if (legacy_fullscreen(wm, window, &output)) {
> +		window->fullscreen = 1;
> +		weston_output_weak_ref_set(&window->legacy_fullscreen_output,
> +					   output);
> +	}
> +
>   	xcb_map_window(wm->conn, map_request->window);
>   	xcb_map_window(wm->conn, window->frame_id);
>   }
> @@ -1216,6 +1276,7 @@ weston_wm_window_create(struct weston_wm *wm,
>   	window->pos_dirty = false;
>   	window->map_request_x = INT_MIN; /* out of range for valid positions */
>   	window->map_request_y = INT_MIN; /* out of range for valid positions */
> +	weston_output_weak_ref_init(&window->legacy_fullscreen_output);
>   
>   	geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
>   	/* technically we should use XRender and check the visual format's
> @@ -1232,6 +1293,8 @@ weston_wm_window_destroy(struct weston_wm_window *window)
>   {
>   	struct weston_wm *wm = window->wm;
>   
> +	weston_output_weak_ref_clear(&window->legacy_fullscreen_output);
> +
>   	if (window->repaint_source)
>   		wl_event_source_remove(window->repaint_source);
>   	if (window->cairo_surface)
> @@ -2542,7 +2605,6 @@ xserver_map_shell_surface(struct weston_wm_window *window,
>   		wm->server->compositor->xwayland;
>   	const struct weston_desktop_xwayland_interface *xwayland_interface =
>   		wm->server->compositor->xwayland_interface;
> -	struct weston_output *output;
>   	struct weston_wm_window *parent;
>   
>   	weston_wm_window_read_properties(window);
> @@ -2586,11 +2648,9 @@ xserver_map_shell_surface(struct weston_wm_window *window,
>   	if (window->fullscreen) {
>   		window->saved_width = window->width;
>   		window->saved_height = window->height;
> -		xwayland_interface->set_fullscreen(window->shsurf, NULL);
> +		xwayland_interface->set_fullscreen(window->shsurf,
> +						   window->legacy_fullscreen_output.output);
>   		return;
> -	} else if (legacy_fullscreen(wm, window, &output)) {
> -		window->fullscreen = 1;
> -		xwayland_interface->set_fullscreen(window->shsurf, output);
>   	} else if (window->override_redirect) {
>   		xwayland_interface->set_xwayland(window->shsurf,
>   						 window->x, window->y);
> 


-- 

Quentin “Sardem FF7” Glidic


More information about the wayland-devel mailing list