Obey fraction DPI ratios on Linux to improve HiDPI support

NEW
Unassigned

Status

()

Core
Graphics
P3
normal
a year ago
3 months ago

People

(Reporter: Ehsan, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: gfx-noted)

Attachments

(1 attachment)

(Reporter)

Description

a year ago
I recently switched to using Linux on a high DPI screen running at 3840x2160 and Gecko was defaulting to a DPI scale of 1, which was making it extremely challenging to read web pages.

I drilled it down to this code: <https://searchfox.org/mozilla-central/rev/79f625ac56d936ef5d17ebe13a123b25efee4241/gfx/thebes/gfxPlatformGtk.cpp#364>.  I had my scaling in the desktop settings set to 1.2, but Gecko had decided that it wouldn't honor anything below 1.32!  This behavior is different than all other native applications, and also different than Epiphany and Chrome.  They all respect the exact fraction DPI scale set in the desktop settings, and I see no reason why we would choose to behave differently.

With a patch to make us obey this value, Firefox behaves exactly like those other two browsers, and looks great on both my built-in HiDPI and my external LowDPI monitor.
(Reporter)

Comment 1

a year ago
Created attachment 8870215 [details] [diff] [review]
Switch to using fraction scaling based on the reported DPI from gtk
Attachment #8870215 - Flags: review?(karlt)
(Reporter)

Comment 3

a year ago
Alex, if you can test this patch and let me know what you think, I would appreciate it!
Whiteboard: gfx-noted
Summary: Obey fraction DPI rarios on Linux to improve HiDPI support → Obey fraction DPI ratios on Linux to improve HiDPI support

Comment 4

a year ago
On my 141 DPI laptop, images with text look better with 1.5 devPixelsPerPx instead of the exact 1.46875 devPixelsPerPx. In the case of images with small text, such as the Wikipedia logo, 1.5 is dramatically better.

If you look at the Chrome function GtkUi::UpdateDeviceScaleFactor <https://cs.chromium.org/chromium/src/chrome/browser/ui/libgtkui/gtk_ui.cc?rcl=727830d6051803fe78533922089672dfb652b3ac&l=1063> you can see that Chrome rounds the scaling factor to the nearest tenth. I tested this by starting Chromium with `chromium --force-device-scale-factor=1.46875` and images with text were just as blurry as Firefox with 1.46875 devPixelsPerPx.

At <https://bugzilla.mozilla.org/show_bug.cgi?id=1335465#c2>, Karl suggested adding a 1.25 bracket. I think that's a good idea.

Comment 5

a year ago
To answer your question about why Firefox should behave differently than other apps: Other apps may care more about representing exact dimensions than displaying crisp images. For example, a word processing program may want to display a virtual piece of paper that is exactly the same width as a real piece of paper. In the 90's before DPIs were so messed up, I actually saw people holding up paper to their screens to decide where to set the margins.
(Reporter)

Comment 6

a year ago
OK, thanks for testing Alex and also thanks a lot for digging up the Chromium source code.  I think doing something like rounding to the nearest tenth makes sense, that would certainly be much better than our current scaling steps.  It is definitely better than having to adjust the layout.css.devPixelsPerPx pref each time I connect to my external Low-DPI monitor.  :-)

Since ultimately what we end up doing here depends on what Karl decides, I'll wait for him to get back to me before changing the patch...
Sorry for the delay responding.  This is a touchy issue as perhaps indicated
by the bugs referenced by comments in Chromium's
GtkUi::UpdateDeviceScaleFactor().  Most Gecko discussion is in bug 1214470.

Resolution media queries only really work well at moderate resolutions if
there is a convention re which precise dpis will be supported by browsers and
web pages.  The dpis more likely to be supported by web pages are the ones
that are common operating system defaults exposed through web browsers.  The
decimal fractions of
https://chromium.googlesource.com/chromium/src/+/32ac9f15d6b11556611d2c86849740f8fb921d32
seem somewhat arbitrary.  That code is Linux-specific, and so I'd prefer to
use base-2-friendly fractions like WINNT..

I'm very cautious about introducing further fractions because of effects both
on web content and Firefox UI.
https://bugzilla.mozilla.org/show_bug.cgi?id=1214470#c33
discusses a typical web content issue.
https://bugzilla.mozilla.org/show_bug.cgi?id=1214470#c34
mentions some UI issues.

These issues may not be obvious on your 280 dpi laptop screen (assuming 15.6"),
but they are much more obvious on a true 115 or 120 dpi screen.

Ehsan, I'd like to understand more about your situation as a case study.
We need to weigh up the advantages of an additional step against the costs of
poor rendering.  The goal is to pick defaults that give most people what they
want and layout.css.devPixelsPerPx is available for those that are not happy
with the defaults.

I'm surprised if a factor of only 1.2 makes the difference between comfortable
and "extremely challenging", so I wonder whether there is piece of information
or understanding I'm missing.

https://bugzilla.mozilla.org/show_bug.cgi?id=1335465#c9 suggests that a
scaling of 2 is good and 1.375 is barely readable in Firefox, while other apps
are very nice at 1.2.  However, comment 0 in this report implies that 1.2 is
sufficient for Firefox.

Is there another scale factor that has changed between these comments?
What desktop environment is providing the other "native applications"?

GTK scales only text (not icons or controls) on changing the dpi.
It has a separate global scaling factor, but that accepts only integer
values.  So I wonder whether you are looking at different native applications,
or whether perhaps 1.2 has somehow triggered a jump to 2.

Does the UI in your desktop environment offer 1.2 (115.2 dpi) as one of a
number of discrete scaling options, or are all fractions available?

Unity apps may behave quite differently, but I don't know whether
/com/ubuntu/user-interface/scale-factor supports non-integer multiples of 1/8.
(1.2 is not an integer multiple of 1/8.)
With Ubuntu moving to GNOME, following GTK behaviour becomes more important.
Flags: needinfo?(ehsan)
Comment on attachment 8870215 [details] [diff] [review]
Switch to using fraction scaling based on the reported DPI from gtk

If we add more steps, then I'd like to do that incrementally, rather than suddenly exposing all possible steps, and then, I suspect, reverting to fewer steps in response to user feedback.
Attachment #8870215 - Flags: review?(karlt) → review-
(In reply to :Ehsan Akhgari (needinfo please, extremely long backlog) from comment #6)
> [..] having to adjust the
> layout.css.devPixelsPerPx pref each time I connect to my external Low-DPI
> monitor.  :-)

Is the system dpi changing on connection of the external monitor?

If so, does the output from "xrdb -query | grep Xft.dpi" change?
(Reporter)

Comment 10

a year ago
I think I may need to take a step back and tell you a bit about what my day to day usage of my computer looks like to explain the fluctuations between https://bugzilla.mozilla.org/show_bug.cgi?id=1335465#c9 and comment 0 and also explain where I'm coming from here (sorry this is long but I think explaining this is important since these issues may not be obvious from the bugzilla comments).  My setup varies between using the built-in HiDPI screen of my laptop when I'm at the office and an external LowDPI 3440x1440 monitor when I'm at home.  My desktop scaling factor is set to 1.2 right now.  I have been switching back and forth between Gnome and XFCE but I'm using XFCE at the moment.  Note that I'm not yet quite sold on the 1.2 value and would like to be able to change it, but Firefox makes this very difficult.  More on this later.

With this setup, out of the box everything looks great on my LowDPI screen, and outside of Firefox everything looks OK on my HiDPI screen (the text in other apps is a bit small but I have gotten used to reading it comfortably after using the HiDPI screen a bit.)  With the default settings, with the HiDPI screen I can't read the text on most web pages as Firefox picks a scaling ratio of 1.

Naturally what I did when I first encountered this issue was googled it.  People have written tutorials about Firefox on Linux with a HighDPI screen, like this one: https://fedoramagazine.org/how-to-get-firefox-looking-right-on-a-high-dpi-display-and-fedora/ (the screenshot in that article BTW is exactly the experience that I get out of the box.)  But the pref solution is very suboptimal for me for a few reasons:

  * It makes it impossible to use a multi-monitor setup.  Right now as I'm typing this, I'm working from home, and the window with this bugzilla tab is sitting on my LowDPI window which is where I have my Firefox window where I can read the text, and there is another Firefox window and a terminal window on my built-in monitor also open, and from where I'm sitting I can very comfortably read the text in the terminal, and can only tell that there's some text on the web page but can't even read the titles let alone the text.
  * As a result of the point above I ended up turning off my built-in monitor (and giving up on my HiDPI screen when I'm at home!) to test out that setup and manually edit the layout.css.devPixelsPerPx pref every time that I connect and disconnect to and from my external monitor.  This quickly becomes tiring since sometimes I disconnect my laptop to go to a different room for a few minutes and suddenly a pref flipping exercise is in order.  It also makes it very hard to actually work when I'm at the office where all of my local builds default to have the wrong pref value so every time I launch a local build, I can't read the text inside the page before I change the pref.
  * It also makes it impossible to switch the OS-wide DPI scaling factor to optimize for my eye's comfort level.  What really started my investigations into our code to try to figure out what we do to the scaling factor was to try to figure out if I can simply adjust the OS scaling factor (i.e., adjust *one* knob) according to my setup and have my entire desktop be in a state where I can read things comfortably.  The flipping between 1.2 and 1.375 was when I was trying to find what would be a good balance with regards to this, but the presence of this issue forcing me to edit this pref tens of times every day has been so draining that I've for now given up on optimizing the scaling factor for my viewing benefit and regularly find myself squinting or twisting my neck in order to be able to read text comfortably which isn't great.

(In reply to Karl Tomlinson (:karlt) from comment #7)
> These issues may not be obvious on your 280 dpi laptop screen (assuming
> 15.6"),
> but they are much more obvious on a true 115 or 120 dpi screen.

Fair enough.  FWIW I wrote the patch as the only solution to the problem I explained above that I could think of.  I'm certainly open to other solutions if you can think of them!

> Ehsan, I'd like to understand more about your situation as a case study.
> We need to weigh up the advantages of an additional step against the costs of
> poor rendering.  The goal is to pick defaults that give most people what they
> want and layout.css.devPixelsPerPx is available for those that are not happy
> with the defaults.

See above for the effectiveness of the pref in practice.  Perhaps people who run their own Firefox builds are rare, but is the pref an answer for people using multiple monitors?

> I'm surprised if a factor of only 1.2 makes the difference between
> comfortable
> and "extremely challenging", so I wonder whether there is piece of
> information
> or understanding I'm missing.

Note that the thing that makes reading the text extremely challenging is Firefox picking a scaling factor of 1 (IOW, not scaling the text.)  On a 4K monitor which is what my laptop has, it should be easy to believe that unscaled painted text on a web page should be unreadable in most cases.  I'd be happy to take screenshots of your favorite sites if you need examples.  :-)

Also, FWIW, I don't have the best eye sight among my peers, even wearing glasses, so perhaps some of this is subjective.  I knew someone who had no difficulty reading unscaled text on 4K screens, but exactly one person. :-)

> Is there another scale factor that has changed between these comments?
> What desktop environment is providing the other "native applications"?

This bug was filed when I was on XFCE.

> GTK scales only text (not icons or controls) on changing the dpi.
> It has a separate global scaling factor, but that accepts only integer
> values.  So I wonder whether you are looking at different native
> applications,
> or whether perhaps 1.2 has somehow triggered a jump to 2.
> 
> Does the UI in your desktop environment offer 1.2 (115.2 dpi) as one of a
> number of discrete scaling options, or are all fractions available?

This is from the XFCE appearance widget, the Fonts tab, the DPI section, with "Custom DPI settings" checked, and the value entered is 132.

> Unity apps may behave quite differently, but I don't know whether
> /com/ubuntu/user-interface/scale-factor supports non-integer multiples of
> 1/8.
> (1.2 is not an integer multiple of 1/8.)
> With Ubuntu moving to GNOME, following GTK behaviour becomes more important.

I'm not using Unity as far as I can tell.

(In reply to Karl Tomlinson (:karlt) from comment #9)
> (In reply to :Ehsan Akhgari (needinfo please, extremely long backlog) from
> comment #6)
> > [..] having to adjust the
> > layout.css.devPixelsPerPx pref each time I connect to my external Low-DPI
> > monitor.  :-)
> 
> Is the system dpi changing on connection of the external monitor?

How can I say?  Things look "right" on both my monitors, FWIW.

> If so, does the output from "xrdb -query | grep Xft.dpi" change?

This is the full output of xrdb -query for me:

*customization:	-color
XScreenSaver.newLoginCommand:	dm-tool switch-to-greeter
Xft.hinting:	1
Xft.hintstyle:	hintmedium
Flags: needinfo?(ehsan)
Priority: -- → P3
Thank you for the report, Ehsan! Like Ehsan, I'm a Linux user who has one non-HiDPI monitor a HiDPI one. I worked around this bug by using this legacy extension[1]. It couldn't be ported to a WebExtension, based on bug 1373607 comment 8.

There was also hope that the Gnome layer could fix it in 3.26 (bug 1373607 comment 9). Sadly for us, the fix hasn't made the default prefs (bug 1373607 comment 14). (When turned on, several apps, including Firefox are showing blurry on the HiDPI screen [2]).

Then, starting from Firefox 57, users won't have a way to automatically change the scaling factor when Firefox moves from a display to another. 

Milan, would you think that might change the priority of the bug?


[1] https://addons.mozilla.org/en-US/firefox/addon/autohidpi/
[2] https://bugzilla.gnome.org/show_bug.cgi?id=788040#c0
Flags: needinfo?(milan)
(In reply to :Ehsan Akhgari from comment #10)
> [...] but is the pref an answer for people using multiple monitors?

The pref is not expected to be a solution for multiple monitors of very
different pixel density.

I'm not aware of good solutions for this situation with GTK on X11.  Unity had
a solution, but there seems little point following that convention, if there
are no-longer desktop environments using that.  GTK on Wayland may have a
solution when the window scaling is an integer, but I haven't checked.

If the desktop environment provides a way for a app to pick up differing
settings when it moves between monitors, then that seems the ideal solution
here.  Bug 1228570 tracks that, but I don't know a convention to follow.

Firefox could implement support for different dpis on different monitors
through its own settings.

xrandr provides for scaling pixels differently on each monitor, which requires
no app support, but this is a poor quality solution that leads to blurry
output failure in subpixel aa.

However, I'm wondering whether you have simply found an intermediate scaling
factor that makes most apps look "great" on the external monitor and "OK" on
the laptop monitor.  If that's due to fine tuning providing text that is at
the larger end of acceptable ranges on one monitor and at the smaller end on
the other, then the pref is available as a similar solution.

I don't expect all web pages to be acceptable sizes at any single scaling
factor.  Authors pick widely varying sizes and so page zoom is intended to
resolve the inter-author problem.

> (In reply to Karl Tomlinson (:karlt) from comment #7)
> > I'm surprised if a factor of only 1.2 makes the difference between
> > comfortable and "extremely challenging", so I wonder whether there is
> > piece of information or understanding I'm missing.
> 
> Note that the thing that makes reading the text extremely challenging is
> Firefox picking a scaling factor of 1 (IOW, not scaling the text.)  On a 4K
> monitor which is what my laptop has, it should be easy to believe that
> unscaled painted text on a web page should be unreadable in most cases.

It is easy to believe that a scaling factor of 1 provides hard-to-read text on
a 4K laptop screen.

If it were only the laptop screen, however, then a scaling factor (whether
1.375 or larger) would provide a satisfactory solution.

IIUC your preferred scaling factor would be about 2 on the 4K laptop monitor,
but I'm confused because other apps look nice with much smaller scaling
factors (e.g. 1.2).  That makes me wonder whether or not the other apps are
rounding up to 2.

> > GTK scales only text (not icons or controls) on changing the dpi.
> > It has a separate global scaling factor, but that accepts only integer
> > values.  So I wonder whether you are looking at different native
> > applications,
> > or whether perhaps 1.2 has somehow triggered a jump to 2.
> > 
> > Does the UI in your desktop environment offer 1.2 (115.2 dpi) as one of a
> > number of discrete scaling options, or are all fractions available?
> 
> This is from the XFCE appearance widget, the Fonts tab, the DPI section,
> with "Custom DPI settings" checked, and the value entered is 132.

132 dpi is a scaling factor of 1.375 and Firefox would scale text at this
value.  At this value, is Firefox text too large on the external monitor and
too small on the laptop monitor, or something else?

> (In reply to Karl Tomlinson (:karlt) from comment #9)
> > Is the system dpi changing on connection of the external monitor?
> 
> How can I say?  Things look "right" on both my monitors, FWIW.

With a scaling that makes your terminal look "very comfortable" on the laptop
screen, if you were to take a screenshot of it and view the screenshot at
native resolution, and then drag the terminal to the other monitor and
view the screenshot at native resolution on the other monitor, then would the
screenshot and terminal still look the same on the other monitor?

If you enable and open gtk inspector [3], then what are the "Font Scale" and
"Window scaling" values in the "Visual" tab?  I suggest opening the inspector
on an GTK3 app that you are happy to crash, such as gtk3-demo.  I'm guessing
it usually works on Xfce terminal however.  Do these values change when
repeating on the other monitor?

[3] https://wiki.gnome.org/Projects/GTK+/Inspector
(In reply to Johan Lorenzo [:jlorenzo] from comment #11)
> ...
> 
> Milan, would you think that might change the priority of the bug?

Yeah, our current priorities system is somewhat confusing where P1 and P2 are used for scheduling.  Let's see how far Ehsan gets with this patch.
Flags: needinfo?(milan)
You need to log in before you can comment on or make changes to this bug.