Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xwayland: add hidpi support via xwayland scale command #5090

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Dirbaio
Copy link

@Dirbaio Dirbaio commented Mar 10, 2020

This PR adds an xwayland scale N command that sets a "global scale factor" for xwayland apps to N.

This causes all xwayland windows to be rendered at that scale. If a window is then displayed in an output with different scale, it is scaled so that the text is the correct size. Text looks best when rendered with matching scale.

This allows the user to choose on which output the text looks best if they have outputs with different scales.

Default xwayland scale is 1, which matches the previous behavior.

This requires xserver patches from https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/432
This requires wlroots patches from swaywm/wlroots#2064

Read the wlroots PR for technical details on how the scaling works.

@jbeich
Copy link
Contributor

jbeich commented May 16, 2020

Can you document xwayland scale <N> in sway/sway.5.scd? Also, -Dxwayland=false build fails (see f98ca3a for a rough fix):

../sway/commands/xwayland/scale.c:23:12: error: no member named 'xwayland' in 'struct sway_server'
        if(server.xwayland.wlr_xwayland != NULL) {
           ~~~~~~ ^
../sway/commands/xwayland/scale.c:24:3: error: implicit declaration of function 'wlr_xwayland_set_scale' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                wlr_xwayland_set_scale(server.xwayland.wlr_xwayland, scale);
                ^
../sway/commands/xwayland/scale.c:24:3: note: did you mean 'xwayland_cmd_scale'?
../sway/commands/xwayland/scale.c:7:21: note: 'xwayland_cmd_scale' declared here
struct cmd_results *xwayland_cmd_scale(int argc, char **argv) {
                    ^
../sway/commands/xwayland/scale.c:24:33: error: no member named 'xwayland' in 'struct sway_server'
                wlr_xwayland_set_scale(server.xwayland.wlr_xwayland, scale);
                                       ~~~~~~ ^
3 errors generated.

@emersion emersion added the enhancement New feature or incremental improvement label Jun 25, 2020
@zsolt-donca
Copy link

I have an issue with the code present in this MR: the mouse cursor is really tiny for me in the XWayland clients. The cursor appears half the normal size, or maybe even less. I am using xwayland scale 2 and one of my outputs has scale 1.5, the other 2.0. The cursor appears very small on both. I already brought this issue up in swaywm/wlroots#2064 (comment) where I included further details, and got the answer swaywm/wlroots#2064 (comment) stating that it is the Wayland compositor/DE, such as sway, that sets the very small cursor. I indeed managed to confirm this by setting XCURSOR_SIZE=48 before launching an affected app, and the cursor appeared normal.

Does anybody has any idea on this? If somebody could point me into the right direction as to where to look for this in the code, I'd be willing to do some testing and maybe come up with a fix. I imagine that this shouldn't be that big - after all, I suspect it's just that the default cursor size should be multiplied by the xwayland scale factor.

@progandy
Copy link
Contributor

If you set a global xwayland scale factor, then you should set a similarly scaled cursor size with an xsettings daemon (Gtk/CursorThemeSize) and xrdb (Xcursor.size) just like you set higher dpi. (Keep XCURSOR_SIZE unset I think)

@zsolt-donca
Copy link

@progandy That's what I am doing. I think that the issue is that XCURSOR_SIZE is being set by sway itself (to 24) - if I unset it, my XWayland-clients have the proper mouse cursor size (probably though the xsettings you also mentioned). I don't have any references to it in my zshrc file, but the variable is still being set, and I can only think of sway.

Can somebody confirm if sway indeed set XCURSOR_SIZE?

@yegorius
Copy link

I confirm: on my system apps that run under Xwayland have XCURSOR_SIZE=24 despite me not setting it anywhere.

@yegorius
Copy link

BTW, Xwayland process also has XCURSOR_SIZE=24

@progandy
Copy link
Contributor

progandy commented Nov 26, 2020

Can somebody confirm if sway indeed set XCURSOR_SIZE?

Yes, I completely forgot that:

setenv("XCURSOR_SIZE", cursor_size_fmt, 1);
(fixed link)
Wayland doesn't have any better way to set the cursor size for wayland clients, so sway will need to handle scaling for xwayland or the whole cursor situation will have to be improved somehow.

@zsolt-donca
Copy link

zsolt-donca commented Dec 1, 2020

Thanks for the pointer, @progandy !

Browsing through the code I found that the value of the XCURSOR_SIZE variable can be controlled through the default seat seat0; quoting from man sway-input:

seat xcursor_theme []
Override the system default XCursor theme. The default seat's (seat0) theme is also used as the default cursor theme in XWayland, and exported through the XCURSOR_THEME and XCURSOR_SIZE environment variables.

And adding the following to sway's config actually sets the correct cursor size to XWayland clients:

seat seat0 xcursor_theme "Adwaita" 48 

... but it has the unintended consequence of making the cursor huge in several applications, most notably in sway itself (when on an empty workspace, or when the cursor is over the window decorations). This was unexpected to me, because it says xcursor_theme.

Is there a way to set the correct cursor size in non x-wayland app while using the above setting for the xwayland apps? Is this even an intended behavior?

As another line of thought, I am wondering if it was a good idea to apply the value of xwayland scale to the default value of cursor size (24), as hardcoded in the code: following:

unsigned cursor_size = 24;

What do you think? If somebody could confirm that this was a good idea, I could start looking into it, and maybe come up with a pull request for this branch.

@zsolt-donca
Copy link

The cursor size issue is bigger than I thought. I don't think that it can be fixed just by setting the right value to XCURSOR_SIZE. For testing purposes, I tried a code version that leaves cursor_size and the seat cursor size to their default (24), but sets XCURSOR_SIZE to 48, effectively doubling the value, as both my xwayland scale and sway output scales are also 2. The result: the cursor is correctly sized in xwayland clients, in sway itself, and in most GDK-based applications, but the cursor is double the normal size in Qt-based apps (even though they are running in wayland-native mode) and in various other apps, such as kitty and alacritty. Apparently, these affected apps pick up the value of XCURSOR_SIZE, and since they are running in wayland-native mode, the cursor size is already scaled (according to my output's scale factor), so the cursor is scaled twice.

I think the cursor size variable XCURSOR_SIZE needs to stay the default, and it should be handled in a lower-level, maybe in wlroots or xwayland. Any thoughts from people more knowledgeable than me?

@sjnewbury
Copy link

The cursor size issue is bigger than I thought. I don't think that it can be fixed just by setting the right value to XCURSOR_SIZE. For testing purposes, I tried a code version that leaves cursor_size and the seat cursor size to their default (24), but sets XCURSOR_SIZE to 48, effectively doubling the value, as both my xwayland scale and sway output scales are also 2. The result: the cursor is correctly sized in xwayland clients, in sway itself, and in most GDK-based applications, but the cursor is double the normal size in Qt-based apps (even though they are running in wayland-native mode) and in various other apps, such as kitty and alacritty. Apparently, these affected apps pick up the value of XCURSOR_SIZE, and since they are running in wayland-native mode, the cursor size is already scaled (according to my output's scale factor), so the cursor is scaled twice.

I think the cursor size variable XCURSOR_SIZE needs to stay the default, and it should be handled in a lower-level, maybe in wlroots or xwayland. Any thoughts from people more knowledgeable than me?

The inconsistencies are almost certainly bugs due to the fact that various compositors have inconsistently applied scaling to cursors using various variables. As far as I can tell it isn't clearly documented on freedesktop.org. It is a tin of worms, but it does need addressing. I see incorrectly sized cursors quite often under sway (x2 scaling) without any patches or hacks so it doesn't entirely work anyway as it is, I'm not sure it's really worse with your patch, it just exposes some of the problems more clearly. IMHO, x-cursor size should be separable from wl-cursor size.

@Eitetsu0
Copy link

Wow . This would be perfect for me if it could accept a fractional scale value like xwayland scale 1.5 .

@nlgranger
Copy link

@Eitetsu0 fractional scaling is not supported by xwayland AFAIK and the point of this PR is just to expose the scaling value as a config option instead of letting sway choose it based on an heuristic.

michaelherold added a commit to michaelherold/dotfiles that referenced this pull request Sep 1, 2021
I am currently running [sway-hidpi-git][1] on my laptop that applies [a
patch][2] for managing XWayland scaling at the compositor level. This
works well enough for me except for the cursor size issue outlined in
the pull request. It has proven to be much more stable than the various
environment variable hacks.

It's important to note that the Emacs text scale also requires the GTK
build of Emacs so that it no longer runs under XWayland. I am using the
[emacs-pgtk-native-comp-git][3] package for this.

[1]: https://aur.archlinux.org/packages/sway-hidpi-git/
[2]: swaywm/sway#5090
[3]: https://aur.archlinux.org/packages/emacs-pgtk-native-comp-git/
@1player
Copy link

1player commented Sep 1, 2022

Discussion of the xserver patch has moved here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1318, where it lists three alternative ways of dealing with this problem.

KDE has confirmed they integrated something like it in their compositor, would this PR work with any of these recent developments? I haven't followed to closely, I'm just holding off on the sidelines waiting for anything that deals with this to get merged before I can use Sway on my workstation, and it seems momentum has been lost.

@manio
Copy link
Contributor

manio commented Dec 27, 2023

Hi,
Can we force unscaled XWayland apps with this PR when sway have scaling set for some specific display/monitor?

This is my biggest problem with sway nowadays (I have a HiDPI display with scale set to 2 and I want all my XWayland apps to have it unscaled while wayland-native apps are OK for me).

The Hyprland have a really great solution for this:
https://wiki.hyprland.org/Configuring/XWayland/
It just works out of the box without patching XWayland.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or incremental improvement
Development

Successfully merging this pull request may close these issues.

None yet