Skip to content

Commit 5bbf6ed

Browse files
lenemterdanirabbitleonardo-lemos
authored
WindowTracker: better search for desktop file (#2382)
Co-authored-by: Danielle Foré <[email protected]> Co-authored-by: Leonardo Lemos <[email protected]>
1 parent ed88ffb commit 5bbf6ed

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

lib/AppSystem.vala

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,64 @@ public class Gala.AppSystem : GLib.Object {
1414
private GLib.HashTable<unowned string, Gala.App> id_to_app;
1515
private GLib.HashTable<string, string> startup_wm_class_to_id;
1616
private Gala.AppCache app_cache;
17+
private string[] all_desktop_files = {};
18+
private GLib.FileMonitor[]? directory_monitors;
1719

1820
construct {
1921
id_to_app = new GLib.HashTable<unowned string, Gala.App> (str_hash, str_equal);
2022
startup_wm_class_to_id = new GLib.HashTable<string, string> (str_hash, str_equal);
2123
running_apps = new GLib.HashTable<Gala.App, unowned Gala.App> (null, null);
2224
app_cache = new AppCache ();
25+
26+
update_desktop_files ();
27+
}
28+
29+
private void update_desktop_files () {
30+
var data_dirs = Environment.get_system_data_dirs ();
31+
data_dirs += Environment.get_user_data_dir ();
32+
33+
var create_monitors = directory_monitors == null;
34+
if (create_monitors) {
35+
directory_monitors = {};
36+
}
37+
38+
foreach (unowned string data_dir in data_dirs) {
39+
var app_dir = Path.build_filename (data_dir, "applications");
40+
if (FileUtils.test (app_dir, FileTest.EXISTS)) {
41+
try {
42+
foreach (var name in enumerate_children (app_dir)) {
43+
if (!name.contains ("~") && name.has_suffix (".desktop")) {
44+
all_desktop_files += name;
45+
}
46+
}
47+
48+
if (!create_monitors) {
49+
continue;
50+
}
51+
52+
var monitor = File.new_for_path (app_dir).monitor (GLib.FileMonitorFlags.NONE, null);
53+
monitor.changed.connect ((file, other_file, event_type) => {
54+
if (event_type == GLib.FileMonitorEvent.CHANGES_DONE_HINT) {
55+
update_desktop_files ();
56+
}
57+
});
58+
directory_monitors += monitor;
59+
} catch (Error e) {
60+
debug ("Error inside %s: %s", app_dir, e.message);
61+
}
62+
}
63+
}
64+
}
65+
66+
private string[] enumerate_children (string dir) throws Error {
67+
string[] result = {};
68+
FileInfo? file_info;
69+
var enumerator = File.new_for_path (dir).enumerate_children (FileAttribute.STANDARD_NAME, 0);
70+
while ((file_info = enumerator.next_file ()) != null) {
71+
result += file_info.get_name ();
72+
}
73+
74+
return result;
2375
}
2476

2577
public unowned Gala.App? lookup_app (string id) {
@@ -105,6 +157,20 @@ public class Gala.AppSystem : GLib.Object {
105157
return lookup_heuristic_basename (desktop_file);
106158
}
107159

160+
public unowned Gala.App? guess_app_by_id (string _id) {
161+
var id = _id.ascii_down ();
162+
unowned Gala.App? result = null;
163+
164+
foreach (var name in all_desktop_files) {
165+
// Try to find desktop file based on the application name
166+
if (name.contains (id) && (result = lookup_app (name)) != null) {
167+
return result;
168+
}
169+
}
170+
171+
return null;
172+
}
173+
108174
public void notify_app_state_changed (Gala.App app) {
109175
if (app.state == Gala.AppState.RUNNING) {
110176
running_apps.insert (app, app);

src/WindowTracker.vala

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,34 @@ public class Gala.WindowTracker : GLib.Object {
199199
return null;
200200
}
201201

202+
private unowned Gala.App? get_app_by_guessing (Meta.Window window) {
203+
unowned var app_system = Gala.AppSystem.get_default ();
204+
unowned Gala.App? result = null;
205+
206+
unowned string? id = window.get_gtk_application_id ();
207+
// if id contains '.' it's probably a valid app id but it doesn't provide the desktop file
208+
if (id != null && !id.contains (".") && (result = app_system.guess_app_by_id (id)) != null) {
209+
return result;
210+
}
211+
212+
id = window.get_sandboxed_app_id ();
213+
if (id != null && !id.contains (".") && (result = app_system.guess_app_by_id (id)) != null) {
214+
return result;
215+
}
216+
217+
id = window.get_wm_class ();
218+
if (id != null && !id.contains (".") && (result = app_system.guess_app_by_id (id)) != null) {
219+
return result;
220+
}
221+
222+
id = window.get_wm_class_instance ();
223+
if (id != null && !id.contains (".") && (result = app_system.guess_app_by_id (id)) != null) {
224+
return result;
225+
}
226+
227+
return null;
228+
}
229+
202230
public Gala.App get_app_for_window (Meta.Window window) {
203231
unowned Meta.Window? transient_for = window.get_transient_for ();
204232
if (transient_for != null) {
@@ -279,9 +307,15 @@ public class Gala.WindowTracker : GLib.Object {
279307
return result;
280308
}
281309

310+
/* Try to carefully guess .desktop file name based on application ids and wm class
311+
*/
312+
result = get_app_by_guessing (window);
313+
if (result != null) {
314+
return result;
315+
}
316+
282317
/* Our last resort - we create a fake app from the window */
283318
return new Gala.App.for_window (window);
284-
285319
}
286320

287321
private void tracked_window_changed (Meta.Window window) {

0 commit comments

Comments
 (0)