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. We should also be careful when mapping surfaces in MAXIMIZED state(v2)
Signed-off-by: Ilia Bozhinov <[email protected]> --- libweston-desktop/xwayland.c | 79 ++++++++++++++++++++++++++-------- xwayland/window-manager.c | 24 +++++++++++ xwayland/xwayland-internal-interface.h | 2 + 3 files changed, 86 insertions(+), 19 deletions(-) diff --git a/libweston-desktop/xwayland.c b/libweston-desktop/xwayland.c index 4f4b453f..f0e91ab9 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 { @@ -62,7 +62,7 @@ struct weston_desktop_xwayland_surface { struct weston_geometry next_geometry; bool has_next_geometry; bool added; - enum weston_desktop_xwayland_surface_state state; + uint32_t state; }; static void @@ -78,7 +78,7 @@ weston_desktop_xwayland_surface_change_state(struct weston_desktop_xwayland_surf assert(!parent || state == TRANSIENT); if (to_add && surface->added) { - surface->state = state; + surface->state |= state; return; } @@ -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,30 @@ 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) { + weston_desktop_xwayland_surface_change_state(surface, MAXIMIZED, NULL, + 0, 0); + } else { + surface->state &= ~MAXIMIZED; + if (surface->state == NONE) + weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, + NULL, 0, 0); + } } static bool @@ -199,7 +222,27 @@ 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_fullscreen(wsurface, fullscreen); + if (fullscreen) { + weston_desktop_xwayland_surface_change_state(surface, FULLSCREEN, + NULL, 0, 0); + } else { + surface->state &= ~FULLSCREEN; + if (surface->state == NONE) + weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, + NULL, 0, 0); + } } static const struct weston_desktop_surface_implementation weston_desktop_xwayland_surface_internal_implementation = { @@ -207,7 +250,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, }; @@ -262,14 +307,14 @@ set_toplevel(struct weston_desktop_xwayland_surface *surface) { weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, NULL, 0, 0); + 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); } @@ -322,9 +367,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 +377,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); 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
