diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c
index 26c52688d3..2c5611b2e6 100644
--- a/video/out/opengl/context_wayland.c
+++ b/video/out/opengl/context_wayland.c
@@ -47,14 +47,14 @@ static void resize(struct ra_ctx *ctx)
     const int32_t width = mp_rect_w(wl->geometry);
     const int32_t height = mp_rect_h(wl->geometry);
 
+    vo_wayland_handle_scale(wl);
+
     vo_wayland_set_opaque_region(wl, ctx->opts.want_alpha);
     if (p->egl_window)
         wl_egl_window_resize(p->egl_window, width, height, 0, 0);
 
     wl->vo->dwidth  = width;
     wl->vo->dheight = height;
-
-    vo_wayland_handle_fractional_scale(wl);
 }
 
 static bool wayland_egl_check_visible(struct ra_ctx *ctx)
diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c
index 3052046935..3b8190e18e 100644
--- a/video/out/vo_dmabuf_wayland.c
+++ b/video/out/vo_dmabuf_wayland.c
@@ -781,12 +781,6 @@ static int preinit(struct vo *vo)
         goto err;
     }
 
-    if (!vo->wl->viewport) {
-        MP_FATAL(vo->wl, "Compositor doesn't support the %s protocol!\n",
-                 wp_viewporter_interface.name);
-        goto err;
-    }
-
     if (vo->wl->single_pixel_manager) {
 #if HAVE_WAYLAND_PROTOCOLS_1_27
         p->solid_buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(
diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c
index 1e5e009bc7..0a64e6ccb2 100644
--- a/video/out/vo_wlshm.c
+++ b/video/out/vo_wlshm.c
@@ -209,7 +209,7 @@ static int resize(struct vo *vo)
         talloc_free(buf);
     }
 
-    vo_wayland_handle_fractional_scale(wl);
+    vo_wayland_handle_scale(wl);
 
     return mp_sws_reinit(p->sws);
 }
diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c
index 761ff5b12c..cdf1ba60b8 100644
--- a/video/out/vulkan/context_wayland.c
+++ b/video/out/vulkan/context_wayland.c
@@ -118,7 +118,7 @@ static bool resize(struct ra_ctx *ctx)
     const int32_t height = mp_rect_h(wl->geometry);
 
     vo_wayland_set_opaque_region(wl, ctx->opts.want_alpha);
-    vo_wayland_handle_fractional_scale(wl);
+    vo_wayland_handle_scale(wl);
     return ra_vk_ctx_resize(ctx, width, height);
 }
 
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index cf4fb8a574..b8c5e00997 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1012,13 +1012,13 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
         }
         wl->window_size.x0 = 0;
         wl->window_size.y0 = 0;
-        wl->window_size.x1 = round(width * wl->scaling);
-        wl->window_size.y1 = round(height * wl->scaling);
+        wl->window_size.x1 = lround(width * wl->scaling);
+        wl->window_size.y1 = lround(height * wl->scaling);
     }
     wl->geometry.x0 = 0;
     wl->geometry.y0 = 0;
-    wl->geometry.x1 = round(width * wl->scaling);
-    wl->geometry.y1 = round(height * wl->scaling);
+    wl->geometry.x1 = lround(width * wl->scaling);
+    wl->geometry.y1 = lround(height * wl->scaling);
 
     if (mp_rect_equals(&old_geometry, &wl->geometry))
         return;
@@ -1500,13 +1500,11 @@ static bool create_input(struct vo_wayland_state *wl)
 
 static int create_viewports(struct vo_wayland_state *wl)
 {
-    if (wl->viewporter) {
-        wl->viewport = wp_viewporter_get_viewport(wl->viewporter, wl->surface);
-        wl->osd_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->osd_surface);
-        wl->video_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->video_surface);
-    }
+    wl->viewport = wp_viewporter_get_viewport(wl->viewporter, wl->surface);
+    wl->osd_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->osd_surface);
+    wl->video_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->video_surface);
 
-    if (wl->viewporter && (!wl->viewport || !wl->osd_viewport || !wl->video_viewport)) {
+    if (!wl->viewport || !wl->osd_viewport || !wl->video_viewport) {
         MP_ERR(wl, "failed to create viewport interfaces!\n");
         return 1;
     }
@@ -1847,9 +1845,7 @@ static void set_surface_scaling(struct vo_wayland_state *wl)
     // dmabuf_wayland is always wl->scaling = 1
     double old_scale = wl->scaling;
     wl->scaling = !wl->using_dmabuf_wayland ? wl->current_output->scale : 1;
-
     rescale_geometry(wl, old_scale);
-    wl_surface_set_buffer_scale(wl->surface, wl->scaling);
 }
 
 static void set_window_bounds(struct vo_wayland_state *wl)
@@ -2182,12 +2178,11 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
     return VO_NOTIMPL;
 }
 
-void vo_wayland_handle_fractional_scale(struct vo_wayland_state *wl)
+void vo_wayland_handle_scale(struct vo_wayland_state *wl)
 {
-    if (wl->fractional_scale_manager && wl->viewport)
-        wp_viewport_set_destination(wl->viewport,
-                                    round(mp_rect_w(wl->geometry) / wl->scaling),
-                                    round(mp_rect_h(wl->geometry) / wl->scaling));
+    wp_viewport_set_destination(wl->viewport,
+                                lround(mp_rect_w(wl->geometry) / wl->scaling),
+                                lround(mp_rect_h(wl->geometry) / wl->scaling));
 }
 
 bool vo_wayland_init(struct vo *vo)
@@ -2244,6 +2239,12 @@ bool vo_wayland_init(struct vo *vo)
         goto err;
     }
 
+    if (!wl->viewporter) {
+        MP_FATAL(wl, "Compositor doesn't support the required %s protocol!\n",
+                 wp_viewporter_interface.name);
+        goto err;
+    }
+
     /* Can't be initialized during registry due to multi-protocol dependence */
     if (create_viewports(wl))
         goto err;
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index adbcca63b2..b6f951995b 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -178,7 +178,7 @@ bool vo_wayland_reconfig(struct vo *vo);
 int vo_wayland_allocate_memfd(struct vo *vo, size_t size);
 int vo_wayland_control(struct vo *vo, int *events, int request, void *arg);
 
-void vo_wayland_handle_fractional_scale(struct vo_wayland_state *wl);
+void vo_wayland_handle_scale(struct vo_wayland_state *wl);
 void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, bool alpha);
 void vo_wayland_sync_swap(struct vo_wayland_state *wl);
 void vo_wayland_uninit(struct vo *vo);