From 08b90a34635635022eb98b102e4ed607e9421c45 Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Thu, 16 Apr 2026 16:02:32 +0200 Subject: [PATCH 1/2] xwayland: set cursor scale --- src/core/seat/cursor.cpp | 5 ++++ src/view/view-impl.hpp | 1 + src/view/xwayland.cpp | 61 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/core/seat/cursor.cpp b/src/core/seat/cursor.cpp index becc6a626..706532262 100644 --- a/src/core/seat/cursor.cpp +++ b/src/core/seat/cursor.cpp @@ -236,6 +236,11 @@ void wf::cursor_t::set_cursor( } } + if (ev->surface) + { + wf::xwayland_adjust_cursor(ev->surface); + } + wlr_cursor_set_surface(cursor, ev->surface, ev->hotspot_x, ev->hotspot_y); last_cursor_name.clear(); diff --git a/src/view/view-impl.hpp b/src/view/view-impl.hpp index ce3b32d0c..3b230f9cb 100644 --- a/src/view/view-impl.hpp +++ b/src/view/view-impl.hpp @@ -77,6 +77,7 @@ void xwayland_update_default_cursor(); void xwayland_bring_to_front(wlr_surface *surface); int xwayland_get_pid(); wl_client *xwayland_get_client(); +void xwayland_adjust_cursor(wlr_surface *cursor_surface); void init_desktop_apis(); void fini_desktop_apis(); diff --git a/src/view/xwayland.cpp b/src/view/xwayland.cpp index 51db3ab05..088647502 100644 --- a/src/view/xwayland.cpp +++ b/src/view/xwayland.cpp @@ -347,3 +347,64 @@ wl_client*wf::xwayland_get_client() return nullptr; #endif } + +#if WF_HAS_XWAYLAND +static void update_xwayland_cursor_surface_scale(wlr_surface *surface, int32_t scale) +{ + if (!surface || (scale <= 0)) + { + return; + } + + surface->current.scale = scale; + + int width = surface->current.buffer_width; + int height = surface->current.buffer_height; + wlr_output_transform_coords(surface->current.transform, &width, &height); + + width /= scale; + height /= scale; + + surface->current.width = width; + surface->current.height = height; +} + +#endif + +void wf::xwayland_adjust_cursor(wlr_surface *cursor_surface) +{ +#if WF_HAS_XWAYLAND + if (wl_resource_get_client(cursor_surface->resource) == wf::xwayland_get_client()) + { + static wf::option_wrapper_t force_xwayland_scaling{"workarounds/force_xwayland_scaling"}; + static wf::wl_listener_wrapper on_cursor_destroy; + static wf::wl_listener_wrapper on_cursor_commit; + static wlr_surface *last_cursor_surface = nullptr; + + if (force_xwayland_scaling && (last_cursor_surface != cursor_surface)) + { + on_cursor_destroy.set_callback([] (void*) + { + on_cursor_destroy.disconnect(); + on_cursor_commit.disconnect(); + last_cursor_surface = nullptr; + }); + + on_cursor_commit.set_callback([] (void*) + { + auto& ol = wf::get_core().output_layout; + auto wo = ol->find_closest_output(wf::get_core().get_cursor_position()); + update_xwayland_cursor_surface_scale(last_cursor_surface, wo->handle->scale); + }); + + on_cursor_destroy.connect(&cursor_surface->events.destroy); + on_cursor_commit.connect(&cursor_surface->events.commit); + last_cursor_surface = cursor_surface; + on_cursor_commit.emit(NULL); + } + } + +#else + (void)cursor_surface; +#endif +} From 83fc8c60d92d67bf914498e27ad3c6dfbdf45a10 Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Thu, 16 Apr 2026 18:29:51 +0200 Subject: [PATCH 2/2] xwayland-surface: fix find_node_at() with scale --- src/view/xwayland/xwayland-surface.cpp | 6 ++++++ src/view/xwayland/xwayland-surface.hpp | 1 + 2 files changed, 7 insertions(+) diff --git a/src/view/xwayland/xwayland-surface.cpp b/src/view/xwayland/xwayland-surface.cpp index 6edf928d1..14ebe1f7b 100644 --- a/src/view/xwayland/xwayland-surface.cpp +++ b/src/view/xwayland/xwayland-surface.cpp @@ -58,3 +58,9 @@ void wf::xw::xwayland_surface_node_t::apply_state(scene::surface_state_t&& state wlr_surface_node_t::apply_state(std::move(state)); } + +std::optional wf::xw::xwayland_surface_node_t::find_node_at(const wf::pointf_t& at) +{ + auto local = to_local(at); + return wlr_surface_node_t::find_node_at(local); +} diff --git a/src/view/xwayland/xwayland-surface.hpp b/src/view/xwayland/xwayland-surface.hpp index 55e558074..da3e6d358 100644 --- a/src/view/xwayland/xwayland-surface.hpp +++ b/src/view/xwayland/xwayland-surface.hpp @@ -19,6 +19,7 @@ class xwayland_surface_node_t : public wf::scene::wlr_surface_node_t std::string stringify() const override; wf::pointf_t to_local(const wf::pointf_t& point) override; wf::pointf_t to_global(const wf::pointf_t& point) override; + std::optional find_node_at(const wf::pointf_t& at) override; void apply_state(scene::surface_state_t&& state) override; void set_scale(float scale);