====== Supporting UI Scaling ====== GTK3 and above support integer scaling of UI components, most useful on HiDPI screens. In Xfce, this can be set in the Appearance settings panel. GTK3 will handle drawing widgets and windows at the new scale automatically, but care has to be taken to supply it with images and icons properly in order for them to be displayed at the correct resolution, without being blurry. ===== Basics ===== * Use ''gtk_widget_get_scale_factor()'' to get the scale factor. * If you don't have a widget handy, but for some reason have a ''GdkWindow'', you can use ''gdk_window_get_scale_factor()''. * If you don't even have a window, you can use ''gdk_monitor_get_scale_factor()''. * Scale factors are (unfortunately) integer-only. There's no such thing as a 1.5x scale, for example. * You can connect to ''notify::scale-factor'' on a ''GtkWidget'' or ''GdkMonitor'' instance to know when you might need to reload icons at a new scale factor. ===== Things that work ===== * Any manually-loaded ''GdkPixbuf'' instances should be loaded at a width and height multiplied by the scale factor. Then, "wrap" the pixbuf in a ''cairo_surface_t'' using ''gdk_cairo_surface_create_from_pixbuf()'', which takes the scale factor. It can also take a ''GdkWindow'', but it's fine to pass ''NULL'' there. * When loading themed icons, use the ''_for_scale()'' variants: ''gtk_icon_theme_lookup_icon_for_scale()'', ''gtk_icon_theme_load_icon_for_scale()'', and ''gtk_icon_theme_lookup_by_gicon_for_scale()''. Pass the unscaled size for the ''size'' parameter, and the UI scale factor for the ''scale'' parameter. I also recommend passing ''GTK_ICON_LOOKUP_FORCE_SIZE''. * ''GIcon'' is a useful alternative in cases where it's awkward to pass around a scale factor (for example, in a ''GtkTreeModel'' implementation, the model shouldn't really know "view" details like the UI scale factor). ''GIcon'' has quite a few implementation types, like ''GFileIcon'', ''GThemedIcon'', and ''GEmblemedIcon''. Even ''GdkPixbuf'' implements ''GIcon''. There's also ''GLoadableIcon'', which you can fairly easily implement if you need to do something custom. * If using ''GIcon'' with ''GtkImage'', you can get arbitrary sizing (that is, other sizes beyond what ''GTK_ICON_SIZE_'' offers) by using ''gtk_image_set_pixel_size()''. The code in ''GtkImage'' ignores the ''GTK_ICON_SIZE_'' sizes if the pixel size is specified. For the pixel size, you want to specify the unscaled size. * Most things that take a themed icon name will automatically handle the scale factor internally. * Many things that take ''GdkPixbuf'' will also take ''GIcon'' or ''cairo_surface_t'', so look for another function variant when replacing existing calls. ===== Things that are problematic ===== * Loading ''GdkPixbuf'' instances manually will result in blurry icons without specifically handling the scale factor. * ''GIcon'' and ''GtkCellRendererPixbuf'' work ok if you are only using "standard" GTK icon sizes (that is, the ''GTK_ICON_SIZE_'' enum values). That should usually be fine for things like ''GtkTreeView'', but might not work well for ''GtkIconView'', as those size types max out at 48x48. * Don't try to "outsmart" ''GtkIconTheme'' by writing your own size selection and loading code. ''GtkIconTheme'' will nearly always do the right thing, and handles a lot of the complex rules that can be encoded into an ''index.theme'' file. Working around this can give results that aren't true to what the icon theme authors intended.