Currently the xwayland implementation of desktop surfaces doesn't do anything when weston_desktop_surface_set_maximized/fullscreen() is called. In order to support this, we have to add xwayland internal interfaces for sending those requests to the xwayland window. Also, a xwayland desktop surface states need to be handled better - the current way of assigning a single state to each surface doesn't work - for example, if a view was maximized, then fullscreen and then unfullscreened, we would lose the maximized state. That's why this code handles states as bit masks of the states.
Signed-off-by: Ilia Bozhinov <[email protected]> --- libweston-desktop/xwayland.c | 74 +++++++++++++++++++++++----------- xwayland/window-manager.c | 24 +++++++++++ xwayland/xwayland-internal-interface.h | 2 + 3 files changed, 77 insertions(+), 23 deletions(-) diff --git a/libweston-desktop/xwayland.c b/libweston-desktop/xwayland.c index 4f4b453f..8a105537 100644 --- a/libweston-desktop/xwayland.c +++ b/libweston-desktop/xwayland.c @@ -38,12 +38,12 @@ #include "xwayland/xwayland-internal-interface.h" enum weston_desktop_xwayland_surface_state { - NONE, - TOPLEVEL, - MAXIMIZED, - FULLSCREEN, - TRANSIENT, - XWAYLAND, + NONE = 0, + TOPLEVEL = 1 << 0, + MAXIMIZED = 1 << 1, + FULLSCREEN = 1 << 2, + TRANSIENT = 1 << 3, + XWAYLAND = 1 << 4, }; struct weston_desktop_xwayland { @@ -178,7 +178,7 @@ weston_desktop_xwayland_surface_destroy(struct weston_desktop_surface *dsurface, if (surface->added) weston_desktop_api_surface_removed(surface->desktop, surface->surface); - else if (surface->state == XWAYLAND) + else if (surface->state & XWAYLAND) weston_desktop_surface_unlink_view(surface->view); free(surface); @@ -190,7 +190,25 @@ weston_desktop_xwayland_surface_get_maximized(struct weston_desktop_surface *dsu { struct weston_desktop_xwayland_surface *surface = user_data; - return surface->state == MAXIMIZED; + return surface->state & MAXIMIZED; +} + +static void +weston_desktop_xwayland_surface_set_maximized(struct weston_desktop_surface *dsurface, + void *user_data, bool maximized) +{ + struct weston_desktop_xwayland_surface *surface = user_data; + struct weston_surface *wsurface = + weston_desktop_surface_get_surface(surface->surface); + + if (surface->state & FULLSCREEN) + return; + + surface->client_interface->send_maximized(wsurface, maximized); + if (maximized) + surface->state |= MAXIMIZED; + else + surface->state &= ~MAXIMIZED; } static bool @@ -199,7 +217,22 @@ weston_desktop_xwayland_surface_get_fullscreen(struct weston_desktop_surface *ds { struct weston_desktop_xwayland_surface *surface = user_data; - return surface->state == FULLSCREEN; + return surface->state & FULLSCREEN; +} + +static void +weston_desktop_xwayland_surface_set_fullscreen(struct weston_desktop_surface *dsurface, + void *user_data, bool fullscreen) +{ + struct weston_desktop_xwayland_surface *surface = user_data; + struct weston_surface *wsurface = + weston_desktop_surface_get_surface(surface->surface); + + surface->client_interface->send_maximized(wsurface, fullscreen); + if (fullscreen) + surface->state |= FULLSCREEN; + else + surface->state &= ~FULLSCREEN; } static const struct weston_desktop_surface_implementation weston_desktop_xwayland_surface_internal_implementation = { @@ -207,7 +240,9 @@ static const struct weston_desktop_surface_implementation weston_desktop_xwaylan .set_size = weston_desktop_xwayland_surface_set_size, .get_maximized = weston_desktop_xwayland_surface_get_maximized, + .set_maximized = weston_desktop_xwayland_surface_set_maximized, .get_fullscreen = weston_desktop_xwayland_surface_get_fullscreen, + .set_fullscreen = weston_desktop_xwayland_surface_set_fullscreen, .destroy = weston_desktop_xwayland_surface_destroy, }; @@ -260,16 +295,15 @@ create_surface(struct weston_desktop_xwayland *xwayland, static void set_toplevel(struct weston_desktop_xwayland_surface *surface) { - weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, NULL, - 0, 0); + surface->state |= TOPLEVEL; + surface->state &= ~(MAXIMIZED | FULLSCREEN); } static void set_toplevel_with_position(struct weston_desktop_xwayland_surface *surface, int32_t x, int32_t y) { - weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, NULL, - 0, 0); + set_toplevel(surface); weston_desktop_api_set_xwayland_position(surface->desktop, surface->surface, x, y); } @@ -305,8 +339,7 @@ static void set_fullscreen(struct weston_desktop_xwayland_surface *surface, struct weston_output *output) { - weston_desktop_xwayland_surface_change_state(surface, FULLSCREEN, NULL, - 0, 0); + surface->state |= FULLSCREEN; weston_desktop_api_fullscreen_requested(surface->desktop, surface->surface, true, output); } @@ -322,9 +355,7 @@ static int move(struct weston_desktop_xwayland_surface *surface, struct weston_pointer *pointer) { - if (surface->state == TOPLEVEL || - surface->state == MAXIMIZED || - surface->state == FULLSCREEN) + if (surface->state & (TOPLEVEL | MAXIMIZED | FULLSCREEN)) weston_desktop_api_move(surface->desktop, surface->surface, pointer->seat, pointer->grab_serial); return 0; @@ -334,9 +365,7 @@ static int resize(struct weston_desktop_xwayland_surface *surface, struct weston_pointer *pointer, uint32_t edges) { - if (surface->state == TOPLEVEL || - surface->state == MAXIMIZED || - surface->state == FULLSCREEN) + if (surface->state & (TOPLEVEL | MAXIMIZED | FULLSCREEN)) weston_desktop_api_resize(surface->desktop, surface->surface, pointer->seat, pointer->grab_serial, edges); @@ -363,8 +392,7 @@ set_window_geometry(struct weston_desktop_xwayland_surface *surface, static void set_maximized(struct weston_desktop_xwayland_surface *surface) { - weston_desktop_xwayland_surface_change_state(surface, MAXIMIZED, NULL, - 0, 0); + surface->state |= MAXIMIZED; weston_desktop_api_maximized_requested(surface->desktop, surface->surface, true); } diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 13acc84e..ef07a7cd 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -2617,8 +2617,32 @@ send_position(struct weston_surface *surface, int32_t x, int32_t y) } } +static void send_maximized(struct weston_surface *surface, bool maximized) +{ + struct weston_wm_window *window = get_wm_window(surface); + + if (window->maximized_horz == maximized && + window->maximized_vert == maximized) + return; + + window->maximized_horz = window->maximized_vert = maximized; + weston_wm_window_set_net_wm_state(window); +} + +static void send_fullscreen(struct weston_surface *surface, bool fullscreen) +{ + struct weston_wm_window *window = get_wm_window(surface); + if (window->fullscreen == fullscreen) + return; + + window->fullscreen = fullscreen; + weston_wm_window_set_net_wm_state(window); +} + static const struct weston_xwayland_client_interface shell_client = { send_configure, + send_maximized, + send_fullscreen }; static int diff --git a/xwayland/xwayland-internal-interface.h b/xwayland/xwayland-internal-interface.h index 10964440..48716b14 100644 --- a/xwayland/xwayland-internal-interface.h +++ b/xwayland/xwayland-internal-interface.h @@ -31,6 +31,8 @@ struct weston_desktop_xwayland_surface; struct weston_xwayland_client_interface { void (*send_configure)(struct weston_surface *surface, int32_t width, int32_t height); + void (*send_maximized)(struct weston_surface *surface, bool maximized); + void (*send_fullscreen)(struct weston_surface *surface, bool fullscreen); }; struct weston_desktop_xwayland_interface { -- 2.13.0 _______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
