diff --git a/lib/Utils.vala b/lib/Utils.vala index fa77fbd8..04d96694 100644 --- a/lib/Utils.vala +++ b/lib/Utils.vala @@ -87,12 +87,13 @@ namespace Gala * * @param window The window to get an icon for * @param size The size of the icon + * @param scale The desired scale of the icon * @param ignore_cache Should not be necessary in most cases, if you care about the icon * being loaded correctly, you should consider using the WindowIcon class */ - public static Gdk.Pixbuf get_icon_for_window (Meta.Window window, int size, bool ignore_cache = false) + public static Gdk.Pixbuf get_icon_for_window (Meta.Window window, int size, int scale = 1, bool ignore_cache = false) { - return get_icon_for_xid ((uint32)window.get_xwindow (), size, ignore_cache); + return get_icon_for_xid ((uint32)window.get_xwindow (), size, scale, ignore_cache); } /** @@ -100,7 +101,7 @@ namespace Gala * * @see get_icon_for_window */ - public static Gdk.Pixbuf get_icon_for_xid (uint32 xid, int size, bool ignore_cache = false) + public static Gdk.Pixbuf get_icon_for_xid (uint32 xid, int size, int scale = 1, bool ignore_cache = false) { Gdk.Pixbuf? result = null; var xid_key = "%u::%i".printf (xid, size); @@ -109,7 +110,7 @@ namespace Gala return result; var app = Bamf.Matcher.get_default ().get_application_for_xid (xid); - result = get_icon_for_application (app, size, ignore_cache); + result = get_icon_for_application (app, size, scale, ignore_cache); xid_pixbuf_cache.set (xid_key, result); @@ -121,7 +122,7 @@ namespace Gala * * @see get_icon_for_window */ - static Gdk.Pixbuf get_icon_for_application (Bamf.Application? app, int size, + static Gdk.Pixbuf get_icon_for_application (Bamf.Application? app, int size, int scale = 1, bool ignore_cache = false) { Gdk.Pixbuf? image = null; @@ -134,9 +135,11 @@ namespace Gala var appinfo = new DesktopAppInfo.from_filename (app.get_desktop_file ()); if (appinfo != null) { icon = Plank.DrawingService.get_icon_from_gicon (appinfo.get_icon ()); - icon_key = "%s::%i".printf (icon, size); + icon_key = "%s::%i::%i".printf (icon, size, scale); if (ignore_cache || (image = icon_pixbuf_cache.get (icon_key)) == null) { - image = Plank.DrawingService.load_icon (icon, size, size); + var scaled_size = size * scale; + var surface = Plank.DrawingService.load_icon_for_scale (icon, scaled_size, scaled_size, scale); + image = Gdk.pixbuf_get_from_surface (surface, 0, 0, scaled_size, scaled_size); not_cached = true; } } @@ -146,9 +149,9 @@ namespace Gala try { unowned Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default (); icon = "application-default-icon"; - icon_key = "%s::%i".printf (icon, size); + icon_key = "%s::%i::%i".printf (icon, size, scale); if ((image = icon_pixbuf_cache.get (icon_key)) == null) { - image = icon_theme.load_icon (icon, size, 0); + image = icon_theme.load_icon_for_scale (icon, size, scale, 0); not_cached = true; } } catch (Error e) { @@ -166,8 +169,8 @@ namespace Gala } } - if (size != image.width || size != image.height) - image = Plank.DrawingService.ar_scale (image, size, size); + if (size * scale != image.width || size * scale != image.height) + image = Plank.DrawingService.ar_scale (image, size * scale, size * scale); if (not_cached) icon_pixbuf_cache.set (icon_key, image); diff --git a/lib/WindowIcon.vala b/lib/WindowIcon.vala index 9ec45aa8..3171d0cd 100644 --- a/lib/WindowIcon.vala +++ b/lib/WindowIcon.vala @@ -33,6 +33,7 @@ namespace Gala public Meta.Window window { get; construct; } public int icon_size { get; construct; } + public int scale { get; construct; } /** * If set to true, the SafeWindowClone will destroy itself when the connected @@ -63,19 +64,21 @@ namespace Gala * * @param window The window for which to create the icon * @param icon_size The size of the icon in pixels + * @param scale The desired scale of the icon * @param destroy_on_unmanaged see destroy_on_unmanaged property */ - public WindowIcon (Meta.Window window, int icon_size, bool destroy_on_unmanaged = false) + public WindowIcon (Meta.Window window, int icon_size, int scale = 1, bool destroy_on_unmanaged = false) { Object (window: window, icon_size: icon_size, - destroy_on_unmanaged: destroy_on_unmanaged); + destroy_on_unmanaged: destroy_on_unmanaged, + scale: scale); } construct { - width = icon_size; - height = icon_size; + width = icon_size * scale; + height = icon_size * scale; xid = (uint32) window.get_xwindow (); // new windows often reach mutter earlier than bamf, that's why @@ -112,7 +115,7 @@ namespace Gala void update_texture (bool initial) { - var pixbuf = Gala.Utils.get_icon_for_xid (xid, icon_size, !initial); + var pixbuf = Gala.Utils.get_icon_for_xid (xid, icon_size, scale, !initial); try { set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (), diff --git a/src/InternalUtils.vala b/src/InternalUtils.vala index 4da20498..7fe6db15 100644 --- a/src/InternalUtils.vala +++ b/src/InternalUtils.vala @@ -550,5 +550,14 @@ namespace Gala result.reverse (); return result; }*/ + + public static int get_ui_scaling_factor () + { +#if HAS_MUTTER326 + return Meta.Backend.get_backend ().get_settings ().get_ui_scaling_factor (); +#else + return 1; +#endif + } } } diff --git a/src/Widgets/WindowSwitcher.vala b/src/Widgets/WindowSwitcher.vala index b00a68a9..f97ae56c 100644 --- a/src/Widgets/WindowSwitcher.vala +++ b/src/Widgets/WindowSwitcher.vala @@ -40,6 +40,7 @@ namespace Gala Plank.DockPreferences dock_settings; float dock_y_offset; float dock_height_offset; + int ui_scale_factor = 1; FileMonitor monitor; Actor background; @@ -77,6 +78,8 @@ namespace Gala update_n_dock_items (launcher_folder, null, FileMonitorEvent.CREATED); } + ui_scale_factor = InternalUtils.get_ui_scaling_factor (); + dock = new Actor (); dock.layout_manager = new BoxLayout (); @@ -136,14 +139,14 @@ namespace Gala var layout = (BoxLayout) dock.layout_manager; var position = dock_settings.Position; - var icon_size = dock_settings.IconSize; + var icon_size = dock_settings.IconSize * ui_scale_factor; var scaled_icon_size = icon_size / 10.0f; var horizontal = dock_settings.is_horizontal_dock (); var top_padding = (float) dock_theme.TopPadding * scaled_icon_size; var bottom_padding = (float) dock_theme.BottomPadding * scaled_icon_size; var item_padding = (float) dock_theme.ItemPadding * scaled_icon_size; - var line_width = dock_theme.LineWidth; + var line_width = dock_theme.LineWidth * ui_scale_factor; var top_offset = 2 * line_width + top_padding; var bottom_offset = (dock_theme.BottomRoundness > 0 ? 2 * line_width : 0) + bottom_padding; @@ -225,7 +228,7 @@ namespace Gala if (dock_surface == null || dock_surface.Width != width || dock_surface.Height != height) { var dummy_surface = new Plank.Surface.with_cairo_surface (1, 1, cr.get_target ()); - dock_surface = dock_theme.create_background (width, height, position, dummy_surface); + dock_surface = dock_theme.create_background (width / ui_scale_factor, height / ui_scale_factor, position, dummy_surface); } float x = 0, y = 0; @@ -234,7 +237,7 @@ namespace Gala x = dock_y_offset; break; case Gtk.PositionType.BOTTOM: - y = dock_y_offset; + y = dock_y_offset / ui_scale_factor; break; case Gtk.PositionType.LEFT: x = 0; @@ -244,17 +247,22 @@ namespace Gala break; } + cr.save (); + cr.scale (ui_scale_factor, ui_scale_factor); cr.set_source_surface (dock_surface.Internal, x, y); cr.paint (); + cr.restore (); return false; } void place_dock () { - var icon_size = dock_settings.IconSize; + ui_scale_factor = InternalUtils.get_ui_scaling_factor (); + + var icon_size = dock_settings.IconSize * ui_scale_factor; var scaled_icon_size = icon_size / 10.0f; - var line_width = dock_theme.LineWidth; + var line_width = dock_theme.LineWidth * ui_scale_factor; var horiz_padding = dock_theme.HorizPadding * scaled_icon_size; var item_padding = (float) dock_theme.ItemPadding * scaled_icon_size; var items_offset = (int) (2 * line_width + (horiz_padding > 0 ? horiz_padding : 0)); @@ -552,7 +560,7 @@ namespace Gala window_clones.add_child (clone); - var icon = new WindowIcon (window, dock_settings.IconSize, true); + var icon = new WindowIcon (window, dock_settings.IconSize, ui_scale_factor, true); icon.reactive = true; icon.opacity = 100; icon.x_expand = true;