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 window The window to get an icon for
* @param size The size of the icon * @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 * @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 * 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 * @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; Gdk.Pixbuf? result = null;
var xid_key = "%u::%i".printf (xid, size); var xid_key = "%u::%i".printf (xid, size);
@ -109,7 +110,7 @@ namespace Gala
return result; return result;
var app = Bamf.Matcher.get_default ().get_application_for_xid (xid); 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); xid_pixbuf_cache.set (xid_key, result);
@ -121,7 +122,7 @@ namespace Gala
* *
* @see get_icon_for_window * @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) bool ignore_cache = false)
{ {
Gdk.Pixbuf? image = null; Gdk.Pixbuf? image = null;
@ -134,9 +135,11 @@ namespace Gala
var appinfo = new DesktopAppInfo.from_filename (app.get_desktop_file ()); var appinfo = new DesktopAppInfo.from_filename (app.get_desktop_file ());
if (appinfo != null) { if (appinfo != null) {
icon = Plank.DrawingService.get_icon_from_gicon (appinfo.get_icon ()); 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) { 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; not_cached = true;
} }
} }
@ -146,9 +149,9 @@ namespace Gala
try { try {
unowned Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default (); unowned Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default ();
icon = "application-default-icon"; 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) { 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; not_cached = true;
} }
} catch (Error e) { } catch (Error e) {
@ -166,8 +169,8 @@ namespace Gala
} }
} }
if (size != image.width || size != image.height) if (size * scale != image.width || size * scale != image.height)
image = Plank.DrawingService.ar_scale (image, size, size); image = Plank.DrawingService.ar_scale (image, size * scale, size * scale);
if (not_cached) if (not_cached)
icon_pixbuf_cache.set (icon_key, image); icon_pixbuf_cache.set (icon_key, image);

View File

@ -33,6 +33,7 @@ namespace Gala
public Meta.Window window { get; construct; } public Meta.Window window { get; construct; }
public int icon_size { 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 * 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 window The window for which to create the icon
* @param icon_size The size of the icon in pixels * @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 * @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, Object (window: window,
icon_size: icon_size, icon_size: icon_size,
destroy_on_unmanaged: destroy_on_unmanaged); destroy_on_unmanaged: destroy_on_unmanaged,
scale: scale);
} }
construct construct
{ {
width = icon_size; width = icon_size * scale;
height = icon_size; height = icon_size * scale;
xid = (uint32) window.get_xwindow (); xid = (uint32) window.get_xwindow ();
// new windows often reach mutter earlier than bamf, that's why // new windows often reach mutter earlier than bamf, that's why
@ -112,7 +115,7 @@ namespace Gala
void update_texture (bool initial) 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 { try {
set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (), set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (),

View File

@ -550,5 +550,14 @@ namespace Gala
result.reverse (); result.reverse ();
return result; 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; Plank.DockPreferences dock_settings;
float dock_y_offset; float dock_y_offset;
float dock_height_offset; float dock_height_offset;
int ui_scale_factor = 1;
FileMonitor monitor; FileMonitor monitor;
Actor background; Actor background;
@ -77,6 +78,8 @@ namespace Gala
update_n_dock_items (launcher_folder, null, FileMonitorEvent.CREATED); update_n_dock_items (launcher_folder, null, FileMonitorEvent.CREATED);
} }
ui_scale_factor = InternalUtils.get_ui_scaling_factor ();
dock = new Actor (); dock = new Actor ();
dock.layout_manager = new BoxLayout (); dock.layout_manager = new BoxLayout ();
@ -136,14 +139,14 @@ namespace Gala
var layout = (BoxLayout) dock.layout_manager; var layout = (BoxLayout) dock.layout_manager;
var position = dock_settings.Position; 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 scaled_icon_size = icon_size / 10.0f;
var horizontal = dock_settings.is_horizontal_dock (); var horizontal = dock_settings.is_horizontal_dock ();
var top_padding = (float) dock_theme.TopPadding * scaled_icon_size; var top_padding = (float) dock_theme.TopPadding * scaled_icon_size;
var bottom_padding = (float) dock_theme.BottomPadding * scaled_icon_size; var bottom_padding = (float) dock_theme.BottomPadding * scaled_icon_size;
var item_padding = (float) dock_theme.ItemPadding * 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 top_offset = 2 * line_width + top_padding;
var bottom_offset = (dock_theme.BottomRoundness > 0 ? 2 * line_width : 0) + bottom_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) { 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 ()); 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; float x = 0, y = 0;
@ -234,7 +237,7 @@ namespace Gala
x = dock_y_offset; x = dock_y_offset;
break; break;
case Gtk.PositionType.BOTTOM: case Gtk.PositionType.BOTTOM:
y = dock_y_offset; y = dock_y_offset / ui_scale_factor;
break; break;
case Gtk.PositionType.LEFT: case Gtk.PositionType.LEFT:
x = 0; x = 0;
@ -244,17 +247,22 @@ namespace Gala
break; break;
} }
cr.save ();
cr.scale (ui_scale_factor, ui_scale_factor);
cr.set_source_surface (dock_surface.Internal, x, y); cr.set_source_surface (dock_surface.Internal, x, y);
cr.paint (); cr.paint ();
cr.restore ();
return false; return false;
} }
void place_dock () 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 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 horiz_padding = dock_theme.HorizPadding * scaled_icon_size;
var item_padding = (float) dock_theme.ItemPadding * 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)); var items_offset = (int) (2 * line_width + (horiz_padding > 0 ? horiz_padding : 0));
@ -552,7 +560,7 @@ namespace Gala
window_clones.add_child (clone); 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.reactive = true;
icon.opacity = 100; icon.opacity = 100;
icon.x_expand = true; icon.x_expand = true;