Skip to content

macos: correctly handles custom retina cursors

Lukas Oberhuber requested to merge lukaso/gtk:fix-retina-cursors into gtk-3-24

This change correctly sizes HiDPI custom cursors on macOS.

Before this patch, hi-res (HiDPI/Retina) custom cursors appear double the size on hi-res (Retina) screens. This is double the size of the same custom cursors on regular-res screens.

Based in part on this comment: #613 (comment 687914)

NB: The custom hi-res cursor must be created using a surface with the scale factor set. MacOS (and I believe all of Gtk3) only support scale factors of 1 and 2.

Testing

This has been tested using Gimp 2.99 (which has hi-res custom cursors built in) with and without the patch. Testing was done on a dual monitor Macbook Pro 16" setup running Monterey where one external monitor is regular-res and the other is hi-res (retina).

Gimp correctly chooses a custom cursor depending on the screen scale (regular-res custom cursor on the regular-res monitor and hi-res custom cursor with a surface with the scale set to 2 on the retina monitor). This is done each time the Gimp main window switches monitors. [Verified using the debugger.]

Before this patch is applied, on the retina display only, custom cursors appear as double size. The custom cursors look correct on the regular-res monitor (the hi-res custom cursors are only passed into Gtk when the scale factor is 2 -- aka hi-res).

After this patch, the custom cursors appear correctly on the hi-res monitor as well as the regular res monitor (the correct image is used in each case, and the correct scaling is applied in each case).

The gimp code that uses this facility is here. It chooses the custom cursor artwork based on the scale factor for the current screen/monitor.

Here is where the artwork is loaded: https://gitlab.gnome.org/GNOME/gimp/-/blob/master/app/widgets/gimpcursor.c#L223-283 and where (if needed) a pixbuf is prepared at 2x size using 2x artwork.

This artwork is used here (in the hi-res case as a surface): https://gitlab.gnome.org/GNOME/gimp/-/blob/master/app/widgets/gimpcursor.c#L452-463

Hotspots

Cursors have hotspots, which is the exact pixel where the cursor points. With the patch in place, it is necessary to pass in a hotspot that is also scaled up 2x compared to the normal-res hotspot (multiply the hotspot coordinates by the scale factor).

The patch then scales the hotspot down as well. This is consistent with the implementation in the wayland Gtk back end, but is a choice.

Screenshots

Note: MacOS screenshot tool did not want to place the cursor where the cursor was on the screen, so they are far down the screen.

Normal cursor on retina display

normal_cursor_on_retina

Custom hi-res cursor on retina display before patch

custom_cursor_before_patch_applied

Custom hi-res cursor on retina display after patch is applied

custom_cursor_after_patch_applied

Edited by Lukas Oberhuber

Merge request reports