For some time I’ve been working on HiDPI support for Gnome, in order to support all the new laptops with very high resolution displays. This work is now at a stage where I can start showing it off and adventurous users might even want to test it out.
The support happens on many layers, like:
- Wayland: I’ve added support in the protocol for scaled windows and outputs, and implemented this in Weston (the Wayland compositor reference implementation) and the wayland sample clients. This is currently in the unstable branches and will be in Wayland 1.2.
- Cairo: In order to seamlessly support hidpi rendering I’ve added support for setting device-scale on cairo surfaces. This code is a prerequisite for the Gtk+ support, and is currently in a cairo branch, but will land in Cairo 1.13 eventually.
- Gnome-icon-theme: Added high resolution version of most images used in the theme.
But most of the work has been in Gtk+. There is a branch called wip/window-scales that contains this code. It has:
- Support for scaled windows in the wayland backend, including support for different scale factors on different outputs.
- Support for scaled windows on X, limited to one scaling factor for all monitors.
- Support for retina displays on OSX
- Support for alternative CSS assets for scaled windows, so that you can specify higher resolution background and border images in your themes that will be used on hidpi screens.
- Support for alternative high-resolution icons for scaled windows, including additions to the icon theme spec so that themes can specify higher resolution images with less details (i.e. 24×24@2x is the same size as 48×48@1x, but has less detail).
Here is how it looks right now: (click for full version)
This is work in progress, but if you want to try it out, here is the code you need to use:
- Cairo device-scale branch
- gnome-themes-standard wip/hidpi branch
- Wayland master if you want to build the wayland Gtk+ backend.
- gtk+ wip/window-scales branch
You can then enable the scaling either by setting GDK_SCALE=2 in the environment, or by using gsettings (only works under gnome):
gsettings set org.gnome.settings-daemon.plugins.xsettings overrides "{ 'Gdk/WindowScalingFactor':<2>, 'Gdk/UnscaledDPI':<92160> }"
There is still a lot of work to do, but I hope to have this mostly done for my talk at Guadec. Hopefully I’ll see you there!
And last, but not least, many thanks to Brion Vibber who generously donated a Chromebook Pixel to me so that I could work on this stuff.
This is not only interesting for HiDPI Displays but although for people with bad eyes. My dad e.g. always changes the resolution to get everything bigger. Btw. can I set the GDK_SCALE to 1.5?
This looks fantastic, though I won’t be able to try it yet. Excellent work, and can’t wait to see it in action.
Hopefully this will make bugs https://bugzilla.gnome.org/show_bug.cgi?id=680659 and https://bugzilla.gnome.org/show_bug.cgi?id=680884 irrelevant.
OTOH, I would like you to explain the intended interaction of the window scaling factor with the text scaling factor in gnome-tweak-tool.
So, the idea here is to scale up bitmaps but allow rendering anything of vector form (cairo drawing, scalable fonts, etc) taking full advantage of the available pixels?
Looks awesome!
Once this support goes in, what are the chances of having it automatically used, and no longer overriding the correctly detected monitor DPI with an assumed 96 or similar?
I’d love to have font sizes and UI sizes Just Work on all devices.
Looking at the screenshot, the window decorations stand out as the main thing that isn’t scaled. Any plans to fix metacity/mutter/gnome-shell to scale the window decorations to match the device scale?
Awesome! Can’t wait to try it out…
Supporting mixed resolutions will be the biggest win here; laptops with 2x-density screens are creeping into the PC world, but external monitors and projectors are mostly going to be more traditional density for a while.
Alex, are you going with only 1 & 2 densities (does make things simpler…) or supporting other densities like 1.5? This would be perfect for casual browsing on the 1080p screen on my Sputnik 2 Linux ultrabook…
What about resolution independence https://bugzilla.gnome.org/show_bug.cgi?id=546711 ?
Window scaling is only by integers. Scaling by a fractional value like 1.5 is problematic as it will lead to things like xwindows/gdkwindows of non-integer sizes which doesn’t work, and it will cause problems with clipping on non-whole-pixel borders. Additionally, we will never have assets for all possible scales. Plus, fractional size borders etc just never look good.
However, one can combine integer scaling with text dpi scaling to achieve some middle-ground. Also, in a wayland compositor one could do the OSX style “render at 2x then downscale to x1.5 approach, but that will be hard in X (although it will be worth looking into).
Alexander: text-scaling will be independent to the window scale, i.e. it will affect both scaled and non-scaled windows the same.
Anonymous: Vector rendering is also “scaled up”, its just that such scaling is “lossless”, i.e. it will render at (what it seems to the application at least) subpixel precision. But yeah, basically,. any normal vector rendering will automatically look good, while pixels (like e.g. png icons) need to supply alternative images at higher resolution.
Other Anonymous: This is just the Gtk+ side, on the gnome desktop side we will have code to automatically enable this for high dpi screens.
Yet another Anonymous: Obviously we also have to fix gnome-shell for the full hidpi experience, yes.
Brion Vibber: I have some ideas how to do mixed resolution on X. With a compositor and some set of X extensions I *think* it will be doable, but that will be more work. For the moment we’ll have to do with only one scaling factor. Of course, when we eventually move to Wayland the mixed resolution stuff will automatically work. The question is what comes first, gnome-shell on wayland or finishing the X work needed to handle mixed resolutions. We’ll have to see.
Ivan: I don’t think resolution independence in general is all that interesting. Scaling by random factors will never look very good, and I don’t think normal apps really need some absolute physical size of its UI. It *is* possible to get at the actual physical resolution on the screen for the few apps that need it (e.g. gimp), but e.g. automatically making all buttons 14 mm tall on all monitors is not really an interesting goal.
(All three of those anonymouses were me.)
Regarding fractional sizes: bitmaps won’t work that well when scaled to a fractional size, but vector drawing should work reasonably well, so you could reasonably apply such a scale factor to widgets and cairo. And while you won’t necessarily have resources available for a 61px icon, you can always scale down a 256px icon like OS X does, or use a vector icon, or choose the closest integer size and either center or scale it. Many options exist. And above a certain size, bilinear scaling should turn out just fine.
“automatically enable this for high dpi screens” sounds nice, but I’d like to make sure that this also nicely handles the 120 DPI case as well, not just the 200+ DPI case. If I have a 120 DPI screen, everything will look too small if rendered for 96 DPI as GNOME currently does. Scaling text by 120/96 would be nice; scaling the UI by 120/96 would be even better.
I personally like the idea of resolution-independence, though it’ll always need some extra details such as usage model: touch needs bigger UI elements; phones and tablets are commonly held closer to the eye than laptops and both are far closer than TVs. Still a good goal, and this work may help there, but it doesn’t need to solve every problem right away.
““render at 2x then downscale to x1.5 approach”
I think we’d be better off as render at 3x then downscale 2x. Downscaling can easily be done using the existing GPU hardware.
Thankyou so much for this. Push hard to get this included in the mainline. With this and Wayland, the linux GUI stack is looking up-to-date at last.
“render at 2x then downscale to x1.5” or “render at 3x then downscale 2x” – won’t that require freetype patches or special-casing text so that it doesn’t mess up with hinting?
Does CSS support @media screen and (min-resolution: 2dppx)? That could be used instead of separate file.
Also there’s background-size, so perhaps 1x CSS could just downscale the background?
@lwqer: no, the gtk CSS format does not support media rules. also, as a system it sucks pretty badly, because it leads to a ton of duplication.
So as you mentioned a Pixel test unit, can we expect to see this pushed into Crouton soon or are there concise instructions to implement this on my oiwn for my Pixel? I did about all I could, as far as tweaking various settings to make XFCE somewhat usable with HDPI, but I’m not as satisfied with XWindow support on the Pixel when compared with how Chrome OS scales on the same device.
Ryan: I don’t use crouton, and XFCE is gtk2 based, so it will not be able to use this work as its for gtk3.
It’s an important step towards resolution independence!
For text you really want fractional scaling. Even MoFo had to give up on its traditional “everything is 96 dpi” stance in its latest Firefox versions and it now uses the system dpi setting (at least on windows). MoFo 96dpi justifications where the main argument of people that broke text resolution handling in GNOME.
In a wayland world will GNOME try to use accurate dpi for each separate screen at last or will it continue to be a PITA to properly set up a single screen? It’s just a simple ruler problem damnit. More complex stuff like color management have been fixed quite a long time ago.
And I know there are screens with buggy hardware out there, but buggy hardware didn’t stop 3D use in GNOME.
One thing I wonder: Why do you use the same hack as Apple did, upscaling some windows and then using HiDPI resources for some stuff inside these windows etc. – instead of properly fixing the issue by making applications DPI-aware and scale up properly?
Nice work! When in Ubuntu?
Is the reason for this that gnome does not respect DPI settings ? I couldn’t understand why is an artificial factor necessary. Why not to use the screen DPI value ? And will this scale fonts ? Scaling fonts seems to be a very bad idea. We could reduce or get rid of font hinting by using larger fonts. Scaling a smaller font would preserve hinting instead.