Hacker News new | ask | show | jobs
by smallstepforman 840 days ago
Haiku OS in my opinion solves this better by basing everything on default font size (in pixels). Eg it defaults to 12px, I used 20px for a 3840x2160 monitor. Some GUI widgets scale based on this. All text (when using be_default_font) scale based on this. Spacing / layout depends on this. The key difference (compared to a global x1.5 scaling factor) is that developers of each app decide how to use this information, so different parts of the GUI are scaled disproportionatily. Sloppy apps ignore this, but the devs are quickly notified. So you end up with text larger but GUI widgets can grow dis-proportionatily, so you can fine tune what is 125%, 150%, etc. Eg. ScrollBar can be 125%, toolbar 150%, text 233%. Haiku has had this since the beginning (even BeOS in the 90’s had this). By 2024, almost all non compliant apps have been fixed and support this.

What Haiku needs is font setting per screen/resolution for multimonitor support. This way you can support mismatched monitors with different factors.

6 comments

This sounds very much like using `em` units in CSS. 1em = the width of the letter "m". So it scales proportionally to font size.

Relative units like this are usually considered best practice, because of the exact reasons that you've listed.

In user dialogs, Windows does/used to do that, too. https://learn.microsoft.com/en-us/windows/win32/api/winuser/...:

“The horizontal base unit returned by GetDialogBaseUnits is equal to the average width, in pixels, of the characters in the system font; the vertical base unit is equal to the height, in pixels, of the font.

The system font is used only if the dialog box template fails to specify a font. Most dialog box templates specify a font; as a result, this function is not useful for most dialog boxes.

For a dialog box that does not use the system font, the base units are the average width and height, in pixels, of the characters in the dialog's font. You can use the GetTextMetrics and GetTextExtentPoint32 functions to calculate these values for a selected font. However, by using the MapDialogRect function, you can avoid errors that might result if your calculations differ from those performed by the system.”

The real issue is that people want to be able to smoothly drag windows across monitors. This requires that each window be able to switch to a different DPI scaling when its "home" monitor changes. Something must also be done to deal with a single window being displayed across monitors with different resolution (which is what happens while dragging) though hardware scaling is probably acceptable there at some minor loss in quality - the "proper" alternative is to render natively at both resolutions, but applications might not natively support that.
My Macbook doesn't (always) drag smoothly across monitors. And I don't think anyone really complains about it?
This works seamlessly on Windows. My 1920×1080 15.6-inch laptop display is at 125%, and my 3840×2160 27-inch monitor is at 175%. Move a window between both, and the size automatically snaps to whichever monitor contains more than 50% of the window.
That isn't seamless - windows has many different was to handle HiDPI, and for a few of them, the window will violently change size as it moves across and will look completely wrong on the "unmatched" monitor, to the point of being completely useless on that monitor (way too big to see anything or way too small to read anything).

What Wayland is doing is making it so the window looks the same size on all screens, with the source matching the primary or highest dpi monitor, and the composite scaling the content to match other monitors. This makes it equally useful on all monitors, at the cost of non-primary monitors having lower clarity.

macOS handles it well by cheating: a window can only be shown on one monitor at any given time. Only while moving a window will it temporarily be allowed to be seen on two monitors at once.

counterpoint: a little bit of cheating here is not a bad thing.
This is similar to how Win32/GDI layout guidelines (pre-win 10) worked.

Windows says reference font dpi is 72 and reference sizes for buttons, list, labels, etc is specified at 96 dpi, then you're supposed to use actual dpi/ref_dpi and scale things according to that.

Then you set DPI scaling per monitor v2 in manifest.xml and catch WM_DPICHANGED message and recompute scale factors and presto, perfect dpi scaling across any monitor at any fractional scale.

Made me think of this for some reason:

https://building.enlyze.com/posts/targeting-25-years-of-wind...

Target from NT4 (up to Windows 11, I suppose) with LLVM and Visual Studio.

Say your UI had a one "pixel" wide vertical line. At some point, resolution becomes high enough that you need to draw it two device pixels wide. What do you do at scales in-between?

Do apps start drawing their lines wider if the default font size goes up? When? Is it consistent system wide?

not an expert in this subject, but I believe subpixel rendering is the broad category of solution https://en.m.wikipedia.org/wiki/Subpixel_rendering

further, the “pixel” unit widely used today is quite far removed from physical pixels on consumer devices and is more similar to an abstracted “point” unit - for example, apple alone supports devices at 1x, 2x, and 3x resolutions (or pixel densities)

> So you end up with text larger but GUI widgets can grow dis-proportionatily, so you can fine tune what is 125%, 150%, etc. Eg. ScrollBar can be 125%, toolbar 150%, text 233%

Who’s the “you” in here? If it’s the end user, I don’t think it’s a better solution for the general population.

This is a very good idea
This is a bad idea because:

> Sloppy apps ignore this, but the devs are quickly notified.

Anything that increases friction for developers is bad. The API for HiDPI should be so seamless that the only thing developer does is to provide higher resolution bitmap icons.

Imagine what web app developers need to do when their users switch from a regular display to a HiDPI display. They do nothing; the browser knows how to scale on its down. And that should be the bar we are aiming for.