aboutsummarylogtreecommitdiffstats
path: root/gwl-grouping-heuristics.patch
blob: f139892dbdae77227d7bd7c6654b9d601354f855 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
diff --git a/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js b/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js
index 22303a136..d86f95c9f 100644
--- a/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js
+++ b/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js
@@ -639,7 +639,89 @@ class GroupedWindowListApplet extends Applet.Applet {
         this.state.set({lastTitleDisplay: titleDisplay});
     }
 
+    _matchFavoriteToWindow(fav, wmClass, wmInstance, gtkAppId) {
+        if (!fav || !fav.app) {
+            return false;
+        }
+
+        let favId = fav.id.toLowerCase();
+        // Get base name without path and .desktop
+        let baseName = favId.substring(favId.lastIndexOf('/') + 1).replace('.desktop', '');
+
+        // 1. Direct match on desktop ID base name (case-insensitive)
+        if (baseName === wmClass || baseName === wmInstance || (gtkAppId && baseName === gtkAppId)) {
+            return true;
+        }
+
+        // 2. Match on StartupWMClass from the app info
+        let appInfo = fav.app.get_app_info();
+        if (appInfo) {
+            let startupClass = appInfo.get_startup_wm_class ? appInfo.get_startup_wm_class() : null;
+            if (!startupClass) {
+                try {
+                    startupClass = appInfo.get_string("StartupWMClass");
+                } catch (e) {}
+            }
+            if (startupClass) {
+                startupClass = startupClass.toLowerCase();
+                if (startupClass === wmClass || startupClass === wmInstance) {
+                    return true;
+                }
+            }
+
+            // 3. Match executable/command name
+            let exec = appInfo.get_executable ? appInfo.get_executable() : null;
+            if (!exec) {
+                try {
+                    let cmd = appInfo.get_commandline ? appInfo.get_commandline() : "";
+                    if (cmd) {
+                        exec = cmd.split(' ')[0];
+                    }
+                } catch (e) {}
+            }
+            if (exec) {
+                let execBase = exec.substring(exec.lastIndexOf('/') + 1).toLowerCase();
+                if (execBase === wmClass || execBase === wmInstance) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    _matchWindowToPinnedApp(metaWindow) {
+        if (!this.pinnedFavorites || !this.pinnedFavorites._favorites) {
+            return null;
+        }
+
+        let wmClass = metaWindow.get_wm_class();
+        let wmInstance = metaWindow.get_wm_class_instance();
+        let gtkAppId = metaWindow.get_gtk_application_id ? metaWindow.get_gtk_application_id() : null;
+
+        wmClass = wmClass ? wmClass.toLowerCase() : "";
+        wmInstance = wmInstance ? wmInstance.toLowerCase() : "";
+        gtkAppId = gtkAppId ? gtkAppId.toLowerCase() : "";
+
+        // Iterate through pinned favorites
+        for (let fav of this.pinnedFavorites._favorites) {
+            if (this._matchFavoriteToWindow(fav, wmClass, wmInstance, gtkAppId)) {
+                return fav.app;
+            }
+        }
+        return null;
+    }
+
     getAppFromWindow(metaWindow) {
+        if (!metaWindow) {
+            return null;
+        }
+
+        // Try matching against pinned favorites first to prevent duplicate icons
+        let pinnedMatch = this._matchWindowToPinnedApp(metaWindow);
+        if (pinnedMatch) {
+            return pinnedMatch;
+        }
+
         const tracker = this.state.trigger('getTracker');
         if (!tracker) {
           return null;
@@ -651,6 +733,20 @@ class GroupedWindowListApplet extends Applet.Applet {
         if (!app) {
           app = tracker.get_app_from_pid(metaWindow.get_client_pid());
         }
+
+        // Fallback: If the tracker returned a transient app, check if its ID matches a pinned favorite
+        if (app && this.pinnedFavorites && this.pinnedFavorites._favorites) {
+            let appId = app.get_id().toLowerCase();
+            for (let fav of this.pinnedFavorites._favorites) {
+                if (!fav || !fav.app) continue;
+                let favId = fav.id.toLowerCase();
+                let baseName = favId.substring(favId.lastIndexOf('/') + 1).replace('.desktop', '');
+                if (appId === baseName || appId === favId) {
+                    return fav.app;
+                }
+            }
+        }
+
         return app;
     }
 
@@ -1030,6 +1126,9 @@ class GroupedWindowListApplet extends Applet.Applet {
 
     onWindowSkipTaskbarChanged(display, metaWindow) {
         const currentWorkspace = this.getCurrentWorkspace();
+        if (!currentWorkspace) {
+            return;
+        }
 
         if (metaWindow.is_skip_taskbar()) {
             currentWorkspace.windowRemoved(currentWorkspace.metaWorkspace, metaWindow);