Bug 93315 - Automatically scale windows?
Summary: Automatically scale windows?
Status: NEW
Alias: None
Product: Wayland
Classification: Unclassified
Component: XWayland (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Wayland bug list
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-10 11:46 UTC by nisses.mail@home.se
Modified: 2018-08-27 07:27 UTC (History)
11 users (show)

See Also:
i915 platform:
i915 features:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description nisses.mail@home.se 2015-12-10 11:46:47 UTC
I was talking to Alex about this in the office and he suggested filing a bug about it, so here we go.

Currently on a hidpi-screen, when running GTK3 apps, such as gedit, totem etc. everything works fine, since the toolkit supports hidpi.
However, older applications, such as Inkscape and GIMP that uses GTK2 becomes super-tiny on the same device. Waiting for them to move over to a newer toolkit version is of course nice, but perhaps wayland could scale those that aren't yet up, since blurry graphics is to prefer over graphics that is too tiny to see.
Comment 1 Alexander Larsson 2015-12-10 11:51:31 UTC
Xwayland should set the scale of the buffers to 1, and then the compositor should automatically scale it up if the output has scale 2. But instead when I run a X11 app it seems to pick larger fonts, but render everything else tiny.
Comment 2 Pekka Paalanen 2015-12-10 12:13:36 UTC
Have you checked that the Wayland compositor actually is configured to have output scale 2? Or that it is not deliberately showing X11 windows unscaled because some X11 toolkits might do hidpi in secret and you don't want to scale up twice?

If X11 apps cannot indicate in which scale they render, then I'd assume Xwayland has no other choice than to use buffer scale 1. When the Wayland compositor is configured correctly, it will scale up all X11 windows. The downside is that Xwayland cannot support hidpi apps. So, you'd have to somehow get that scale info from X11 apps to have them not scaled up twice. Is there any X11 protocol for that?

I gave a quick try with Weston and xterm, and output scale 2 causes the xterm to be scaled up like you would expect.
Comment 3 Alexander Larsson 2015-12-10 14:38:16 UTC
Unfortunately there is no X APIs to get the scale, each toolkit makes some guess on their own.
Comment 4 Pekka Paalanen 2015-12-10 15:09:14 UTC
Right, so either a Wayland compositor scales all X11 windows or none. If you scale none, you miss non-hidpi-aware X11 apps. If you scale all, you have to somehow ensure hidpi-aware X11 apps do not scale themselves.

I suppose there is nothing to do in Xwayland for this? Or should it be lying something to avoid X11 apps scaling themselves?

Should this bug target some other piece of software? Like a compositor that doesn't scale X11 windows?
Comment 5 Daniel Stone 2015-12-10 15:22:12 UTC
Server-side decorations also make it really hard, since you need to make sure the decorations are rendered at the appropriate scale.
Comment 6 Alexander Larsson 2015-12-10 15:25:06 UTC
I've not looked at the gnome-shell code, but running wayland gnome-shell with scale=2 i get X11 windows that have tiny icons but normal text, so i assume it reports the real pixel size to the X11 apps and a large dpi.

It would be nicer if it returned a smaller resolution and a lower dpi, unless the app somehow opted in to supporting hidpi.
Comment 7 Daniel Stone 2015-12-10 15:30:36 UTC
(In reply to Alexander Larsson from comment #6)
> I've not looked at the gnome-shell code, but running wayland gnome-shell
> with scale=2 i get X11 windows that have tiny icons but normal text, so i
> assume it reports the real pixel size to the X11 apps and a large dpi.
> 
> It would be nicer if it returned a smaller resolution and a lower dpi,
> unless the app somehow opted in to supporting hidpi.

It would be nice, but unfortunately X11 has the global co-ordinate space very deeply baked in to its entire API. There's no good way to do this.

I think the only solution will be to work out a way for apps to declare that they are indeed HiDPI-aware and have scaled appropriately (e.g. _NET_WM_SCALE_FACTOR == 2), have the server watch those, and pass that through to the host compositor as appropriate, and make sure that whatever's rendering decorations accounts for this.

Except then you run into the very difficult question of window placement: you'd need to offset all transients by the appropriate amount as well. So, if you have a window which you're scaling up by 2x, and it wants to create a transient at an offset of (40,40) relative to the primary, you need to shift that to (80,80) accordingly.

The window manager would also need to enforce this wrt window configuration: if you have a 3200x1800 output, it needs to clamp maximisation to 1600x900, and so on, and so forth.

Not particularly pretty ...
Comment 8 Alexander Larsson 2015-12-10 15:39:41 UTC
Could we run two xwayland instances? first display is lodpi, and second is hidpi? Then we have some magic desktop file thing to tell the shell to launch hidpi apps on display 2?
Comment 9 Daniel Stone 2015-12-10 16:52:24 UTC
(In reply to Alexander Larsson from comment #8)
> Could we run two xwayland instances? first display is lodpi, and second is
> hidpi? Then we have some magic desktop file thing to tell the shell to
> launch hidpi apps on display 2?

Not without some pretty radical surgery, no. Mutter would need a huge rework to be a WM across multiple X servers at the same time, as would the XWayland integration (e.g. to cope with XIDs no longer being unique).

There's also an additional complication that GTK+2 is HiDPI but not mixed-DPI aware; it seems to just pick a scaling factor from the overall logical display dimensions, so will always scale up to HiDPI, even if it's currently positioned on a low-DPI display. (The silver lining in that cloud is that GTK+2 or Chrome, whichever, don't actually listen to updates on the scaling-factor GSetting, so you can hack around it by changing the GSetting, launching, then changing it back ...)
Comment 10 Olivier Fourdan 2015-12-15 10:02:16 UTC
(In reply to Daniel Stone from comment #9)
> (In reply to Alexander Larsson from comment #8)
> > Could we run two xwayland instances? first display is lodpi, and second is
> > hidpi? Then we have some magic desktop file thing to tell the shell to
> > launch hidpi apps on display 2?
> 
> Not without some pretty radical surgery, no. Mutter would need a huge rework
> to be a WM across multiple X servers at the same time, as would the XWayland
> integration (e.g. to cope with XIDs no longer being unique).

Not sure if that'd be workable, but What about 2 screens of the same display then (:0.0 and :0.1)? Each could have its own resolution/size/DPI, and yet map to the same Wayland output.
Comment 11 Daniel Stone 2015-12-15 14:55:52 UTC
(In reply to Olivier Fourdan from comment #10)
> Not sure if that'd be workable, but What about 2 screens of the same display
> then (:0.0 and :0.1)? Each could have its own resolution/size/DPI, and yet
> map to the same Wayland output.

Mm, a much better idea, but still some pretty radical surgery. Screens aren't hotpluggable for starters (IIRC), and also they're the root of Drawables, so you can't blit Pixmaps across Screens, have a Window spanning Screens, or move a Window between Screens. :(
Comment 12 Alexander Larsson 2015-12-15 15:30:33 UTC
I don't think that is really a problem though. 

not dynamic: We could just always allocate a scale 2 screen.

can't blit across screens: When would you need that. Apps would generally just connect to either one, and ignore the other. The compositor can do blitting on the wayland side.

windows can't share screens or move to other screen: Well, either the app has no knowledge of hidpi, we then always want it to be on the screen that has scale=1 (i.e. is scaled up if the real output is scale=2). Apps that are hidpi aware are passed the unmodified screen (and some env var is set about the scale), and then they can render in full resolution. Then the compositor can scale these down to scale=1 outputs in the mixed-scale case.
Comment 13 Alexander Larsson 2015-12-15 15:31:00 UTC
s/env var/root window x-property/
Comment 14 Daniel Stone 2015-12-15 15:56:04 UTC
(In reply to Alexander Larsson from comment #12)
> I don't think that is really a problem though. 
> 
> not dynamic: We could just always allocate a scale 2 screen.
> 
> can't blit across screens: When would you need that. Apps would generally
> just connect to either one, and ignore the other. The compositor can do
> blitting on the wayland side.
> 
> windows can't share screens or move to other screen: Well, either the app
> has no knowledge of hidpi, we then always want it to be on the screen that
> has scale=1 (i.e. is scaled up if the real output is scale=2). Apps that are
> hidpi aware are passed the unmodified screen (and some env var is set about
> the scale), and then they can render in full resolution. Then the compositor
> can scale these down to scale=1 outputs in the mixed-scale case.

Hm, right; I think that could well work, but would require a fair bit of surgery. Especially on the XWayland side, where we have to perform the mapping back into a fixed/linear co-ordinate space. But yeah, it could well just work ...
Comment 15 drago01 2016-02-20 19:32:46 UTC
I tried to do this once and run into lots of nasty corner cases (see bug 728902).
Comment 16 Adam Goode 2016-05-19 14:14:45 UTC
Will these ideas also work for fractional scales? 1.25x screens are common now.
Comment 17 Olivier Fourdan 2016-05-19 15:32:13 UTC
(In reply to Adam Goode from comment #16)
> Will these ideas also work for fractional scales? 1.25x screens are common
> now.

The scaling facter is an integer in Wayland protocol:

    <event name="scale" since="2">
      <description summary="output scaling properties">
	This event contains scaling geometry information
        that is not in the geometry event. It may be sent after
        binding the output object or if the output scale changes
        later. If it is not sent, the client should assume a
	scale of 1.

	A scale larger than 1 means that the compositor will
	automatically scale surface buffers by this amount
	when rendering. This is used for very high resolution
	displays where applications rendering at the native
	resolution would be too small to be legible.

	It is intended that scaling aware clients track the
	current output of a surface, and if it is on a scaled
	output it should use wl_surface.set_buffer_scale with
	the scale of the output. That way the compositor can
	avoid scaling the surface, and the client can supply
	a higher detail image.
      </description>
      <arg name="factor" type="int" summary="scaling factor of output"/>
    </event>

Beside, I am not sure how a quarter of a pixel would look like.
Comment 18 Alexander Larsson 2016-05-19 15:37:31 UTC
For wayland the plan is for the app to submit scale=2 buffers and for coordinates (window pos, cursor pos, etc) to be scale=2, but the compositor downscales to 1.5 in the final composite to the scanout buffer.
Comment 19 Shane Chen 2016-06-14 19:22:11 UTC
(In reply to Alexander Larsson from comment #18)
> For wayland the plan is for the app to submit scale=2 buffers and for
> coordinates (window pos, cursor pos, etc) to be scale=2, but the compositor
> downscales to 1.5 in the final composite to the scanout buffer.

I'm curious about how to downscale to 1.5.
As the wl_ouput::scale can only be int , so if the compositor is rendering in 1.5 scale, it will tell the client that the output scale is 2? So the client will never aware about the actual output scale 1.5?
Comment 20 Alexander Larsson 2016-06-14 19:41:58 UTC
Yeah, which is how e.g. MacOS X handles this.
Comment 21 Pekka Paalanen 2018-08-27 07:27:48 UTC
A new interesting idea for window scaling from Keith:
https://lists.x.org/archives/xorg-devel/2018-August/057474.html


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.