Merge lp:~3v1n0/bamf/desktop-class-matching-improved into lp:bamf/0.4
- desktop-class-matching-improved
- Merge into 0.4
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Marco Trevisan (Treviño) | ||||
Approved revision: | 469 | ||||
Merged at revision: | 460 | ||||
Proposed branch: | lp:~3v1n0/bamf/desktop-class-matching-improved | ||||
Merge into: | lp:bamf/0.4 | ||||
Diff against target: |
1185 lines (+459/-304) 6 files modified
src/bamf-legacy-window.c (+51/-16) src/bamf-legacy-window.h (+14/-15) src/bamf-matcher.c (+319/-250) src/bamf-view.c (+3/-1) src/bamf-xutils.c (+68/-20) src/bamf-xutils.h (+4/-2) |
||||
To merge this branch: | bzr merge lp:~3v1n0/bamf/desktop-class-matching-improved | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jason Smith (community) | Approve | ||
Review via email: mp+102741@code.launchpad.net |
Commit message
BamfLegacyWindow and BamfMatcher changes needed to get the proper WM_CLASS / desktop-class matching in BAMF.
Description of the change
BamfLegacyWindow and BamfMatcher changes needed to get the proper WM_CLASS matching in BAMF.
This mostly allow to get the wanted experience with the Chrome/Chromium web applications
so now:
- When a Web application is launched and has a matching .desktop file (this means that
the file should include the StartupWMClass parameter that matches the window's class
instance name) then it's matched as a new application using that file.
- When a Web application is launched and has not a matching .desktop file (no file
matches its class), then we fallback to the know .desktop files (so very likely to the
parent application desktop).
Changes include:
- BamfLegacyWindow is now able to fetch both the window class name and instance name also
for non-gtk3 builds (instead of using libwnck, we fallback to Xlib)
- BamfXutils now avoid to open a display connection per request.
- BamfMatcher includes now the utility function
bamf_
duplication. It correctly matches the chromium web applications and avoids the re-usage
of non-optimum running .desktop files.
- 467. By Marco Trevisan (Treviño)
-
BamfMatcher: free the temporary list we use to order the windows by stack
- 468. By Marco Trevisan (Treviño)
-
BamfMatcher: be more explicit about the desktop file to use for a new application.
- 469. By Marco Trevisan (Treviño)
-
BamfMatcher: oops... Forgot an else when checking the type of new application we should create
Preview Diff
1 | === modified file 'src/bamf-legacy-window.c' | |||
2 | --- src/bamf-legacy-window.c 2012-02-10 20:05:54 +0000 | |||
3 | +++ src/bamf-legacy-window.c 2012-04-20 17:39:18 +0000 | |||
4 | @@ -1,5 +1,5 @@ | |||
5 | 1 | /* | 1 | /* |
7 | 2 | * Copyright (C) 2010 Canonical Ltd | 2 | * Copyright (C) 2010-2012 Canonical Ltd |
8 | 3 | * | 3 | * |
9 | 4 | * This program is free software: you can redistribute it and/or modify | 4 | * This program is free software: you can redistribute it and/or modify |
10 | 5 | * it under the terms of the GNU General Public License version 3 as | 5 | * it under the terms of the GNU General Public License version 3 as |
11 | @@ -14,6 +14,7 @@ | |||
12 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
13 | 15 | * | 15 | * |
14 | 16 | * Authored by: Jason Smith <jason.smith@canonical.com> | 16 | * Authored by: Jason Smith <jason.smith@canonical.com> |
15 | 17 | * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> | ||
16 | 17 | * | 18 | * |
17 | 18 | */ | 19 | */ |
18 | 19 | 20 | ||
19 | @@ -47,6 +48,10 @@ | |||
20 | 47 | { | 48 | { |
21 | 48 | WnckWindow * legacy_window; | 49 | WnckWindow * legacy_window; |
22 | 49 | char * mini_icon_path; | 50 | char * mini_icon_path; |
23 | 51 | #ifndef USE_GTK3 | ||
24 | 52 | char * group_name; | ||
25 | 53 | char * instance_name; | ||
26 | 54 | #endif | ||
27 | 50 | gulong closed_id; | 55 | gulong closed_id; |
28 | 51 | gulong name_changed_id; | 56 | gulong name_changed_id; |
29 | 52 | gulong state_changed_id; | 57 | gulong state_changed_id; |
30 | @@ -105,7 +110,6 @@ | |||
31 | 105 | return wnck_window_is_skip_tasklist (self->priv->legacy_window); | 110 | return wnck_window_is_skip_tasklist (self->priv->legacy_window); |
32 | 106 | } | 111 | } |
33 | 107 | 112 | ||
34 | 108 | #ifdef USE_GTK3 | ||
35 | 109 | const char * | 113 | const char * |
36 | 110 | bamf_legacy_window_get_class_instance_name (BamfLegacyWindow *self) | 114 | bamf_legacy_window_get_class_instance_name (BamfLegacyWindow *self) |
37 | 111 | { | 115 | { |
38 | @@ -115,17 +119,29 @@ | |||
39 | 115 | 119 | ||
40 | 116 | window = self->priv->legacy_window; | 120 | window = self->priv->legacy_window; |
41 | 117 | 121 | ||
42 | 122 | if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_class_instance_name) | ||
43 | 123 | return BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_class_instance_name (self); | ||
44 | 124 | |||
45 | 118 | if (!window) | 125 | if (!window) |
46 | 119 | return NULL; | 126 | return NULL; |
47 | 120 | 127 | ||
48 | 128 | #ifdef USE_GTK3 | ||
49 | 121 | return wnck_window_get_class_instance_name (window); | 129 | return wnck_window_get_class_instance_name (window); |
50 | 130 | |||
51 | 131 | #else | ||
52 | 132 | if (!self->priv->instance_name) | ||
53 | 133 | { | ||
54 | 134 | Window xid = wnck_window_get_xid (window); | ||
55 | 135 | bamf_xutils_get_window_class_hints (xid, &self->priv->instance_name, NULL); | ||
56 | 136 | } | ||
57 | 137 | |||
58 | 138 | return self->priv->instance_name; | ||
59 | 139 | #endif | ||
60 | 122 | } | 140 | } |
61 | 123 | #endif | ||
62 | 124 | 141 | ||
63 | 125 | const char * | 142 | const char * |
64 | 126 | bamf_legacy_window_get_class_name (BamfLegacyWindow *self) | 143 | bamf_legacy_window_get_class_name (BamfLegacyWindow *self) |
65 | 127 | { | 144 | { |
66 | 128 | WnckClassGroup *group; | ||
67 | 129 | WnckWindow *window; | 145 | WnckWindow *window; |
68 | 130 | 146 | ||
69 | 131 | g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), NULL); | 147 | g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), NULL); |
70 | @@ -138,12 +154,18 @@ | |||
71 | 138 | if (!window) | 154 | if (!window) |
72 | 139 | return NULL; | 155 | return NULL; |
73 | 140 | 156 | ||
80 | 141 | group = wnck_window_get_class_group (window); | 157 | #ifdef USE_GTK3 |
81 | 142 | 158 | return wnck_window_get_class_group_name (window); | |
82 | 143 | if (!group) | 159 | |
83 | 144 | return NULL; | 160 | #else |
84 | 145 | 161 | if (!self->priv->group_name) | |
85 | 146 | return wnck_class_group_get_res_class (group); | 162 | { |
86 | 163 | Window xid = wnck_window_get_xid (window); | ||
87 | 164 | bamf_xutils_get_window_class_hints (xid, NULL, &self->priv->group_name); | ||
88 | 165 | } | ||
89 | 166 | |||
90 | 167 | return self->priv->group_name; | ||
91 | 168 | #endif | ||
92 | 147 | } | 169 | } |
93 | 148 | 170 | ||
94 | 149 | const char * | 171 | const char * |
95 | @@ -186,7 +208,7 @@ | |||
96 | 186 | { | 208 | { |
97 | 187 | g_string_append (exec, argv[i]); | 209 | g_string_append (exec, argv[i]); |
98 | 188 | if (argv[i + 1] != NULL) | 210 | if (argv[i + 1] != NULL) |
100 | 189 | g_string_append (exec, " "); | 211 | g_string_append (exec, " "); |
101 | 190 | g_free (argv[i]); | 212 | g_free (argv[i]); |
102 | 191 | i++; | 213 | i++; |
103 | 192 | } | 214 | } |
104 | @@ -253,7 +275,6 @@ | |||
105 | 253 | { | 275 | { |
106 | 254 | g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), 0); | 276 | g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (self), 0); |
107 | 255 | 277 | ||
108 | 256 | |||
109 | 257 | if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_xid) | 278 | if (BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_xid) |
110 | 258 | return BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_xid (self); | 279 | return BAMF_LEGACY_WINDOW_GET_CLASS (self)->get_xid (self); |
111 | 259 | 280 | ||
112 | @@ -347,10 +368,10 @@ | |||
113 | 347 | bamf_legacy_window_get_geometry (BamfLegacyWindow *self, gint *x, gint *y, | 368 | bamf_legacy_window_get_geometry (BamfLegacyWindow *self, gint *x, gint *y, |
114 | 348 | gint *width, gint *height) | 369 | gint *width, gint *height) |
115 | 349 | { | 370 | { |
120 | 350 | *x = 0; | 371 | if (x) *x = 0; |
121 | 351 | *y = 0; | 372 | if (y) *y = 0; |
122 | 352 | *width = 0; | 373 | if (width) *width = 0; |
123 | 353 | *height = 0; | 374 | if (height) *height = 0; |
124 | 354 | 375 | ||
125 | 355 | g_return_if_fail (BAMF_IS_LEGACY_WINDOW (self)); | 376 | g_return_if_fail (BAMF_IS_LEGACY_WINDOW (self)); |
126 | 356 | 377 | ||
127 | @@ -478,6 +499,20 @@ | |||
128 | 478 | self->priv->mini_icon_path = NULL; | 499 | self->priv->mini_icon_path = NULL; |
129 | 479 | } | 500 | } |
130 | 480 | 501 | ||
131 | 502 | #ifndef USE_GTK3 | ||
132 | 503 | if (self->priv->group_name) | ||
133 | 504 | { | ||
134 | 505 | g_free (self->priv->group_name); | ||
135 | 506 | self->priv->group_name = NULL; | ||
136 | 507 | } | ||
137 | 508 | |||
138 | 509 | if (self->priv->instance_name) | ||
139 | 510 | { | ||
140 | 511 | g_free (self->priv->instance_name); | ||
141 | 512 | self->priv->instance_name = NULL; | ||
142 | 513 | } | ||
143 | 514 | #endif | ||
144 | 515 | |||
145 | 481 | if (self->priv->legacy_window) | 516 | if (self->priv->legacy_window) |
146 | 482 | { | 517 | { |
147 | 483 | g_signal_handler_disconnect (self->priv->legacy_window, | 518 | g_signal_handler_disconnect (self->priv->legacy_window, |
148 | 484 | 519 | ||
149 | === modified file 'src/bamf-legacy-window.h' | |||
150 | --- src/bamf-legacy-window.h 2012-02-10 17:33:51 +0000 | |||
151 | +++ src/bamf-legacy-window.h 2012-04-20 17:39:18 +0000 | |||
152 | @@ -70,19 +70,20 @@ | |||
153 | 70 | { | 70 | { |
154 | 71 | GObjectClass parent; | 71 | GObjectClass parent; |
155 | 72 | 72 | ||
169 | 73 | const char * (*get_name) (BamfLegacyWindow *legacy_window); | 73 | const char * (*get_name) (BamfLegacyWindow *legacy_window); |
170 | 74 | const char * (*get_class_name) (BamfLegacyWindow *legacy_window); | 74 | const char * (*get_class_name) (BamfLegacyWindow *legacy_window); |
171 | 75 | char * (*get_exec_string) (BamfLegacyWindow *legacy_window); | 75 | const char * (*get_class_instance_name) (BamfLegacyWindow *legacy_window); |
172 | 76 | char * (*get_app_id) (BamfLegacyWindow *legacy_window); | 76 | char * (*get_exec_string) (BamfLegacyWindow *legacy_window); |
173 | 77 | char * (*get_unique_bus_name) (BamfLegacyWindow *legacy_window); | 77 | char * (*get_app_id) (BamfLegacyWindow *legacy_window); |
174 | 78 | char * (*get_menu_object_path) (BamfLegacyWindow *legacy_window); | 78 | char * (*get_unique_bus_name) (BamfLegacyWindow *legacy_window); |
175 | 79 | gint (*get_pid) (BamfLegacyWindow *legacy_window); | 79 | char * (*get_menu_object_path) (BamfLegacyWindow *legacy_window); |
176 | 80 | guint32 (*get_xid) (BamfLegacyWindow *legacy_window); | 80 | gint (*get_pid) (BamfLegacyWindow *legacy_window); |
177 | 81 | gboolean (*needs_attention) (BamfLegacyWindow *legacy_window); | 81 | guint32 (*get_xid) (BamfLegacyWindow *legacy_window); |
178 | 82 | gboolean (*is_active) (BamfLegacyWindow *legacy_window); | 82 | gboolean (*needs_attention) (BamfLegacyWindow *legacy_window); |
179 | 83 | gboolean (*is_skip_tasklist) (BamfLegacyWindow *legacy_window); | 83 | gboolean (*is_active) (BamfLegacyWindow *legacy_window); |
180 | 84 | gboolean (*is_desktop) (BamfLegacyWindow *legacy_window); | 84 | gboolean (*is_skip_tasklist) (BamfLegacyWindow *legacy_window); |
181 | 85 | gboolean (*is_dialog) (BamfLegacyWindow *legacy_window); | 85 | gboolean (*is_desktop) (BamfLegacyWindow *legacy_window); |
182 | 86 | gboolean (*is_dialog) (BamfLegacyWindow *legacy_window); | ||
183 | 86 | BamfWindowMaximizationType (*maximized) (BamfLegacyWindow *legacy_window); | 87 | BamfWindowMaximizationType (*maximized) (BamfLegacyWindow *legacy_window); |
184 | 87 | 88 | ||
185 | 88 | void (*get_geometry) (BamfLegacyWindow *self, | 89 | void (*get_geometry) (BamfLegacyWindow *self, |
186 | @@ -126,9 +127,7 @@ | |||
187 | 126 | 127 | ||
188 | 127 | BamfWindowMaximizationType bamf_legacy_window_maximized (BamfLegacyWindow *self); | 128 | BamfWindowMaximizationType bamf_legacy_window_maximized (BamfLegacyWindow *self); |
189 | 128 | 129 | ||
190 | 129 | #ifdef USE_GTK3 | ||
191 | 130 | const char * bamf_legacy_window_get_class_instance_name (BamfLegacyWindow *self); | 130 | const char * bamf_legacy_window_get_class_instance_name (BamfLegacyWindow *self); |
192 | 131 | #endif | ||
193 | 132 | 131 | ||
194 | 133 | const char * bamf_legacy_window_get_class_name (BamfLegacyWindow *self); | 132 | const char * bamf_legacy_window_get_class_name (BamfLegacyWindow *self); |
195 | 134 | 133 | ||
196 | 135 | 134 | ||
197 | === modified file 'src/bamf-matcher.c' | |||
198 | --- src/bamf-matcher.c 2012-03-19 17:11:35 +0000 | |||
199 | +++ src/bamf-matcher.c 2012-04-20 17:39:18 +0000 | |||
200 | @@ -1,5 +1,5 @@ | |||
201 | 1 | /* | 1 | /* |
203 | 2 | * Copyright (C) 2010-2011 Canonical Ltd | 2 | * Copyright (C) 2010-2012 Canonical Ltd |
204 | 3 | * | 3 | * |
205 | 4 | * This program is free software: you can redistribute it and/or modify | 4 | * This program is free software: you can redistribute it and/or modify |
206 | 5 | * it under the terms of the GNU General Public License version 3 as | 5 | * it under the terms of the GNU General Public License version 3 as |
207 | @@ -28,6 +28,7 @@ | |||
208 | 28 | #include "bamf-legacy-screen.h" | 28 | #include "bamf-legacy-screen.h" |
209 | 29 | #include "bamf-indicator-source.h" | 29 | #include "bamf-indicator-source.h" |
210 | 30 | #include "bamf-xutils.h" | 30 | #include "bamf-xutils.h" |
211 | 31 | #include <strings.h> | ||
212 | 31 | 32 | ||
213 | 32 | G_DEFINE_TYPE (BamfMatcher, bamf_matcher, BAMF_DBUS_TYPE_MATCHER_SKELETON); | 33 | G_DEFINE_TYPE (BamfMatcher, bamf_matcher, BAMF_DBUS_TYPE_MATCHER_SKELETON); |
214 | 33 | #define BAMF_MATCHER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \ | 34 | #define BAMF_MATCHER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \ |
215 | @@ -126,6 +127,37 @@ | |||
216 | 126 | 127 | ||
217 | 127 | static void bamf_matcher_unregister_view (BamfMatcher *self, BamfView *view); | 128 | static void bamf_matcher_unregister_view (BamfMatcher *self, BamfView *view); |
218 | 128 | 129 | ||
219 | 130 | static BamfApplication * | ||
220 | 131 | bamf_matcher_get_application_by_desktop_file (BamfMatcher *self, const char *desktop_file) | ||
221 | 132 | { | ||
222 | 133 | GList *l; | ||
223 | 134 | BamfView *view; | ||
224 | 135 | |||
225 | 136 | g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); | ||
226 | 137 | |||
227 | 138 | if (!desktop_file) | ||
228 | 139 | return NULL; | ||
229 | 140 | |||
230 | 141 | for (l = self->priv->views; l; l = l->next) | ||
231 | 142 | { | ||
232 | 143 | view = l->data; | ||
233 | 144 | |||
234 | 145 | if (!BAMF_IS_APPLICATION (view)) | ||
235 | 146 | continue; | ||
236 | 147 | |||
237 | 148 | BamfApplication *app = BAMF_APPLICATION (view); | ||
238 | 149 | const gchar *app_desktop; | ||
239 | 150 | app_desktop = bamf_application_get_desktop_file (app); | ||
240 | 151 | |||
241 | 152 | if (g_strcmp0 (desktop_file, app_desktop) == 0) | ||
242 | 153 | { | ||
243 | 154 | return app; | ||
244 | 155 | } | ||
245 | 156 | } | ||
246 | 157 | |||
247 | 158 | return NULL; | ||
248 | 159 | } | ||
249 | 160 | |||
250 | 129 | static gboolean | 161 | static gboolean |
251 | 130 | emit_paths_changed (gpointer user_data) | 162 | emit_paths_changed (gpointer user_data) |
252 | 131 | { | 163 | { |
253 | @@ -177,11 +209,7 @@ | |||
254 | 177 | 209 | ||
255 | 178 | static void bamf_matcher_prepare_path_change (BamfMatcher *self, const gchar *desktop_file, ViewChangeType change_type) | 210 | static void bamf_matcher_prepare_path_change (BamfMatcher *self, const gchar *desktop_file, ViewChangeType change_type) |
256 | 179 | { | 211 | { |
257 | 180 | GList *l; | ||
258 | 181 | BamfView *view; | ||
259 | 182 | BamfMatcherPrivate *priv; | 212 | BamfMatcherPrivate *priv; |
260 | 183 | const char *app_desktop; | ||
261 | 184 | gboolean found = FALSE; | ||
262 | 185 | 213 | ||
263 | 186 | if (desktop_file == NULL) return; | 214 | if (desktop_file == NULL) return; |
264 | 187 | 215 | ||
265 | @@ -189,26 +217,12 @@ | |||
266 | 189 | 217 | ||
267 | 190 | priv = self->priv; | 218 | priv = self->priv; |
268 | 191 | 219 | ||
269 | 192 | for (l = priv->views; l; l = l->next) | ||
270 | 193 | { | ||
271 | 194 | view = l->data; | ||
272 | 195 | |||
273 | 196 | if (!BAMF_IS_APPLICATION (view) || !bamf_view_is_running (view)) | ||
274 | 197 | continue; | ||
275 | 198 | |||
276 | 199 | app_desktop = bamf_application_get_desktop_file (BAMF_APPLICATION (view)); | ||
277 | 200 | if (!app_desktop) continue; | ||
278 | 201 | |||
279 | 202 | if (g_strcmp0 (desktop_file, app_desktop) == 0) | ||
280 | 203 | { | ||
281 | 204 | found = TRUE; | ||
282 | 205 | break; | ||
283 | 206 | } | ||
284 | 207 | } | ||
285 | 208 | |||
286 | 209 | /* the app was already running (ADDED) / had more instances which are still | 220 | /* the app was already running (ADDED) / had more instances which are still |
287 | 210 | * there (REMOVED) */ | 221 | * there (REMOVED) */ |
289 | 211 | if (found) return; | 222 | if (bamf_matcher_get_application_by_desktop_file (self, desktop_file)) |
290 | 223 | { | ||
291 | 224 | return; | ||
292 | 225 | } | ||
293 | 212 | 226 | ||
294 | 213 | if (!priv->opened_closed_paths_table) | 227 | if (!priv->opened_closed_paths_table) |
295 | 214 | { | 228 | { |
296 | @@ -258,7 +272,7 @@ | |||
297 | 258 | self->priv->views = g_list_prepend (self->priv->views, view); | 272 | self->priv->views = g_list_prepend (self->priv->views, view); |
298 | 259 | 273 | ||
299 | 260 | g_signal_emit_by_name (self, "view-opened", path, type); | 274 | g_signal_emit_by_name (self, "view-opened", path, type); |
301 | 261 | 275 | ||
302 | 262 | // trigger manually since this is already active | 276 | // trigger manually since this is already active |
303 | 263 | if (bamf_view_is_active (view)) | 277 | if (bamf_view_is_active (view)) |
304 | 264 | on_view_active_changed (view, TRUE, self); | 278 | on_view_active_changed (view, TRUE, self); |
305 | @@ -1514,59 +1528,134 @@ | |||
306 | 1514 | is_web_app_window (BamfMatcher *self, BamfLegacyWindow *window) | 1528 | is_web_app_window (BamfMatcher *self, BamfLegacyWindow *window) |
307 | 1515 | { | 1529 | { |
308 | 1516 | const char *window_class = bamf_legacy_window_get_class_name (window); | 1530 | const char *window_class = bamf_legacy_window_get_class_name (window); |
309 | 1517 | #ifdef USE_GTK3 | ||
310 | 1518 | const char *instance_name = bamf_legacy_window_get_class_instance_name(window); | 1531 | const char *instance_name = bamf_legacy_window_get_class_instance_name(window); |
319 | 1519 | // chromium uses url wm_class strings to represent its web apps. These apps | 1532 | |
320 | 1520 | // will still have the same parent pid and hints as the main chrome window, so we | 1533 | // Chrome/Chromium uses url wm_class strings to represent its web apps. |
321 | 1521 | // skip the hint check. We can tell a window is a chrome web app window if its instance | 1534 | // These apps will still have the same parent pid and hints as the main chrome |
322 | 1522 | // name is google-chrome but its window class is not Google-chrome | 1535 | // window, so we skip the hint check. |
323 | 1523 | return !g_strcmp0(instance_name, "google-chrome") && g_strcmp0(window_class, "Google-chrome"); | 1536 | // We can tell a window is a chrome web app window if its instance name is |
324 | 1524 | #else | 1537 | // not google-chrome but its window class is Google-chrome |
325 | 1525 | return g_str_has_prefix(window_class, "crx_"); | 1538 | // We can tell a window is chromium web app window if its instance name is |
326 | 1526 | #endif | 1539 | // not chromium-browser but its window class is Chromium Browser |
327 | 1540 | |||
328 | 1541 | gboolean valid_app = FALSE; | ||
329 | 1542 | |||
330 | 1543 | if (g_strcmp0 (window_class, "Google-chrome") == 0 && | ||
331 | 1544 | g_strcmp0 (instance_name, "google-chrome") != 0) | ||
332 | 1545 | { | ||
333 | 1546 | valid_app = TRUE; | ||
334 | 1547 | } | ||
335 | 1548 | else if (g_strcmp0 (window_class, "Chromium-browser") == 0 && | ||
336 | 1549 | g_strcmp0 (instance_name, "chromium-browser") != 0) | ||
337 | 1550 | { | ||
338 | 1551 | valid_app = TRUE; | ||
339 | 1552 | } | ||
340 | 1553 | |||
341 | 1554 | return valid_app; | ||
342 | 1555 | } | ||
343 | 1556 | |||
344 | 1557 | static gboolean | ||
345 | 1558 | bamf_matcher_window_skips_hint_set (BamfMatcher *self, BamfLegacyWindow *window) | ||
346 | 1559 | { | ||
347 | 1560 | gboolean skip_hint_set = FALSE; | ||
348 | 1561 | g_return_val_if_fail (BAMF_IS_MATCHER (self), TRUE); | ||
349 | 1562 | |||
350 | 1563 | skip_hint_set = is_web_app_window (self, window); | ||
351 | 1564 | |||
352 | 1565 | return skip_hint_set; | ||
353 | 1566 | } | ||
354 | 1567 | |||
355 | 1568 | static GList * | ||
356 | 1569 | bamf_matcher_get_class_matching_desktop_files (BamfMatcher *self, const gchar *class_name) | ||
357 | 1570 | { | ||
358 | 1571 | GList* desktop_files = NULL; | ||
359 | 1572 | gpointer key; | ||
360 | 1573 | gpointer value; | ||
361 | 1574 | GHashTableIter iter; | ||
362 | 1575 | |||
363 | 1576 | g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); | ||
364 | 1577 | g_hash_table_iter_init (&iter, self->priv->desktop_class_table); | ||
365 | 1578 | |||
366 | 1579 | while (g_hash_table_iter_next (&iter, &key, &value)) | ||
367 | 1580 | { | ||
368 | 1581 | gchar* desktop_file = g_strdup (key); | ||
369 | 1582 | gchar* desktop_class = value; | ||
370 | 1583 | |||
371 | 1584 | if (g_strcmp0 (desktop_class, class_name) == 0) | ||
372 | 1585 | { | ||
373 | 1586 | desktop_files = g_list_prepend (desktop_files, desktop_file); | ||
374 | 1587 | } | ||
375 | 1588 | } | ||
376 | 1589 | |||
377 | 1590 | return desktop_files; | ||
378 | 1591 | } | ||
379 | 1592 | |||
380 | 1593 | static gboolean | ||
381 | 1594 | bamf_matcher_has_instance_class_desktop_file (BamfMatcher *self, const gchar *class_name) | ||
382 | 1595 | { | ||
383 | 1596 | gpointer key; | ||
384 | 1597 | gpointer value; | ||
385 | 1598 | GHashTableIter iter; | ||
386 | 1599 | |||
387 | 1600 | g_return_val_if_fail (BAMF_IS_MATCHER (self), FALSE); | ||
388 | 1601 | g_hash_table_iter_init (&iter, self->priv->desktop_class_table); | ||
389 | 1602 | |||
390 | 1603 | while (g_hash_table_iter_next (&iter, &key, &value)) | ||
391 | 1604 | { | ||
392 | 1605 | gchar* desktop_class = value; | ||
393 | 1606 | |||
394 | 1607 | if (g_strcmp0 (desktop_class, class_name) == 0) | ||
395 | 1608 | { | ||
396 | 1609 | return TRUE; | ||
397 | 1610 | } | ||
398 | 1611 | } | ||
399 | 1612 | |||
400 | 1613 | return FALSE; | ||
401 | 1527 | } | 1614 | } |
402 | 1528 | 1615 | ||
403 | 1529 | static GList * | 1616 | static GList * |
404 | 1530 | bamf_matcher_possible_applications_for_window (BamfMatcher *self, | 1617 | bamf_matcher_possible_applications_for_window (BamfMatcher *self, |
405 | 1531 | BamfWindow *bamf_window) | 1618 | BamfWindow *bamf_window) |
406 | 1532 | { | 1619 | { |
407 | 1533 | char *hint = NULL; | ||
408 | 1534 | BamfMatcherPrivate *priv; | 1620 | BamfMatcherPrivate *priv; |
409 | 1535 | gint pid; | ||
410 | 1536 | BamfLegacyWindow *window; | 1621 | BamfLegacyWindow *window; |
412 | 1537 | GList *desktop_files = NULL, *pid_list = NULL, *l; | 1622 | GList *desktop_files = NULL, *l; |
413 | 1623 | char *desktop_file = NULL; | ||
414 | 1624 | char *desktop_class = NULL; | ||
415 | 1538 | 1625 | ||
416 | 1539 | g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL); | 1626 | g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL); |
417 | 1540 | g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); | 1627 | g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); |
418 | 1541 | 1628 | ||
419 | 1542 | priv = self->priv; | 1629 | priv = self->priv; |
420 | 1543 | |||
421 | 1544 | window = bamf_window_get_window (bamf_window); | 1630 | window = bamf_window_get_window (bamf_window); |
422 | 1545 | 1631 | ||
427 | 1546 | hint = get_window_hint (window, _NET_WM_DESKTOP_FILE); | 1632 | desktop_file = get_window_hint (window, _NET_WM_DESKTOP_FILE); |
428 | 1547 | const char *window_class = bamf_legacy_window_get_class_name (window); | 1633 | |
429 | 1548 | 1634 | const char *class_name = bamf_legacy_window_get_class_name (window); | |
430 | 1549 | if (hint) | 1635 | const char *instance_name = bamf_legacy_window_get_class_instance_name (window); |
431 | 1636 | gboolean known_desktop_class = bamf_matcher_has_instance_class_desktop_file (self, instance_name); | ||
432 | 1637 | |||
433 | 1638 | if (desktop_file) | ||
434 | 1550 | { | 1639 | { |
437 | 1551 | /* whew, hard work, didn't even have to make a copy! */ | 1640 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); |
438 | 1552 | if (hint[0] != '\0' && !is_web_app_window(self, window)) | 1641 | |
439 | 1642 | if (!known_desktop_class || g_strcmp0 (desktop_class, desktop_file) == 0) | ||
440 | 1553 | { | 1643 | { |
442 | 1554 | desktop_files = g_list_prepend (desktop_files, hint); | 1644 | desktop_files = g_list_prepend (desktop_files, desktop_file); |
443 | 1555 | } | 1645 | } |
444 | 1556 | else | 1646 | else |
445 | 1557 | { | 1647 | { |
447 | 1558 | g_free (hint); | 1648 | g_free (desktop_file); |
448 | 1559 | } | 1649 | } |
449 | 1560 | } | 1650 | } |
451 | 1561 | else | 1651 | |
452 | 1652 | desktop_file = NULL; | ||
453 | 1653 | |||
454 | 1654 | if (!desktop_files) | ||
455 | 1562 | { | 1655 | { |
461 | 1563 | 1656 | if (class_name) | |
457 | 1564 | char *desktop_file; | ||
458 | 1565 | char *desktop_class; | ||
459 | 1566 | |||
460 | 1567 | if (window_class) | ||
462 | 1568 | { | 1657 | { |
464 | 1569 | char *window_class_down = g_ascii_strdown (window_class, -1); | 1658 | char *window_class_down = g_ascii_strdown (class_name, -1); |
465 | 1570 | l = g_hash_table_lookup (priv->desktop_id_table, window_class_down); | 1659 | l = g_hash_table_lookup (priv->desktop_id_table, window_class_down); |
466 | 1571 | g_free (window_class_down); | 1660 | g_free (window_class_down); |
467 | 1572 | 1661 | ||
468 | @@ -1577,11 +1666,14 @@ | |||
469 | 1577 | if (desktop_file) | 1666 | if (desktop_file) |
470 | 1578 | { | 1667 | { |
471 | 1579 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); | 1668 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); |
475 | 1580 | if ((desktop_class == NULL || g_strcmp0 (desktop_class, window_class) == 0) && | 1669 | |
476 | 1581 | !g_list_find_custom (desktop_files, desktop_file, | 1670 | if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0) |
474 | 1582 | (GCompareFunc) g_strcmp0)) | ||
477 | 1583 | { | 1671 | { |
479 | 1584 | desktop_files = g_list_prepend (desktop_files, g_strdup (desktop_file)); | 1672 | if (!g_list_find_custom (desktop_files, desktop_file, |
480 | 1673 | (GCompareFunc) g_strcmp0)) | ||
481 | 1674 | { | ||
482 | 1675 | desktop_files = g_list_prepend (desktop_files, g_strdup (desktop_file)); | ||
483 | 1676 | } | ||
484 | 1585 | } | 1677 | } |
485 | 1586 | } | 1678 | } |
486 | 1587 | } | 1679 | } |
487 | @@ -1589,31 +1681,10 @@ | |||
488 | 1589 | desktop_files = g_list_reverse (desktop_files); | 1681 | desktop_files = g_list_reverse (desktop_files); |
489 | 1590 | } | 1682 | } |
490 | 1591 | 1683 | ||
514 | 1592 | /* Iterate over the desktop class table, and add matching desktop files */ | 1684 | gint pid = bamf_legacy_window_get_pid (window); |
515 | 1593 | gpointer key; | 1685 | GList *pid_list = bamf_matcher_possible_applications_for_pid (self, pid); |
493 | 1594 | gpointer value; | ||
494 | 1595 | GHashTableIter iter; | ||
495 | 1596 | g_hash_table_iter_init (&iter, priv->desktop_class_table); | ||
496 | 1597 | |||
497 | 1598 | while (g_hash_table_iter_next (&iter, &key, &value)) | ||
498 | 1599 | { | ||
499 | 1600 | desktop_file = g_strdup (key); | ||
500 | 1601 | desktop_class = value; | ||
501 | 1602 | if (g_strcmp0 (desktop_class, window_class) == 0 && | ||
502 | 1603 | !g_list_find_custom (desktop_files, desktop_file, (GCompareFunc) g_strcmp0)) | ||
503 | 1604 | { | ||
504 | 1605 | desktop_files = g_list_prepend (desktop_files, desktop_file); | ||
505 | 1606 | } | ||
506 | 1607 | else | ||
507 | 1608 | { | ||
508 | 1609 | g_free (desktop_file); | ||
509 | 1610 | } | ||
510 | 1611 | } | ||
511 | 1612 | |||
512 | 1613 | pid = bamf_legacy_window_get_pid (window); | ||
513 | 1614 | pid_list = bamf_matcher_possible_applications_for_pid (self, pid); | ||
516 | 1615 | 1686 | ||
518 | 1616 | /* Append these files to the end to give preference to window_class style picking. | 1687 | /* Append these files to the end to give preference to class_name style picking. |
519 | 1617 | This style of matching is prefered and used by GNOME Shell however does not work | 1688 | This style of matching is prefered and used by GNOME Shell however does not work |
520 | 1618 | very well in practice, thus requiring the fallback here */ | 1689 | very well in practice, thus requiring the fallback here */ |
521 | 1619 | for (l = pid_list; l; l = l->next) | 1690 | for (l = pid_list; l; l = l->next) |
522 | @@ -1627,10 +1698,10 @@ | |||
523 | 1627 | { | 1698 | { |
524 | 1628 | gboolean append = FALSE; | 1699 | gboolean append = FALSE; |
525 | 1629 | 1700 | ||
527 | 1630 | if (window_class) | 1701 | if (instance_name) |
528 | 1631 | { | 1702 | { |
529 | 1632 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); | 1703 | desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); |
531 | 1633 | if (desktop_class == NULL || g_strcmp0 (desktop_class, window_class) == 0) | 1704 | if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0) |
532 | 1634 | { | 1705 | { |
533 | 1635 | append = TRUE; | 1706 | append = TRUE; |
534 | 1636 | } | 1707 | } |
535 | @@ -1671,7 +1742,12 @@ | |||
536 | 1671 | 1742 | ||
537 | 1672 | g_list_free (pid_list); | 1743 | g_list_free (pid_list); |
538 | 1673 | } | 1744 | } |
540 | 1674 | 1745 | ||
541 | 1746 | if (!desktop_files && known_desktop_class) | ||
542 | 1747 | { | ||
543 | 1748 | desktop_files = bamf_matcher_get_class_matching_desktop_files (self, instance_name); | ||
544 | 1749 | } | ||
545 | 1750 | |||
546 | 1675 | return desktop_files; | 1751 | return desktop_files; |
547 | 1676 | } | 1752 | } |
548 | 1677 | 1753 | ||
549 | @@ -1681,75 +1757,141 @@ | |||
550 | 1681 | { | 1757 | { |
551 | 1682 | GList *possible_apps, *l; | 1758 | GList *possible_apps, *l; |
552 | 1683 | BamfLegacyWindow *window; | 1759 | BamfLegacyWindow *window; |
557 | 1684 | GList *views, *a; | 1760 | const gchar *app_class; |
558 | 1685 | const char *win_class; | 1761 | const gchar *app_desktop = NULL; |
555 | 1686 | const char *desktop_file; | ||
556 | 1687 | const char *app_class; | ||
559 | 1688 | BamfApplication *app = NULL, *best = NULL; | 1762 | BamfApplication *app = NULL, *best = NULL; |
560 | 1689 | BamfView *view; | ||
561 | 1690 | 1763 | ||
562 | 1691 | g_return_if_fail (BAMF_IS_MATCHER (self)); | 1764 | g_return_if_fail (BAMF_IS_MATCHER (self)); |
563 | 1692 | g_return_if_fail (BAMF_IS_WINDOW (bamf_window)); | 1765 | g_return_if_fail (BAMF_IS_WINDOW (bamf_window)); |
564 | 1693 | 1766 | ||
565 | 1694 | window = bamf_window_get_window (bamf_window); | 1767 | window = bamf_window_get_window (bamf_window); |
566 | 1695 | views = self->priv->views; | ||
567 | 1696 | 1768 | ||
568 | 1697 | possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window); | 1769 | possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window); |
606 | 1698 | win_class = bamf_legacy_window_get_class_name (window); | 1770 | const char *win_instance = bamf_legacy_window_get_class_instance_name (window); |
607 | 1699 | 1771 | const char *win_class_name = bamf_legacy_window_get_class_name (window); | |
608 | 1700 | /* Loop over every application, inside that application see if its .desktop file | 1772 | |
609 | 1701 | * matches with any of our possible hits. If so we match it. If we have no possible hits | 1773 | app_class = win_instance; |
610 | 1702 | * fall back to secondary matching. | 1774 | |
611 | 1703 | */ | 1775 | /* Loop over every possible desktop file that could match the window, and try |
612 | 1704 | for (a = views; a; a = a->next) | 1776 | * to reuse an already-opened window that uses it. |
613 | 1705 | { | 1777 | * Desktop files are ordered by priority, so we try to use the first possible, |
614 | 1706 | view = a->data; | 1778 | * wm_class matching applications have the priority, btw. */ |
615 | 1707 | 1779 | if (possible_apps) | |
616 | 1708 | if (!BAMF_IS_APPLICATION (view)) | 1780 | { |
617 | 1709 | continue; | 1781 | /* primary matching */ |
618 | 1710 | 1782 | for (l = possible_apps; l; l = l->next) | |
619 | 1711 | app = BAMF_APPLICATION (view); | 1783 | { |
620 | 1712 | app_class = bamf_application_get_wmclass (app); | 1784 | const gchar *desktop_file = l->data; |
621 | 1713 | desktop_file = bamf_application_get_desktop_file (app); | 1785 | app = bamf_matcher_get_application_by_desktop_file (self, desktop_file); |
622 | 1714 | 1786 | ||
623 | 1715 | if (possible_apps) | 1787 | if (BAMF_IS_APPLICATION (app)) |
624 | 1716 | { | 1788 | { |
625 | 1717 | /* primary matching */ | 1789 | const gchar *app_desktop_class; |
626 | 1718 | 1790 | app_desktop_class = bamf_application_get_wmclass (app); | |
627 | 1719 | for (l = possible_apps; l; l = l->next) | 1791 | |
628 | 1720 | { | 1792 | if (win_instance && app_desktop_class && strcasecmp (win_instance, app_desktop_class) == 0) |
629 | 1721 | if (g_strcmp0 (desktop_file, l->data) == 0) | 1793 | { |
630 | 1722 | { | 1794 | best = app; |
631 | 1723 | if (!best || !g_strcmp0 (win_class, app_class)) | 1795 | break; |
632 | 1724 | best = app; | 1796 | } |
633 | 1725 | break; | 1797 | else if (!best) |
634 | 1726 | } | 1798 | { |
635 | 1727 | } | 1799 | best = app; |
636 | 1728 | } | 1800 | } |
637 | 1729 | else if (desktop_file == NULL) | 1801 | } |
638 | 1730 | { | 1802 | } |
639 | 1731 | /* secondary matching */ | 1803 | |
640 | 1732 | 1804 | /* If a "best" application has been found, we should check again if the | |
641 | 1733 | if (bamf_application_contains_similar_to_window (app, bamf_window) && (!best || !g_strcmp0 (win_class, app_class))) | 1805 | * desktop file that is going to be used is really the best one we have. |
642 | 1734 | best = app; | 1806 | * To do this, we compare the window class name with the desktop class |
643 | 1807 | * of both candidates to ensure that really is the best one. | ||
644 | 1808 | * This is important to avoid that very-similar (which differ only by | ||
645 | 1809 | * StartupWMClass) running desktop files, would be wrongly used to match | ||
646 | 1810 | * an incompatible window. */ | ||
647 | 1811 | if (BAMF_IS_APPLICATION (best) && possible_apps) | ||
648 | 1812 | { | ||
649 | 1813 | const gchar *best_app_desktop = bamf_application_get_desktop_file (best); | ||
650 | 1814 | const gchar *best_desktop = possible_apps->data; | ||
651 | 1815 | |||
652 | 1816 | if (win_class_name && g_strcmp0 (best_app_desktop, best_desktop) != 0) | ||
653 | 1817 | { | ||
654 | 1818 | const gchar *best_app_class; | ||
655 | 1819 | const gchar *best_desktop_class; | ||
656 | 1820 | |||
657 | 1821 | best_app_class = bamf_application_get_wmclass (best); | ||
658 | 1822 | best_desktop_class = g_hash_table_lookup (self->priv->desktop_class_table, best_desktop); | ||
659 | 1823 | |||
660 | 1824 | /* We compare the two classes using their "distance" from the | ||
661 | 1825 | * desidered class value */ | ||
662 | 1826 | if (best_app_class && best_desktop_class) | ||
663 | 1827 | { | ||
664 | 1828 | int max_chars = strlen (win_class_name); | ||
665 | 1829 | int app_diff = strncasecmp (win_class_name, best_app_class, max_chars); | ||
666 | 1830 | int desktop_diff = strncasecmp (win_class_name, best_desktop_class, max_chars); | ||
667 | 1831 | |||
668 | 1832 | if (abs (desktop_diff) < abs (app_diff)) | ||
669 | 1833 | { | ||
670 | 1834 | best = bamf_matcher_get_application_by_desktop_file (self, best_desktop); | ||
671 | 1835 | app_desktop = best_desktop; | ||
672 | 1836 | } | ||
673 | 1837 | } | ||
674 | 1838 | } | ||
675 | 1839 | } | ||
676 | 1840 | } | ||
677 | 1841 | else | ||
678 | 1842 | { | ||
679 | 1843 | /* secondary matching */ | ||
680 | 1844 | GList *a; | ||
681 | 1845 | BamfView *view; | ||
682 | 1846 | const gchar *app_desktop_class; | ||
683 | 1847 | |||
684 | 1848 | for (a = self->priv->views; a; a = a->next) | ||
685 | 1849 | { | ||
686 | 1850 | view = a->data; | ||
687 | 1851 | |||
688 | 1852 | if (!BAMF_IS_APPLICATION (view)) | ||
689 | 1853 | continue; | ||
690 | 1854 | |||
691 | 1855 | app = BAMF_APPLICATION (view); | ||
692 | 1856 | app_desktop_class = bamf_application_get_wmclass (app); | ||
693 | 1857 | |||
694 | 1858 | if (bamf_application_contains_similar_to_window (app, bamf_window)) | ||
695 | 1859 | { | ||
696 | 1860 | if (win_instance && g_strcmp0 (win_instance, app_desktop_class) == 0) | ||
697 | 1861 | { | ||
698 | 1862 | best = app; | ||
699 | 1863 | break; | ||
700 | 1864 | } | ||
701 | 1865 | else if (!best) | ||
702 | 1866 | { | ||
703 | 1867 | best = app; | ||
704 | 1868 | } | ||
705 | 1869 | } | ||
706 | 1735 | } | 1870 | } |
707 | 1736 | } | 1871 | } |
708 | 1737 | 1872 | ||
709 | 1738 | if (!best) | 1873 | if (!best) |
710 | 1739 | { | 1874 | { |
713 | 1740 | if (possible_apps) | 1875 | if (app_desktop) |
714 | 1741 | best = bamf_application_new_from_desktop_files (possible_apps); | 1876 | { |
715 | 1877 | best = bamf_application_new_from_desktop_file (app_desktop); | ||
716 | 1878 | } | ||
717 | 1879 | else if (possible_apps) | ||
718 | 1880 | { | ||
719 | 1881 | best = bamf_application_new_from_desktop_files (possible_apps); | ||
720 | 1882 | } | ||
721 | 1742 | else | 1883 | else |
726 | 1743 | best = bamf_application_new (); | 1884 | { |
727 | 1744 | 1885 | best = bamf_application_new (); | |
728 | 1745 | bamf_application_set_wmclass (best, win_class); | 1886 | } |
729 | 1746 | 1887 | ||
730 | 1888 | bamf_application_set_wmclass (best, app_class); | ||
731 | 1747 | bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (best)); | 1889 | bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (best)); |
732 | 1748 | } | 1890 | } |
733 | 1749 | 1891 | ||
734 | 1750 | g_list_free_full (possible_apps, g_free); | ||
735 | 1751 | |||
736 | 1752 | bamf_view_add_child (BAMF_VIEW (best), BAMF_VIEW (bamf_window)); | 1892 | bamf_view_add_child (BAMF_VIEW (best), BAMF_VIEW (bamf_window)); |
737 | 1893 | |||
738 | 1894 | g_list_free_full (possible_apps, g_free); | ||
739 | 1753 | } | 1895 | } |
740 | 1754 | 1896 | ||
741 | 1755 | /* Ensures that the window hint is set if a registered pid matches, and that set window hints | 1897 | /* Ensures that the window hint is set if a registered pid matches, and that set window hints |
742 | @@ -1760,7 +1902,7 @@ | |||
743 | 1760 | { | 1902 | { |
744 | 1761 | GArray *pids; | 1903 | GArray *pids; |
745 | 1762 | GHashTable *registered_pids; | 1904 | GHashTable *registered_pids; |
747 | 1763 | char *window_hint = NULL; | 1905 | char *desktop_file_hint = NULL; |
748 | 1764 | gint i, pid; | 1906 | gint i, pid; |
749 | 1765 | gpointer key; | 1907 | gpointer key; |
750 | 1766 | 1908 | ||
751 | @@ -1769,51 +1911,35 @@ | |||
752 | 1769 | 1911 | ||
753 | 1770 | registered_pids = self->priv->registered_pids; | 1912 | registered_pids = self->priv->registered_pids; |
754 | 1771 | 1913 | ||
758 | 1772 | // web apps can end up forcing their parent browsers to match on them, so remove from pid table if this is the case | 1914 | /* Some windows such as web applications shares the pid with their parent |
759 | 1773 | if (is_web_app_window (self, window)) | 1915 | * browser so, we have to ignore them */ |
760 | 1774 | { | 1916 | if (bamf_matcher_window_skips_hint_set (self, window)) |
761 | 1917 | { | ||
762 | 1918 | return; | ||
763 | 1919 | } | ||
764 | 1920 | |||
765 | 1921 | desktop_file_hint = get_window_hint (window, _NET_WM_DESKTOP_FILE); | ||
766 | 1922 | |||
767 | 1923 | if (desktop_file_hint) | ||
768 | 1924 | { | ||
769 | 1925 | /* already set, make sure we know about this | ||
770 | 1926 | * fact for future windows of this applications */ | ||
771 | 1775 | pid = bamf_legacy_window_get_pid (window); | 1927 | pid = bamf_legacy_window_get_pid (window); |
772 | 1776 | 1928 | ||
773 | 1777 | if (pid > 0) | 1929 | if (pid > 0) |
774 | 1778 | { | 1930 | { |
778 | 1779 | gpointer key = GINT_TO_POINTER (pid); | 1931 | key = GINT_TO_POINTER (pid); |
779 | 1780 | const char* result = g_hash_table_lookup (registered_pids, key); | 1932 | |
780 | 1781 | if (result && g_str_has_prefix (result, "/home/")) | 1933 | if (!g_hash_table_lookup (registered_pids, key)) |
781 | 1782 | { | 1934 | { |
783 | 1783 | g_hash_table_remove (registered_pids, key); | 1935 | g_hash_table_insert (registered_pids, key, g_strdup (desktop_file_hint)); |
784 | 1784 | } | 1936 | } |
785 | 1785 | } | 1937 | } |
786 | 1786 | 1938 | ||
787 | 1939 | g_free (desktop_file_hint); | ||
788 | 1787 | return; | 1940 | return; |
789 | 1788 | } | 1941 | } |
790 | 1789 | 1942 | ||
791 | 1790 | window_hint = get_window_hint (window, _NET_WM_DESKTOP_FILE); | ||
792 | 1791 | if (window_hint) | ||
793 | 1792 | { | ||
794 | 1793 | if (window_hint[0] != '\0') | ||
795 | 1794 | { | ||
796 | 1795 | /* already set, make sure we know about this | ||
797 | 1796 | * fact for future windows of this applications */ | ||
798 | 1797 | pid = bamf_legacy_window_get_pid (window); | ||
799 | 1798 | |||
800 | 1799 | if (pid > 0) | ||
801 | 1800 | { | ||
802 | 1801 | key = GINT_TO_POINTER (pid); | ||
803 | 1802 | |||
804 | 1803 | if (!g_hash_table_lookup (registered_pids, key)) | ||
805 | 1804 | { | ||
806 | 1805 | g_hash_table_insert (registered_pids, key, g_strdup (window_hint)); | ||
807 | 1806 | } | ||
808 | 1807 | } | ||
809 | 1808 | |||
810 | 1809 | g_free (window_hint); | ||
811 | 1810 | return; | ||
812 | 1811 | } | ||
813 | 1812 | |||
814 | 1813 | g_free (window_hint); | ||
815 | 1814 | window_hint = NULL; | ||
816 | 1815 | } | ||
817 | 1816 | |||
818 | 1817 | pids = pid_parent_tree (self, bamf_legacy_window_get_pid (window)); | 1943 | pids = pid_parent_tree (self, bamf_legacy_window_get_pid (window)); |
819 | 1818 | 1944 | ||
820 | 1819 | for (i = 0; i < pids->len; i++) | 1945 | for (i = 0; i < pids->len; i++) |
821 | @@ -1821,15 +1947,15 @@ | |||
822 | 1821 | pid = g_array_index (pids, gint, i); | 1947 | pid = g_array_index (pids, gint, i); |
823 | 1822 | key = GINT_TO_POINTER (pid); | 1948 | key = GINT_TO_POINTER (pid); |
824 | 1823 | 1949 | ||
827 | 1824 | window_hint = g_hash_table_lookup (registered_pids, key); | 1950 | desktop_file_hint = g_hash_table_lookup (registered_pids, key); |
828 | 1825 | if (window_hint != NULL && window_hint[0] != '\0') | 1951 | if (desktop_file_hint != NULL && desktop_file_hint[0] != '\0') |
829 | 1826 | break; | 1952 | break; |
830 | 1827 | } | 1953 | } |
831 | 1828 | 1954 | ||
832 | 1829 | g_array_free (pids, TRUE); | 1955 | g_array_free (pids, TRUE); |
833 | 1830 | 1956 | ||
836 | 1831 | if (window_hint) | 1957 | if (desktop_file_hint) |
837 | 1832 | set_window_hint (window, _NET_WM_DESKTOP_FILE, window_hint); | 1958 | set_window_hint (window, _NET_WM_DESKTOP_FILE, desktop_file_hint); |
838 | 1833 | } | 1959 | } |
839 | 1834 | 1960 | ||
840 | 1835 | static void | 1961 | static void |
841 | @@ -1895,13 +2021,6 @@ | |||
842 | 1895 | g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (window), NULL); | 2021 | g_return_val_if_fail (BAMF_IS_LEGACY_WINDOW (window), NULL); |
843 | 1896 | 2022 | ||
844 | 1897 | role = get_window_hint (window, WM_WINDOW_ROLE); | 2023 | role = get_window_hint (window, WM_WINDOW_ROLE); |
845 | 1898 | |||
846 | 1899 | if (role && role[0] == '\0') | ||
847 | 1900 | { | ||
848 | 1901 | g_free (role); | ||
849 | 1902 | role = NULL; | ||
850 | 1903 | } | ||
851 | 1904 | |||
852 | 1905 | exec = g_strconcat ("gnome-control-center", (role ? " " : NULL), role, NULL); | 2024 | exec = g_strconcat ("gnome-control-center", (role ? " " : NULL), role, NULL); |
853 | 1906 | 2025 | ||
854 | 1907 | desktopFileTable = self->priv->desktop_file_table; | 2026 | desktopFileTable = self->priv->desktop_file_table; |
855 | @@ -2013,15 +2132,11 @@ | |||
856 | 2013 | bamf_matcher_setup_indicator_state (BamfMatcher *self, BamfIndicator *indicator) | 2132 | bamf_matcher_setup_indicator_state (BamfMatcher *self, BamfIndicator *indicator) |
857 | 2014 | { | 2133 | { |
858 | 2015 | GList *possible_apps, *l; | 2134 | GList *possible_apps, *l; |
859 | 2016 | GList *views, *a; | ||
860 | 2017 | const char *desktop_file; | 2135 | const char *desktop_file; |
861 | 2018 | BamfApplication *app = NULL, *best = NULL; | 2136 | BamfApplication *app = NULL, *best = NULL; |
862 | 2019 | BamfView *view; | ||
863 | 2020 | 2137 | ||
864 | 2021 | g_return_if_fail (BAMF_IS_MATCHER (self)); | 2138 | g_return_if_fail (BAMF_IS_MATCHER (self)); |
865 | 2022 | g_return_if_fail (BAMF_IS_INDICATOR (indicator)); | 2139 | g_return_if_fail (BAMF_IS_INDICATOR (indicator)); |
866 | 2023 | |||
867 | 2024 | views = self->priv->views; | ||
868 | 2025 | 2140 | ||
869 | 2026 | possible_apps = bamf_matcher_possible_applications_for_pid (self, bamf_indicator_get_pid (indicator)); | 2141 | possible_apps = bamf_matcher_possible_applications_for_pid (self, bamf_indicator_get_pid (indicator)); |
870 | 2027 | 2142 | ||
871 | @@ -2029,27 +2144,17 @@ | |||
872 | 2029 | * matches with any of our possible hits. If so we match it. If we have no possible hits | 2144 | * matches with any of our possible hits. If so we match it. If we have no possible hits |
873 | 2030 | * fall back to secondary matching. | 2145 | * fall back to secondary matching. |
874 | 2031 | */ | 2146 | */ |
876 | 2032 | for (a = views; a && !best; a = a->next) | 2147 | if (possible_apps) |
877 | 2033 | { | 2148 | { |
887 | 2034 | view = a->data; | 2149 | for (l = possible_apps; l; l = l->next) |
879 | 2035 | |||
880 | 2036 | if (!BAMF_IS_APPLICATION (view)) | ||
881 | 2037 | continue; | ||
882 | 2038 | |||
883 | 2039 | app = BAMF_APPLICATION (view); | ||
884 | 2040 | desktop_file = bamf_application_get_desktop_file (app); | ||
885 | 2041 | |||
886 | 2042 | if (possible_apps) | ||
888 | 2043 | { | 2150 | { |
890 | 2044 | /* primary matching */ | 2151 | desktop_file = l->data; |
891 | 2152 | app = bamf_matcher_get_application_by_desktop_file (self, desktop_file); | ||
892 | 2045 | 2153 | ||
894 | 2046 | for (l = possible_apps; l; l = l->next) | 2154 | if (BAMF_IS_APPLICATION (app)) |
895 | 2047 | { | 2155 | { |
901 | 2048 | if (g_strcmp0 (desktop_file, l->data) == 0) | 2156 | best = app; |
902 | 2049 | { | 2157 | break; |
898 | 2050 | best = app; | ||
899 | 2051 | break; | ||
900 | 2052 | } | ||
903 | 2053 | } | 2158 | } |
904 | 2054 | } | 2159 | } |
905 | 2055 | } | 2160 | } |
906 | @@ -2270,6 +2375,7 @@ | |||
907 | 2270 | } | 2375 | } |
908 | 2271 | } | 2376 | } |
909 | 2272 | 2377 | ||
910 | 2378 | g_list_free (windows); | ||
911 | 2273 | g_variant_builder_close (&b); | 2379 | g_variant_builder_close (&b); |
912 | 2274 | 2380 | ||
913 | 2275 | return g_variant_builder_end (&b); | 2381 | return g_variant_builder_end (&b); |
914 | @@ -2279,27 +2385,15 @@ | |||
915 | 2279 | bamf_matcher_application_is_running (BamfMatcher *matcher, | 2385 | bamf_matcher_application_is_running (BamfMatcher *matcher, |
916 | 2280 | const char *application) | 2386 | const char *application) |
917 | 2281 | { | 2387 | { |
922 | 2282 | const char * desktop_file; | 2388 | BamfApplication *app; |
919 | 2283 | GList *l; | ||
920 | 2284 | BamfView *view; | ||
921 | 2285 | BamfMatcherPrivate *priv; | ||
923 | 2286 | 2389 | ||
924 | 2287 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), FALSE); | 2390 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), FALSE); |
925 | 2288 | 2391 | ||
927 | 2289 | priv = matcher->priv; | 2392 | app = bamf_matcher_get_application_by_desktop_file (matcher, application); |
928 | 2290 | 2393 | ||
930 | 2291 | for (l = priv->views; l; l = l->next) | 2394 | if (BAMF_IS_APPLICATION (app)) |
931 | 2292 | { | 2395 | { |
942 | 2293 | view = l->data; | 2396 | return bamf_view_is_running (BAMF_VIEW (app)); |
933 | 2294 | |||
934 | 2295 | if (!BAMF_IS_APPLICATION (view)) | ||
935 | 2296 | continue; | ||
936 | 2297 | |||
937 | 2298 | desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view)); | ||
938 | 2299 | if (g_strcmp0 (desktop_file, application) == 0) | ||
939 | 2300 | { | ||
940 | 2301 | return bamf_view_is_running (view); | ||
941 | 2302 | } | ||
943 | 2303 | } | 2397 | } |
944 | 2304 | 2398 | ||
945 | 2305 | return FALSE; | 2399 | return FALSE; |
946 | @@ -2370,27 +2464,15 @@ | |||
947 | 2370 | const char *application) | 2464 | const char *application) |
948 | 2371 | { | 2465 | { |
949 | 2372 | const char * path = ""; | 2466 | const char * path = ""; |
954 | 2373 | const char * desktop_file; | 2467 | BamfApplication *app; |
951 | 2374 | GList *l; | ||
952 | 2375 | BamfView *view; | ||
953 | 2376 | BamfMatcherPrivate *priv; | ||
955 | 2377 | 2468 | ||
956 | 2378 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL); | 2469 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL); |
957 | 2379 | 2470 | ||
959 | 2380 | priv = matcher->priv; | 2471 | app = bamf_matcher_get_application_by_desktop_file (matcher, application); |
960 | 2381 | 2472 | ||
962 | 2382 | for (l = priv->views; l; l = l->next) | 2473 | if (BAMF_IS_APPLICATION (app)) |
963 | 2383 | { | 2474 | { |
974 | 2384 | view = l->data; | 2475 | return bamf_view_get_path (BAMF_VIEW (app)); |
965 | 2385 | |||
966 | 2386 | if (!BAMF_IS_APPLICATION (view)) | ||
967 | 2387 | continue; | ||
968 | 2388 | |||
969 | 2389 | desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view)); | ||
970 | 2390 | if (g_strcmp0 (desktop_file, application) == 0) | ||
971 | 2391 | { | ||
972 | 2392 | path = bamf_view_get_path (view); | ||
973 | 2393 | } | ||
975 | 2394 | } | 2476 | } |
976 | 2395 | 2477 | ||
977 | 2396 | return path; | 2478 | return path; |
978 | @@ -2530,29 +2612,16 @@ | |||
979 | 2530 | { | 2612 | { |
980 | 2531 | GVariantBuilder b; | 2613 | GVariantBuilder b; |
981 | 2532 | GVariant *xids; | 2614 | GVariant *xids; |
986 | 2533 | const char * desktop_file; | 2615 | BamfApplication *app; |
983 | 2534 | GList *l; | ||
984 | 2535 | BamfView *view; | ||
985 | 2536 | BamfMatcherPrivate *priv; | ||
987 | 2537 | 2616 | ||
988 | 2538 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL); | 2617 | g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL); |
989 | 2539 | 2618 | ||
990 | 2540 | priv = matcher->priv; | ||
991 | 2541 | xids = NULL; | 2619 | xids = NULL; |
992 | 2620 | app = bamf_matcher_get_application_by_desktop_file (matcher, application); | ||
993 | 2542 | 2621 | ||
995 | 2543 | for (l = priv->views; l; l = l->next) | 2622 | if (BAMF_IS_APPLICATION (app)) |
996 | 2544 | { | 2623 | { |
1008 | 2545 | view = l->data; | 2624 | xids = bamf_application_get_xids (app); |
998 | 2546 | |||
999 | 2547 | if (!BAMF_IS_APPLICATION (view)) | ||
1000 | 2548 | continue; | ||
1001 | 2549 | |||
1002 | 2550 | desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view)); | ||
1003 | 2551 | if (g_strcmp0 (desktop_file, application) == 0) | ||
1004 | 2552 | { | ||
1005 | 2553 | xids = bamf_application_get_xids (BAMF_APPLICATION (view)); | ||
1006 | 2554 | break; | ||
1007 | 2555 | } | ||
1009 | 2556 | } | 2625 | } |
1010 | 2557 | 2626 | ||
1011 | 2558 | if (!xids) | 2627 | if (!xids) |
1012 | 2559 | 2628 | ||
1013 | === modified file 'src/bamf-view.c' | |||
1014 | --- src/bamf-view.c 2012-03-16 19:39:34 +0000 | |||
1015 | +++ src/bamf-view.c 2012-04-20 17:39:18 +0000 | |||
1016 | @@ -465,7 +465,9 @@ | |||
1017 | 465 | 465 | ||
1018 | 466 | ifaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (view)); | 466 | ifaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (view)); |
1019 | 467 | 467 | ||
1021 | 468 | for (l = ifaces; l; l = l->next) | 468 | /* The dbus object interface list is in reversed order, we try to export |
1022 | 469 | * the interfaces in bottom to top order (BamfView should be the first) */ | ||
1023 | 470 | for (l = g_list_last(ifaces); l; l = l->prev) | ||
1024 | 469 | { | 471 | { |
1025 | 470 | g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (l->data), | 472 | g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (l->data), |
1026 | 471 | connection, path, &error); | 473 | connection, path, &error); |
1027 | 472 | 474 | ||
1028 | === modified file 'src/bamf-xutils.c' | |||
1029 | --- src/bamf-xutils.c 2012-02-10 20:05:54 +0000 | |||
1030 | +++ src/bamf-xutils.c 2012-04-20 17:39:18 +0000 | |||
1031 | @@ -21,6 +21,29 @@ | |||
1032 | 21 | #include "bamf-xutils.h" | 21 | #include "bamf-xutils.h" |
1033 | 22 | #include <string.h> | 22 | #include <string.h> |
1034 | 23 | 23 | ||
1035 | 24 | static Display * | ||
1036 | 25 | get_xdisplay (gboolean *opened) | ||
1037 | 26 | { | ||
1038 | 27 | Display *xdisplay; | ||
1039 | 28 | xdisplay = gdk_x11_get_default_xdisplay (); | ||
1040 | 29 | |||
1041 | 30 | if (opened) | ||
1042 | 31 | *opened = FALSE; | ||
1043 | 32 | |||
1044 | 33 | if (!xdisplay) | ||
1045 | 34 | { | ||
1046 | 35 | xdisplay = XOpenDisplay (NULL); | ||
1047 | 36 | |||
1048 | 37 | if (xdisplay) | ||
1049 | 38 | { | ||
1050 | 39 | if (opened) | ||
1051 | 40 | *opened = TRUE; | ||
1052 | 41 | } | ||
1053 | 42 | } | ||
1054 | 43 | |||
1055 | 44 | return xdisplay; | ||
1056 | 45 | } | ||
1057 | 46 | |||
1058 | 24 | char * | 47 | char * |
1059 | 25 | bamf_xutils_get_window_hint (Window xid, const char *atom_name, Atom type) | 48 | bamf_xutils_get_window_hint (Window xid, const char *atom_name, Atom type) |
1060 | 26 | { | 49 | { |
1061 | @@ -32,22 +55,17 @@ | |||
1062 | 32 | gulong numItems; | 55 | gulong numItems; |
1063 | 33 | gulong bytesAfter; | 56 | gulong bytesAfter; |
1064 | 34 | unsigned char *buffer; | 57 | unsigned char *buffer; |
1066 | 35 | gboolean close_display = TRUE; | 58 | gboolean close_display = FALSE; |
1067 | 36 | 59 | ||
1068 | 37 | g_return_val_if_fail ((xid != 0), NULL); | 60 | g_return_val_if_fail ((xid != 0), NULL); |
1069 | 38 | g_return_val_if_fail (atom_name, NULL); | 61 | g_return_val_if_fail (atom_name, NULL); |
1070 | 39 | 62 | ||
1072 | 40 | XDisplay = XOpenDisplay (NULL); | 63 | XDisplay = get_xdisplay (&close_display); |
1073 | 64 | |||
1074 | 41 | if (!XDisplay) | 65 | if (!XDisplay) |
1075 | 42 | { | 66 | { |
1084 | 43 | XDisplay = gdk_x11_get_default_xdisplay (); | 67 | g_warning ("%s: Unable to get a valid XDisplay", G_STRFUNC); |
1085 | 44 | if (!XDisplay) | 68 | return NULL; |
1078 | 45 | { | ||
1079 | 46 | g_warning ("%s: Unable to get a valid XDisplay", G_STRFUNC); | ||
1080 | 47 | return hint; | ||
1081 | 48 | } | ||
1082 | 49 | |||
1083 | 50 | close_display = FALSE; | ||
1086 | 51 | } | 69 | } |
1087 | 52 | 70 | ||
1088 | 53 | atom = XInternAtom (XDisplay, atom_name, FALSE); | 71 | atom = XInternAtom (XDisplay, atom_name, FALSE); |
1089 | @@ -70,7 +88,9 @@ | |||
1090 | 70 | 88 | ||
1091 | 71 | if (result == Success && numItems > 0) | 89 | if (result == Success && numItems > 0) |
1092 | 72 | { | 90 | { |
1094 | 73 | hint = g_strdup ((char*) buffer); | 91 | if (buffer && buffer[0] != '\0') |
1095 | 92 | hint = g_strdup ((char*) buffer); | ||
1096 | 93 | |||
1097 | 74 | XFree (buffer); | 94 | XFree (buffer); |
1098 | 75 | } | 95 | } |
1099 | 76 | 96 | ||
1100 | @@ -81,22 +101,18 @@ | |||
1101 | 81 | bamf_xutils_set_window_hint (Window xid, const char *atom_name, Atom type, const char *data) | 101 | bamf_xutils_set_window_hint (Window xid, const char *atom_name, Atom type, const char *data) |
1102 | 82 | { | 102 | { |
1103 | 83 | Display *XDisplay; | 103 | Display *XDisplay; |
1105 | 84 | gboolean close_display = TRUE; | 104 | gboolean close_display = FALSE; |
1106 | 85 | 105 | ||
1107 | 86 | g_return_if_fail (xid != 0); | 106 | g_return_if_fail (xid != 0); |
1108 | 87 | g_return_if_fail (atom_name); | 107 | g_return_if_fail (atom_name); |
1109 | 88 | g_return_if_fail (data); | 108 | g_return_if_fail (data); |
1110 | 89 | 109 | ||
1112 | 90 | XDisplay = XOpenDisplay (NULL); | 110 | XDisplay = get_xdisplay (&close_display); |
1113 | 111 | |||
1114 | 91 | if (!XDisplay) | 112 | if (!XDisplay) |
1115 | 92 | { | 113 | { |
1123 | 93 | XDisplay = gdk_x11_get_default_xdisplay (); | 114 | g_warning ("%s: Unable to get a valid XDisplay", G_STRFUNC); |
1124 | 94 | if (!XDisplay) | 115 | return; |
1118 | 95 | { | ||
1119 | 96 | g_warning ("%s: Unable to get a valid XDisplay", G_STRFUNC); | ||
1120 | 97 | return; | ||
1121 | 98 | } | ||
1122 | 99 | close_display = FALSE; | ||
1125 | 100 | } | 116 | } |
1126 | 101 | 117 | ||
1127 | 102 | XChangeProperty (XDisplay, | 118 | XChangeProperty (XDisplay, |
1128 | @@ -113,3 +129,35 @@ | |||
1129 | 113 | if (close_display) | 129 | if (close_display) |
1130 | 114 | XCloseDisplay (XDisplay); | 130 | XCloseDisplay (XDisplay); |
1131 | 115 | } | 131 | } |
1132 | 132 | |||
1133 | 133 | void | ||
1134 | 134 | bamf_xutils_get_window_class_hints (Window xid, char **class_instance_name, char **class_name) | ||
1135 | 135 | { | ||
1136 | 136 | Display *xdisplay; | ||
1137 | 137 | gboolean close_display = FALSE; | ||
1138 | 138 | |||
1139 | 139 | xdisplay = get_xdisplay (&close_display); | ||
1140 | 140 | |||
1141 | 141 | if (!xdisplay) | ||
1142 | 142 | { | ||
1143 | 143 | g_warning ("%s: Unable to get a valid XDisplay", G_STRFUNC); | ||
1144 | 144 | return; | ||
1145 | 145 | } | ||
1146 | 146 | |||
1147 | 147 | XClassHint class_hint; | ||
1148 | 148 | class_hint.res_name = NULL; | ||
1149 | 149 | class_hint.res_class = NULL; | ||
1150 | 150 | |||
1151 | 151 | XGetClassHint(xdisplay, xid, &class_hint); | ||
1152 | 152 | |||
1153 | 153 | if (class_name && class_hint.res_class && class_hint.res_class[0] != 0) | ||
1154 | 154 | *class_name = g_convert (class_hint.res_class, -1, "utf-8", "iso-8859-1", | ||
1155 | 155 | NULL, NULL, NULL); | ||
1156 | 156 | |||
1157 | 157 | if (class_instance_name && class_hint.res_name && class_hint.res_name[0] != 0) | ||
1158 | 158 | *class_instance_name = g_convert (class_hint.res_name, -1, "utf-8", "iso-8859-1", | ||
1159 | 159 | NULL, NULL, NULL); | ||
1160 | 160 | |||
1161 | 161 | XFree (class_hint.res_class); | ||
1162 | 162 | XFree (class_hint.res_name); | ||
1163 | 163 | } | ||
1164 | 116 | 164 | ||
1165 | === modified file 'src/bamf-xutils.h' | |||
1166 | --- src/bamf-xutils.h 2012-02-10 20:05:54 +0000 | |||
1167 | +++ src/bamf-xutils.h 2012-04-20 17:39:18 +0000 | |||
1168 | @@ -18,8 +18,8 @@ | |||
1169 | 18 | */ | 18 | */ |
1170 | 19 | 19 | ||
1171 | 20 | 20 | ||
1174 | 21 | #ifndef __BAMFXUTILS_H__ | 21 | #ifndef __BAMF_XUTILS_H__ |
1175 | 22 | #define __BAMFXUTILS_H__ | 22 | #define __BAMF_XUTILS_H__ |
1176 | 23 | 23 | ||
1177 | 24 | #include <glib.h> | 24 | #include <glib.h> |
1178 | 25 | #include <X11/Xatom.h> | 25 | #include <X11/Xatom.h> |
1179 | @@ -29,4 +29,6 @@ | |||
1180 | 29 | void bamf_xutils_set_window_hint (Window xid, const char *atom_name, Atom type, const char *data); | 29 | void bamf_xutils_set_window_hint (Window xid, const char *atom_name, Atom type, const char *data); |
1181 | 30 | char* bamf_xutils_get_window_hint (Window xid, const char *atom_name, Atom type); | 30 | char* bamf_xutils_get_window_hint (Window xid, const char *atom_name, Atom type); |
1182 | 31 | 31 | ||
1183 | 32 | void bamf_xutils_get_window_class_hints (Window xid, char **class_instance_name, char **class_name); | ||
1184 | 33 | |||
1185 | 32 | #endif | 34 | #endif |
+1 looks okay