]> git.mdlowis.com Git - proto/labwc.git/commitdiff
xwayland: Save natural geometry from initially maximized views
authorJohn Lindgren <john@jlindgren.net>
Wed, 8 Feb 2023 02:12:56 +0000 (21:12 -0500)
committerJohan Malm <johanmalm@users.noreply.github.com>
Wed, 8 Feb 2023 22:19:25 +0000 (22:19 +0000)
src/xwayland.c

index d85247bc1731e2c9d42aed982da79605280be056..2a87261dba10e06b9b3afecd767a343005d827cd 100644 (file)
@@ -106,6 +106,38 @@ xwayland_surface_from_view(struct view *view)
        return xwayland_view->xwayland_surface;
 }
 
+static void
+ensure_initial_geometry(struct view *view)
+{
+       if (!view->w || !view->h) {
+               struct wlr_xwayland_surface *xwayland_surface =
+                       xwayland_surface_from_view(view);
+               view->x = xwayland_surface->x;
+               view->y = xwayland_surface->y;
+               view->w = xwayland_surface->width;
+               view->h = xwayland_surface->height;
+               /*
+                * If there is no pending move/resize yet, then set
+                * current values (used in map()).
+                */
+               struct view_pending_move_resize *pending =
+                       &view->pending_move_resize;
+               if (!pending->width || !pending->height) {
+                       pending->x = view->x;
+                       pending->y = view->y;
+                       pending->width = view->w;
+                       pending->height = view->h;
+               }
+       }
+}
+
+static bool
+want_deco(struct wlr_xwayland_surface *xwayland_surface)
+{
+       return xwayland_surface->decorations ==
+               WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
+}
+
 static void
 handle_commit(struct wl_listener *listener, void *data)
 {
@@ -320,6 +352,15 @@ handle_request_maximize(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, request_maximize);
        assert(view);
+       if (!view->been_mapped) {
+               ensure_initial_geometry(view);
+               /*
+                * Set decorations early to avoid changing geometry
+                * after maximize (reduces visual glitches).
+                */
+               view_set_decorations(view,
+                       want_deco(xwayland_surface_from_view(view)));
+       }
        view_toggle_maximize(view);
 }
 
@@ -328,6 +369,9 @@ handle_request_fullscreen(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, request_fullscreen);
        bool fullscreen = xwayland_surface_from_view(view)->fullscreen;
+       if (!view->been_mapped) {
+               ensure_initial_geometry(view);
+       }
        view_set_fullscreen(view, fullscreen, NULL);
 }
 
@@ -389,13 +433,6 @@ get_string_prop(struct view *view, const char *prop)
        return "";
 }
 
-static bool
-want_deco(struct wlr_xwayland_surface *xwayland_surface)
-{
-       return xwayland_surface->decorations ==
-               WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
-}
-
 static void
 handle_set_decorations(struct wl_listener *listener, void *data)
 {
@@ -471,18 +508,13 @@ map(struct view *view)
                return;
        }
        view->mapped = true;
+       ensure_initial_geometry(view);
        wlr_scene_node_set_enabled(&view->scene_tree->node, true);
        struct wlr_xwayland_surface *xwayland_surface =
                xwayland_surface_from_view(view);
        if (!view->fullscreen && xwayland_surface->fullscreen) {
                view_set_fullscreen(view, true, NULL);
        }
-       if (!view->maximized && !view->fullscreen) {
-               view->x = xwayland_surface->x;
-               view->y = xwayland_surface->y;
-               view->w = xwayland_surface->width;
-               view->h = xwayland_surface->height;
-       }
 
        if (view->surface != xwayland_surface->surface) {
                if (view->surface) {
@@ -516,6 +548,16 @@ map(struct view *view)
                        set_initial_position(view, xwayland_surface);
                }
 
+               /*
+                * When mapping the view for the first time, visual
+                * artifacts are reduced if we display it immediately at
+                * the final intended position/size rather than waiting
+                * for handle_commit().
+                */
+               view->x = view->pending_move_resize.x;
+               view->y = view->pending_move_resize.y;
+               view->w = view->pending_move_resize.width;
+               view->h = view->pending_move_resize.height;
                view_moved(view);
                view->been_mapped = true;
        }