LWN.net Logo

Development

High resolution displays and GNOME

By Nathan Willis
August 7, 2013
GUADEC 2013

For years, developers have lived comfortably with the assumption that screen resolutions were in the predictable confines of a certain pixel density—around 75 to 100 pixels-per-inch (ppi). As everyone who sees the latest Chromebook models from Google knows, however, such is no longer the case: the newest displays are well over 200 ppi. There have been partially-completed attempts to modify GNOME for high-resolution display support, but with little success. But now there appears to be a workable solution, as Alex Larsson demonstrated at GUADEC 2013.

The latest Chromebook (the "Pixel") boasts a 239 ppi screen, Larsson said, at which resolution GNOME's user interface elements are unreadably tiny. Allegedly, the display resolution is configurable, via the Xft.DPI setting, which has long been hard-coded to 96 in GNOME. But simply changing it to 239 does not work; as he showed the audience, the result only scales the size of displayed text. Although that improves legibility, UI elements like buttons and scrollbars are still ridiculously tiny. In addition, text labels and icons no longer line up, the default heights of menu bars and buttons is no longer correct, and many other UI assumptions are broken.

[Alex Larsson]

Perhaps the system could be modified to scale everything according to this DPI setting, he said. But despite the fact that the idea seems intuitive, he continued, simply scaling all of the UI elements is not the solution—scaling lines to a non-integer-multiple gives the user fuzzy lines that should be sharp and blurry icons that arguably look worse than the unscaled originals. Vector elements need to be drawn so that they align to the pixel grid of the display, and a separate fix needs to be available for those elements still using PNG or other raster graphics formats.

There are a lot of places in GNOME's user interface that are implicitly sized according to raster images and pixel-specific measurements: icons, cursors, window borders, padding, the minimum sizes of GTK+ widgets—even the cursor speed is defined in terms of pixels. The list of places where the code would need to change is lengthy, and changing it holds the possibility for a lot of unexpected breakage.

But then again, he continued, scaling everything to the exact same physical size is not strictly required; users already cope well with the variations in size caused by the different resolutions of laptop displays and external monitors; no one complains that a button is 6mm high on one and 8mm high on the other. All that really matters is that the system scales elements to approximately similar size on the Pixel display.

Abstraction to the rescue

The notion that the correct solution only needs to approximate the difference in resolution turned out to be one of the key insights. Larsson's eventual answer was to treat the existing "pixel" sizes already in use as an abstract, rather than a physical measurement, so that high-resolution displays appear low-resolution to the top levels of the software stack, and to set a scaling factor that multiplies the actual pixel count rendered on high-resolution displays. For almost everything above the drawing layer, the current definition of pixel would suffice; the pixel size itself could be scaled only when rendered by the lower-level libraries like Cairo and GDK, with very few side effects. Moreover, by always scaling abstract pixels to monitor pixels by integer factors, the pixel grid would automatically be preserved, meaning vector images would remain sharp—and the math would be considerably simpler, too.

He then implemented the abstract pixel scaling plan in Cairo, GDK, and GTK+. Normal monitors are unaffected, as their scaling factor is 1. "HiDPI" monitors like the Pixel use a scaling factor of 2, which results in a usable desktop interface, despite the on-screen elements not quite being the same physical dimensions.

In Cairo, the high-resolution scale factor is applied when the Cairo surface is rendered; applications can access the scaling factor for the display with cairo_surface_get_device_scale(), but normally GTK+ hides it completely. Similarly, in GDK, the sizes and positions of windows, screens, and monitors is still reported in abstract pixels; gdk_window_get_scale_factor() will report the scaling factor, but it is usually unnecessary for applications to know it. Wayland compositors will scale client buffers as necessary, and will allow clients to provide double-scale buffers to cope with the occasional window that spans both a high- and low-resolution display. X support is less flexible; all displays must be the same scale, which is reported via the GDK_SCALE environment variable, but, Larsson said, Wayland is the protocol of the future, so the development there is more important.

There are new functions like gdk_window_create_similar_surface() to transparently create an offscreen surface for the purpose of double-buffering, and GtkIconTheme has been patched to support specifying both normal-resolution and high-resolution versions of icons, but by and large the scaling function is invisible to application code. There are also hooks in place for use when displaying images and other situations where scaling up window content is inappropriate. The scaling functionality is due to land in Cairo 1.13, and Wayland support has been added in version 1.2 of the Wayland protocol definition. The GTK+ and GDK changes are currently available in Larsson's wip/window-scales branch.

Larsson added that GTK+ on Mac OS X also supports the scaling factor, using the operating system's Quartz library. Windows support, however, remains on the to-do list. For the time being, there are very few displays on the market that require a scaling factor other than 1. Larsson described the Chromebook Pixel as the primary driving factor, but Apple Retina displays are also supported, and there are a handful of high-density netbook displays that qualify as high-resolution as well. For the present, 1 and 2 remain the only scaling factors in deployment. There is no telling if or when a 3 or 4 scaling factor will be required for some future display, but when it does, the GNOME stack will be prepared well in advance.

[The author wishes to thank the GNOME Foundation for assistance with travel to GUADEC 2013.]

Comments (19 posted)

Brief items

Quotes of the week

Anytime installing your package pulls in libbonobo, I kill your kitten. Thank you. That is all.
Joanmarie Diggs

Attempt to preemptively defuse snarkers: Cinnamon/MATE/forks of Gnome are a good sign. Don't think so? Study more ecology.
Federico Mena-Quintero

Comments (none posted)

Calligra 2.7 released

Version 2.7 of the Calligra office suite has been released. There's lots of new features, including a reworked toolbox in a number of applications, epub3 support in Author, better task scheduling in Plan, and a long list of improvements to the Krita paint application.

Comments (1 posted)

PyPy 2.1 released

Version 2.1 of the PyPy Python interpreter written in Python (we looked at version 2.0 in May) has been released. It is the first version with official support for ARM processors (work that was supported by the Raspberry Pi Foundation): "PyPy is a very compliant Python interpreter, almost a drop-in replacement for CPython 2.7. It's fast (http://speed.pypy.org) due to its integrated tracing JIT compiler. This release supports x86 machines running Linux 32/64, Mac OS X 64 or Windows 32. This release also supports ARM machines running Linux 32bit - anything with ARMv6 (like the Raspberry Pi) or ARMv7 (like the Beagleboard, Chromebook, Cubieboard, etc.) that supports VFPv3 should work. Both hard-float armhf/gnueabihf and soft-float armel/gnueabi builds are provided." In addition, the first beta release of PyPy3 2.1, which is a Python 3, rather than 2.7, interpreter, is also available.

Full Story (comments: none)

bison 3.0 released

Version 3.0 of the bison parser generator is out with a lot of new features. "An executive summary would include: (i) deep overhaul/improvements of the diagnostics, (ii) more versatile means to describe semantic value types (including the ability to store genuine C++ objects in C++ parsers), (iii) push-parser interface extended to Java, and (iv) parse-time semantic predicates for GLR parsers."

Full Story (comments: 20)

Firefox 23 available

Mozilla has released Firefox 23, for desktop systems and Android devices. The banner feature in this version is mixed content blocking, which provides users with a per-page option to block HTTP resources in HTTPS pages. Other changes include a revamp about:memory user interface and the addition of "social sharing" functionality. Last but certainly not least, this release removes support for the blink tag. At least until the inevitable public outcry.

Full Story (comments: 11)

bzr 2.6.0 released

Version 2.6.0 of the bzr version control system has been released. This update is a bugfix release of the 2.5.x series, but it is marked as the beginning of a long-term stable release series that will be supported by Canonical.

Full Story (comments: none)

matplotlib 1.3.0 available

Version 1.3.0 of matplotlib has been released. This version includes several new features, such as event plots, triangular grid interpolation, and "xkcd-style sketch plotting.

Full Story (comments: none)

Newsletters and articles

Development newsletters from the past week

Comments (none posted)

Danjou: The definitive guide on how to use static, class or abstract methods in Python

On his blog, Julien Danjou examines static, class, and abstract methods in Python and gives examples of how they might be used. "Doing code reviews is a great way to discover things that people might struggle to comprehend. While proof-reading OpenStack patches recently, I spotted that people were not using correctly the various decorators Python provides for methods. So here's my attempt at providing me a link to send them to in my next code reviews. :-)"

Comments (7 posted)

Page editor: Nathan Willis
Next page: Announcements>>

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds