Make window-switcher compatible with HiDPI (#154)

This commit is contained in:
David Hewitt 2018-02-14 20:17:31 +00:00 committed by Rico Tzschichholz
parent c0eb426f81
commit e39e5591da
4 changed files with 46 additions and 23 deletions

View File

@ -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);

View File

@ -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 (),

View File

@ -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
}
}
}

View File

@ -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;