Skip to content

Commit 3ed7f90

Browse files
committed
Use Gala.Icon for WindowIcon
1 parent bef8836 commit 3ed7f90

File tree

3 files changed

+52
-102
lines changed

3 files changed

+52
-102
lines changed

lib/Icon.vala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@
66
*/
77

88
public class Gala.Icon : Clutter.Actor {
9+
private class GIconSource : Object, IconSource {
10+
private static Gtk.IconTheme icon_theme = new Gtk.IconTheme () {
11+
theme_name = "elementary"
12+
};
13+
14+
public GLib.Icon gicon { get; construct; }
15+
16+
public GIconSource (GLib.Icon gicon) {
17+
Object (gicon: gicon);
18+
}
19+
20+
public string? get_cache_key (int size, float scale) {
21+
var gicon_str = gicon.to_string ();
22+
return gicon_str != null ? "gicon-%s-%d-%f".printf (gicon_str, size, scale) : null;
23+
}
24+
25+
public Gdk.Pixbuf create_pixbuf (int size, float scale) throws Error {
26+
var icon_paintable = icon_theme.lookup_by_gicon (gicon, size, (int) Math.ceilf (scale), NONE, 0);
27+
28+
var file = icon_paintable?.file;
29+
if (file == null) {
30+
throw new IOError.FAILED ("Icon paintable has no file");
31+
}
32+
33+
return new Gdk.Pixbuf.from_stream_at_scale (file.read (), -1, get_texture_size (size, scale), true);
34+
}
35+
}
36+
937
private class ResourceIconSource : Object, IconSource {
1038
public string path { get; construct; }
1139

@@ -41,6 +69,7 @@ public class Gala.Icon : Clutter.Actor {
4169
public float monitor_scale { get; construct set; }
4270

4371
public string resource_path { set { source = new ResourceIconSource (value); } }
72+
public GLib.Icon gicon { set { source = new GIconSource (value); } }
4473

4574
private IconSource _source;
4675
private IconSource source {
@@ -51,6 +80,10 @@ public class Gala.Icon : Clutter.Actor {
5180
}
5281
}
5382

83+
public Icon (int icon_size, float monitor_scale) {
84+
Object (icon_size: icon_size, monitor_scale: monitor_scale);
85+
}
86+
5487
public Icon.from_resource (int icon_size, float monitor_scale, string resource_path) {
5588
Object (icon_size: icon_size, monitor_scale: monitor_scale, resource_path: resource_path);
5689
}

lib/Utils.vala

Lines changed: 13 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,9 @@ namespace Gala {
1919
public class Utils {
2020
public const int BUTTON_SIZE = 36;
2121

22-
private struct CachedIcon {
23-
public Gdk.Pixbuf icon;
24-
public int icon_size;
25-
public int scale;
26-
}
27-
2822
private static Gee.HashMap<int, Gdk.Pixbuf?>? resize_pixbufs = null;
2923

30-
private static Gee.HashMultiMap<DesktopAppInfo, CachedIcon?> icon_cache;
3124
private static Gee.HashMap<Meta.Window, DesktopAppInfo> window_to_desktop_cache;
32-
private static Gee.ArrayList<CachedIcon?> unknown_icon_cache;
3325

3426
private static AppCache app_cache;
3527

@@ -40,27 +32,24 @@ namespace Gala {
4032
theme_name = "elementary"
4133
};
4234

43-
icon_cache = new Gee.HashMultiMap<DesktopAppInfo, CachedIcon?> ();
4435
window_to_desktop_cache = new Gee.HashMap<Meta.Window, DesktopAppInfo> ();
45-
unknown_icon_cache = new Gee.ArrayList<CachedIcon?> ();
4636

4737
app_cache = new AppCache ();
4838
app_cache.changed.connect (() => {
49-
icon_cache.clear ();
5039
window_to_desktop_cache.clear ();
5140
});
5241
}
5342

54-
public static Gdk.Pixbuf get_icon_for_window (Meta.Window window, int icon_size, int scale) {
43+
public static GLib.Icon get_icon_for_window (Meta.Window window) {
5544
var transient_for = window.get_transient_for ();
5645
if (transient_for != null) {
57-
return get_icon_for_window (transient_for, icon_size, scale);
46+
return get_icon_for_window (transient_for);
5847
}
5948

6049
GLib.DesktopAppInfo? desktop_app = null;
6150
desktop_app = window_to_desktop_cache[window];
6251
if (desktop_app != null) {
63-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
52+
var icon = desktop_app.get_icon ();
6453
if (icon != null) {
6554
return icon;
6655
}
@@ -71,7 +60,7 @@ namespace Gala {
7160
var wm_instance = window.get_wm_class_instance ();
7261
desktop_app = app_cache.lookup_startup_wmclass (wm_instance);
7362
if (desktop_app != null && check_app_prefix (desktop_app, sandbox_id)) {
74-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
63+
var icon = desktop_app.get_icon ();
7564
if (icon != null) {
7665
window_to_desktop_cache[window] = desktop_app;
7766
return icon;
@@ -81,7 +70,7 @@ namespace Gala {
8170
var wm_class = window.get_wm_class ();
8271
desktop_app = app_cache.lookup_startup_wmclass (wm_class);
8372
if (desktop_app != null && check_app_prefix (desktop_app, sandbox_id)) {
84-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
73+
var icon = desktop_app.get_icon ();
8574
if (icon != null) {
8675
window_to_desktop_cache[window] = desktop_app;
8776
return icon;
@@ -90,7 +79,7 @@ namespace Gala {
9079

9180
desktop_app = lookup_desktop_wmclass (wm_instance);
9281
if (desktop_app != null && check_app_prefix (desktop_app, sandbox_id)) {
93-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
82+
var icon = desktop_app.get_icon ();
9483
if (icon != null) {
9584
window_to_desktop_cache[window] = desktop_app;
9685
return icon;
@@ -99,7 +88,7 @@ namespace Gala {
9988

10089
desktop_app = lookup_desktop_wmclass (wm_class);
10190
if (desktop_app != null && check_app_prefix (desktop_app, sandbox_id)) {
102-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
91+
var icon = desktop_app.get_icon ();
10392
if (icon != null) {
10493
window_to_desktop_cache[window] = desktop_app;
10594
return icon;
@@ -108,7 +97,7 @@ namespace Gala {
10897

10998
desktop_app = get_app_from_id (sandbox_id);
11099
if (desktop_app != null) {
111-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
100+
var icon = desktop_app.get_icon ();
112101
if (icon != null) {
113102
window_to_desktop_cache[window] = desktop_app;
114103
return icon;
@@ -118,7 +107,7 @@ namespace Gala {
118107
var gapplication_id = window.get_gtk_application_id ();
119108
desktop_app = get_app_from_id (gapplication_id);
120109
if (desktop_app != null) {
121-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
110+
var icon = desktop_app.get_icon ();
122111
if (icon != null) {
123112
window_to_desktop_cache[window] = desktop_app;
124113
return icon;
@@ -144,7 +133,7 @@ namespace Gala {
144133
});
145134

146135
if (desktop_app != null) {
147-
var icon = get_icon_for_desktop_app_info (desktop_app, icon_size, scale);
136+
var icon = desktop_app.get_icon ();
148137
if (icon != null) {
149138
window_to_desktop_cache[window] = desktop_app;
150139
return icon;
@@ -153,34 +142,9 @@ namespace Gala {
153142
}
154143
}
155144

156-
// Haven't been able to get an icon for the window at this point, look to see
157-
// if we've already cached "application-default-icon" at this size
158-
foreach (var icon in unknown_icon_cache) {
159-
if (icon.icon_size == icon_size && icon.scale == scale) {
160-
return icon.icon;
161-
}
162-
}
163-
164-
// Construct a new "application-default-icon" and store it in the cache
165-
try {
166-
var icon_paintable = icon_theme.lookup_icon (
167-
"application-default-icon",
168-
null,
169-
icon_size,
170-
scale,
171-
Gtk.TextDirection.NONE,
172-
0
173-
);
174-
175-
var pixbuf = new Gdk.Pixbuf.from_file (icon_paintable.get_file ().get_path ());
176-
177-
unknown_icon_cache.add (CachedIcon () { icon = pixbuf, icon_size = icon_size, scale = scale });
178-
return pixbuf;
179-
} catch (Error e) {
180-
var icon = new Gdk.Pixbuf (Gdk.Colorspace.RGB, true, 8, icon_size * scale, icon_size * scale);
181-
icon.fill (0x00000000);
182-
return icon;
183-
}
145+
// Haven't been able to get an icon for the window at this point,
146+
// return a default icon
147+
return new ThemedIcon ("application-default-icon");
184148
}
185149

186150
private static bool check_app_prefix (GLib.DesktopAppInfo app, string? sandbox_id) {
@@ -200,7 +164,6 @@ namespace Gala {
200164
public static void clear_window_cache (Meta.Window window) {
201165
var desktop = window_to_desktop_cache[window];
202166
if (desktop != null) {
203-
icon_cache.remove_all (desktop);
204167
window_to_desktop_cache.unset (window);
205168
}
206169
}
@@ -229,52 +192,6 @@ namespace Gala {
229192
return get_app_from_id (canonicalized);
230193
}
231194

232-
private static Gdk.Pixbuf? get_icon_for_desktop_app_info (GLib.DesktopAppInfo desktop, int icon_size, int scale) {
233-
if (icon_cache.contains (desktop)) {
234-
foreach (var icon in icon_cache[desktop]) {
235-
if (icon.icon_size == icon_size && icon.scale == scale) {
236-
return icon.icon;
237-
}
238-
}
239-
}
240-
241-
var icon = desktop.get_icon ();
242-
243-
if (icon is GLib.ThemedIcon) {
244-
var icon_names = ((GLib.ThemedIcon)icon).get_names ();
245-
if (icon_names.length == 0) {
246-
return null;
247-
}
248-
249-
var icon_paintable = icon_theme.lookup_icon (icon_names[0], icon_names[1:], icon_size, scale, NONE, 0);
250-
251-
var path = icon_paintable.get_file ()?.get_path ();
252-
if (path == null) {
253-
return null;
254-
}
255-
256-
try {
257-
var pixbuf = new Gdk.Pixbuf.from_file (path);
258-
icon_cache.@set (desktop, CachedIcon () { icon = pixbuf, icon_size = icon_size, scale = scale });
259-
return pixbuf;
260-
} catch (Error e) {
261-
return null;
262-
}
263-
} else if (icon is GLib.FileIcon) {
264-
var file = ((GLib.FileIcon)icon).file;
265-
var size_with_scale = icon_size * scale;
266-
try {
267-
var pixbuf = new Gdk.Pixbuf.from_stream_at_scale (file.read (), size_with_scale, size_with_scale, true);
268-
icon_cache.@set (desktop, CachedIcon () { icon = pixbuf, icon_size = icon_size, scale = scale });
269-
return pixbuf;
270-
} catch (Error e) {
271-
return null;
272-
}
273-
}
274-
275-
return null;
276-
}
277-
278195
/**
279196
* Multiplies an integer by a floating scaling factor, and then
280197
* returns the result rounded to the nearest integer

lib/WindowIcon.vala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public class Gala.WindowIcon : Clutter.Actor {
1515
public int icon_size { get; construct; }
1616
public int scale { get; construct; }
1717

18+
private Icon icon;
19+
1820
/**
1921
* Creates a new WindowIcon
2022
*
@@ -29,6 +31,9 @@ public class Gala.WindowIcon : Clutter.Actor {
2931
}
3032

3133
construct {
34+
icon = new Icon (icon_size, scale);
35+
add_child (icon);
36+
3237
/**
3338
* Sometimes a WindowIcon is constructed on Meta.Display::window_created.
3439
* In this case it can happen that we don't have any info about the app yet so we can't get the
@@ -42,11 +47,6 @@ public class Gala.WindowIcon : Clutter.Actor {
4247
}
4348

4449
private void reload_icon () {
45-
width = icon_size * scale;
46-
height = icon_size * scale;
47-
48-
var pixbuf = Gala.Utils.get_icon_for_window (window, icon_size, scale);
49-
var image = new Gala.Image.from_pixbuf (pixbuf);
50-
set_content (image);
50+
icon.gicon = Utils.get_icon_for_window (window);
5151
}
5252
}

0 commit comments

Comments
 (0)