Skip to content

xwayland: set cursor scale#3012

Merged
ammen99 merged 2 commits into
masterfrom
xwayland-scale-cursor
Apr 17, 2026
Merged

xwayland: set cursor scale#3012
ammen99 merged 2 commits into
masterfrom
xwayland-scale-cursor

Conversation

@ammen99
Copy link
Copy Markdown
Member

@ammen99 ammen99 commented Apr 16, 2026

Fixes #3011

@lilydjwg This was my first idea about how to fix the issue. I think it might not work very well with mixed DPI, however. Let me know whether this is the correct approach, or maybe we need to do something else?

@lilydjwg
Copy link
Copy Markdown
Contributor

It doesn't work. The code is executed but nothing has changed.

@ammen99
Copy link
Copy Markdown
Member Author

ammen99 commented Apr 16, 2026

@lilydjwg Try the latest commit. Does it at least change things for xterm? Here, I can see quite a big difference.

@lilydjwg
Copy link
Copy Markdown
Contributor

No, nothing has changed.

@ammen99
Copy link
Copy Markdown
Member Author

ammen99 commented Apr 16, 2026

No, nothing has changed.

What is your ini file? Also are you sure that firefox is running Xwayland mode to begin with? I just tested gedit and firefox with the x11 backend and the cursor has the same size as wayland native applications with my patch.

@lilydjwg
Copy link
Copy Markdown
Contributor

Here is my wayfire.ini.

Besides Firefox, I also tested with xterm.

@lilydjwg
Copy link
Copy Markdown
Contributor

I gave codex gpt-5.4 a try and it ended up copying some logic from wlroots' surface_finalize_pending, and it worked as expected. Here's a slightly-revised patch from codex:

diff --git a/src/view/xwayland.cpp b/src/view/xwayland.cpp
index 3fa17742..0fc60185 100644
--- a/src/view/xwayland.cpp
+++ b/src/view/xwayland.cpp
@@ -215,6 +215,39 @@ class xwayland_view_controller_t
 static wlr_xwayland *xwayland_handle = nullptr;
 static wf::wl_listener_wrapper on_xwayland_surface_created;
 static wf::wl_listener_wrapper on_xwayland_ready;
+
+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);
+
+    if (surface->current.viewport.has_src)
+    {
+        width  = surface->current.viewport.src.width;
+        height = surface->current.viewport.src.height;
+    } else
+    {
+        width  /= scale;
+        height /= scale;
+    }
+
+    if (surface->current.viewport.has_dst)
+    {
+        width  = surface->current.viewport.dst_width;
+        height = surface->current.viewport.dst_height;
+    }
+
+    surface->current.width  = width;
+    surface->current.height = height;
+}
 #endif
 
 void wf::init_xwayland(bool lazy)
@@ -372,7 +405,7 @@ void wf::xwayland_adjust_cursor(wlr_surface *cursor_surface)
             {
                 auto& ol = wf::get_core().output_layout;
                 auto wo  = ol->find_closest_output(wf::get_core().get_cursor_position());
-                last_cursor_surface->current.scale = wo->handle->scale;
+                update_xwayland_cursor_surface_scale(last_cursor_surface, wo->handle->scale);
             });
 
             on_cursor_destroy.connect(&cursor_surface->events.destroy);

@ammen99
Copy link
Copy Markdown
Member Author

ammen99 commented Apr 17, 2026

I feel like the src/dst bits are wrong but we also need to scale the size, right. I am not sure why it seems to work here ...

@lilydjwg
Copy link
Copy Markdown
Contributor

Maybe some code path isn't taken in my case? (I looked at this place yesterday but didn't figure out a working solution.)

@ammen99
Copy link
Copy Markdown
Member Author

ammen99 commented Apr 17, 2026

Maybe some code path isn't taken in my case? (I looked at this place yesterday but didn't figure out a working solution.)

Yes, I don't expect many if any clients at all use viewport for cursors, definitely not xwayland. If you delete all of these branches, does it still work? If yes, we could merge.

@lilydjwg
Copy link
Copy Markdown
Contributor

Yes, I simplified the function to the following:

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;
}

And it still works.

@ammen99
Copy link
Copy Markdown
Member Author

ammen99 commented Apr 17, 2026

@lilydjwg Should I push the changes or will you send a PR to this branch?

@lilydjwg
Copy link
Copy Markdown
Contributor

You can just push the changes.

@ammen99 ammen99 force-pushed the xwayland-scale-cursor branch from 90bf78f to 83fc8c6 Compare April 17, 2026 18:38
@ammen99
Copy link
Copy Markdown
Member Author

ammen99 commented Apr 17, 2026

Hopefully I pushed everything correctly, let me know if I messed something up @lilydjwg

@ammen99 ammen99 merged commit 4808227 into master Apr 17, 2026
8 checks passed
@ammen99 ammen99 deleted the xwayland-scale-cursor branch April 17, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When force_xwayland_scaling is true, cursor is big and blurry

2 participants