Skip to content

lua: render button images HiDPI-aware and size them to the line height - #22229

Open
andriiryzhkov wants to merge 2 commits into
darktable-org:masterfrom
andriiryzhkov:lua_button_image_hidpi
Open

lua: render button images HiDPI-aware and size them to the line height#22229
andriiryzhkov wants to merge 2 commits into
darktable-org:masterfrom
andriiryzhkov:lua_button_image_hidpi

Conversation

@andriiryzhkov

@andriiryzhkov andriiryzhkov commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Lua's button.image went straight to gtk_image_new_from_file(), which decodes at logical resolution and lays the result out at whatever size the file happens to be. On a HiDPI screen every script icon is upscaled and soft, and a 512px PNG makes a 512px-tall button. Scripts work around it by shipping small fixed-size PNGs, which then stay small when the interface font grows.

This decodes the file at darktable.gui->ppd device resolution, sized against the button's own line height so the icon tracks the font, and hands GTK a cairo surface with the matching device scale. An SVG renders at the size asked for; a raster is capped at its native size. Animated files are left to gtk_image_new_from_file(), since a single pixbuf would freeze them on the first frame.

ppd rather than gtk_widget_get_scale_factor(), because the button is usually still unparented here and GTK then answers for monitor 0. The derived device scale is nudged one ulp up: GTK sizes an image as ceil(pixels / device_scale) and cairo inverts the scale rather than dividing by it, so without the nudge an exact ratio can gain a pixel. Both ppd and the line height are sampled once, so an icon keeps the resolution it was built with until the script assigns it again – I could be argued out of that.

The companion change is lua-scripts#715, switching the script manager's icons from 20px PNGs to SVG. Neither breaks without the other, but the icons only look right with both.

Screenshots with both PRs applied:

Before:
sm_before

After:
sm_after

Written with AI assistance.

Scripts set a button image by file name and the widget handed it to
gtk_image_new_from_file(), which ignores the scale factor, so on HiDPI
the bitmap was stretched blurry and its fixed pixel size never matched
the font-relative icons around it.

Decode through a pixbuf at device resolution and hand GTK a surface
carrying the scale. A raster is capped at its own size since upscaling
only blurs it; an svg is not, because the size reported for it is just
the nominal one from its attributes.
@wpferguson

wpferguson commented Sep 10, 2026

Copy link
Copy Markdown
Member

My plan for a solution was to use darktable cairo buttons so that we didn't have to include extra files.

EDIT: and then the buttons would match all the other ones in darktable.

EDIT 2: #16792

@andriiryzhkov

Copy link
Copy Markdown
Collaborator Author

@wpferguson : That would be a good solution, especially for script manager. Indeed my primary motivation was to fix existing button icons in script manager. But this fix can also be useful for someone wanting to use buttons with icons from either PNG or SVG file. I mean this fix and cairo icons and happily coexist.

Anyway, you can keep this option until you come up with cairo icons implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants