File: | _build/../libvnck/screen.c |
Warning: | line 1088, column 3 Value stored to 'current_col' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* screen object */ |
2 | |
3 | /* |
4 | * Copyright (C) 2001 Havoc Pennington |
5 | * Copyright (C) 2003 Kim Woelders |
6 | * Copyright (C) 2003 Red Hat, Inc. |
7 | * Copyright (C) 2006-2007 Vincent Untz |
8 | * |
9 | * This library is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU Library General Public |
11 | * License as published by the Free Software Foundation; either |
12 | * version 2 of the License, or (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * Library General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Library General Public |
20 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
21 | */ |
22 | |
23 | #undef VNCK_DISABLE_DEPRECATED |
24 | |
25 | #include <config.h> |
26 | |
27 | #include <glib/gi18n-lib.h> |
28 | #include "screen.h" |
29 | #include "window.h" |
30 | #include "workspace.h" |
31 | #include "application.h" |
32 | #include "class-group.h" |
33 | #include "xutils.h" |
34 | #include "private.h" |
35 | #include <cdk/cdk.h> |
36 | #include <cdk/cdkx.h> |
37 | #include <string.h> |
38 | #include <stdlib.h> |
39 | |
40 | /** |
41 | * SECTION:screen |
42 | * @short_description: an object representing a screen. |
43 | * @see_also: #VnckWindow, #VnckWorkspace |
44 | * @stability: Unstable |
45 | * |
46 | * The #VnckScreen represents a physical screen. A screen may consist of |
47 | * multiple monitors which are merged to form a large screen area. The |
48 | * #VnckScreen is at the bottom of the libvnck stack of objects: #VnckWorkspace |
49 | * objects exist a #VnckScreen and #VnckWindow objects are displayed on a |
50 | * #VnckWorkspace. |
51 | * |
52 | * The #VnckScreen corresponds to the notion of |
53 | * <classname>CdkScreen</classname> in CDK. |
54 | * |
55 | * The #VnckScreen objects are always owned by libvnck and must not be |
56 | * referenced or unreferenced. |
57 | */ |
58 | |
59 | #define _NET_WM_ORIENTATION_HORZ0 0 |
60 | #define _NET_WM_ORIENTATION_VERT1 1 |
61 | |
62 | #define _NET_WM_TOPLEFT0 0 |
63 | #define _NET_WM_TOPRIGHT1 1 |
64 | #define _NET_WM_BOTTOMRIGHT2 2 |
65 | #define _NET_WM_BOTTOMLEFT3 3 |
66 | |
67 | static VnckScreen** screens = NULL((void*)0); |
68 | |
69 | struct _VnckScreenPrivate |
70 | { |
71 | int number; |
72 | Window xroot; |
73 | Screen *xscreen; |
74 | |
75 | int orig_event_mask; |
76 | |
77 | /* in map order */ |
78 | GList *mapped_windows; |
79 | /* in stacking order */ |
80 | GList *stacked_windows; |
81 | /* in 0-to-N order */ |
82 | GList *workspaces; |
83 | |
84 | /* previously_active_window is used in tandem with active_window to |
85 | * determine return status of vnck_window_is_most_recently_actived(). |
86 | * These are usually shared for all screens, although this is not guaranteed |
87 | * to be true. |
88 | */ |
89 | VnckWindow *active_window; |
90 | VnckWindow *previously_active_window; |
91 | |
92 | VnckWorkspace *active_workspace; |
93 | |
94 | /* Provides the sorting order number for the next window, to make |
95 | * sure windows remain sorted in the order they appear. |
96 | */ |
97 | gint window_order; |
98 | |
99 | Pixmap bg_pixmap; |
100 | |
101 | char *wm_name; |
102 | |
103 | guint update_handler; |
104 | |
105 | #ifdef HAVE_STARTUP_NOTIFICATION1 |
106 | SnDisplay *sn_display; |
107 | #endif |
108 | |
109 | guint showing_desktop : 1; |
110 | |
111 | guint vertical_workspaces : 1; |
112 | _VnckLayoutCorner starting_corner; |
113 | gint rows_of_workspaces; |
114 | gint columns_of_workspaces; |
115 | |
116 | /* if you add flags, be sure to set them |
117 | * when we create the screen so we get an initial update |
118 | */ |
119 | guint need_update_stack_list : 1; |
120 | guint need_update_workspace_list : 1; |
121 | guint need_update_viewport_settings : 1; |
122 | guint need_update_active_workspace : 1; |
123 | guint need_update_active_window : 1; |
124 | guint need_update_workspace_layout : 1; |
125 | guint need_update_workspace_names : 1; |
126 | guint need_update_bg_pixmap : 1; |
127 | guint need_update_showing_desktop : 1; |
128 | guint need_update_wm : 1; |
129 | }; |
130 | |
131 | G_DEFINE_TYPE_WITH_PRIVATE (VnckScreen, vnck_screen, G_TYPE_OBJECT)static void vnck_screen_init (VnckScreen *self); static void vnck_screen_class_init (VnckScreenClass *klass); static GType vnck_screen_get_type_once (void); static gpointer vnck_screen_parent_class = ((void*)0 ); static gint VnckScreen_private_offset; static void vnck_screen_class_intern_init (gpointer klass) { vnck_screen_parent_class = g_type_class_peek_parent (klass); if (VnckScreen_private_offset != 0) g_type_class_adjust_private_offset (klass, &VnckScreen_private_offset); vnck_screen_class_init ((VnckScreenClass*) klass); } __attribute__ ((__unused__)) static inline gpointer vnck_screen_get_instance_private (VnckScreen *self) { return (((gpointer) ((guint8*) (self) + (glong) (VnckScreen_private_offset )))); } GType vnck_screen_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = vnck_screen_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType vnck_screen_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((( GType) ((20) << (2))), g_intern_static_string ("VnckScreen" ), sizeof (VnckScreenClass), (GClassInitFunc)(void (*)(void)) vnck_screen_class_intern_init, sizeof (VnckScreen), (GInstanceInitFunc )(void (*)(void)) vnck_screen_init, (GTypeFlags) 0); { {{ VnckScreen_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (VnckScreenPrivate )); };} } return g_define_type_id; }; |
132 | |
133 | enum { |
134 | ACTIVE_WINDOW_CHANGED, |
135 | ACTIVE_WORKSPACE_CHANGED, |
136 | WINDOW_STACKING_CHANGED, |
137 | WINDOW_OPENED, |
138 | WINDOW_CLOSED, |
139 | WORKSPACE_CREATED, |
140 | WORKSPACE_DESTROYED, |
141 | APPLICATION_OPENED, |
142 | APPLICATION_CLOSED, |
143 | CLASS_GROUP_OPENED, |
144 | CLASS_GROUP_CLOSED, |
145 | BACKGROUND_CHANGED, |
146 | SHOWING_DESKTOP_CHANGED, |
147 | VIEWPORTS_CHANGED, |
148 | WM_CHANGED, |
149 | LAST_SIGNAL |
150 | }; |
151 | |
152 | static void vnck_screen_finalize (GObject *object); |
153 | |
154 | static void update_client_list (VnckScreen *screen); |
155 | static void update_workspace_list (VnckScreen *screen); |
156 | static void update_viewport_settings (VnckScreen *screen); |
157 | static void update_active_workspace (VnckScreen *screen); |
158 | static void update_active_window (VnckScreen *screen); |
159 | static void update_workspace_layout (VnckScreen *screen); |
160 | static void update_workspace_names (VnckScreen *screen); |
161 | static void update_showing_desktop (VnckScreen *screen); |
162 | |
163 | static void queue_update (VnckScreen *screen); |
164 | static void unqueue_update (VnckScreen *screen); |
165 | static void do_update_now (VnckScreen *screen); |
166 | |
167 | static void emit_active_window_changed (VnckScreen *screen); |
168 | static void emit_active_workspace_changed (VnckScreen *screen, |
169 | VnckWorkspace *previous_space); |
170 | static void emit_window_stacking_changed (VnckScreen *screen); |
171 | static void emit_window_opened (VnckScreen *screen, |
172 | VnckWindow *window); |
173 | static void emit_window_closed (VnckScreen *screen, |
174 | VnckWindow *window); |
175 | static void emit_workspace_created (VnckScreen *screen, |
176 | VnckWorkspace *space); |
177 | static void emit_workspace_destroyed (VnckScreen *screen, |
178 | VnckWorkspace *space); |
179 | static void emit_application_opened (VnckScreen *screen, |
180 | VnckApplication *app); |
181 | static void emit_application_closed (VnckScreen *screen, |
182 | VnckApplication *app); |
183 | static void emit_class_group_opened (VnckScreen *screen, |
184 | VnckClassGroup *class_group); |
185 | static void emit_class_group_closed (VnckScreen *screen, |
186 | VnckClassGroup *class_group); |
187 | static void emit_background_changed (VnckScreen *screen); |
188 | static void emit_showing_desktop_changed (VnckScreen *screen); |
189 | static void emit_viewports_changed (VnckScreen *screen); |
190 | static void emit_wm_changed (VnckScreen *screen); |
191 | |
192 | static guint signals[LAST_SIGNAL] = { 0 }; |
193 | |
194 | static void |
195 | vnck_screen_init (VnckScreen *screen) |
196 | { |
197 | screen->priv = vnck_screen_get_instance_private (screen); |
198 | |
199 | screen->priv->number = -1; |
200 | screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPLEFT; |
201 | screen->priv->rows_of_workspaces = 1; |
202 | screen->priv->columns_of_workspaces = -1; |
203 | } |
204 | |
205 | static void |
206 | vnck_screen_class_init (VnckScreenClass *klass) |
207 | { |
208 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); |
209 | |
210 | _vnck_init (); |
211 | |
212 | object_class->finalize = vnck_screen_finalize; |
213 | |
214 | /** |
215 | * VnckScreen::active-window-changed: |
216 | * @screen: the #VnckScreen which emitted the signal. |
217 | * @previously_active_window: the previously active #VnckWindow before this |
218 | * change. |
219 | * |
220 | * Emitted when the active window on @screen has changed. |
221 | */ |
222 | signals[ACTIVE_WINDOW_CHANGED] = |
223 | g_signal_new ("active_window_changed", |
224 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
225 | G_SIGNAL_RUN_LAST, |
226 | G_STRUCT_OFFSET (VnckScreenClass, active_window_changed)((glong) __builtin_offsetof(VnckScreenClass, active_window_changed )), |
227 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
228 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WINDOW(vnck_window_get_type ())); |
229 | |
230 | /** |
231 | * VnckScreen::active-workspace-changed: |
232 | * @screen: the #VnckScreen which emitted the signal. |
233 | * @previously_active_space: the previously active #VnckWorkspace before this |
234 | * change. |
235 | * |
236 | * Emitted when the active workspace on @screen has changed. |
237 | */ |
238 | signals[ACTIVE_WORKSPACE_CHANGED] = |
239 | g_signal_new ("active_workspace_changed", |
240 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
241 | G_SIGNAL_RUN_LAST, |
242 | G_STRUCT_OFFSET (VnckScreenClass, active_workspace_changed)((glong) __builtin_offsetof(VnckScreenClass, active_workspace_changed )), |
243 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
244 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WORKSPACE(vnck_workspace_get_type ())); |
245 | |
246 | /** |
247 | * VnckScreen::window-stacking-changed: |
248 | * @screen: the #VnckScreen which emitted the signal. |
249 | * |
250 | * Emitted when the stacking order of #VnckWindow on @screen has changed. |
251 | */ |
252 | signals[WINDOW_STACKING_CHANGED] = |
253 | g_signal_new ("window_stacking_changed", |
254 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
255 | G_SIGNAL_RUN_LAST, |
256 | G_STRUCT_OFFSET (VnckScreenClass, window_stacking_changed)((glong) __builtin_offsetof(VnckScreenClass, window_stacking_changed )), |
257 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
258 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
259 | |
260 | /** |
261 | * VnckScreen::window-opened: |
262 | * @screen: the #VnckScreen which emitted the signal. |
263 | * @window: the opened #VnckWindow. |
264 | * |
265 | * Emitted when a new #VnckWindow is opened on @screen. |
266 | */ |
267 | signals[WINDOW_OPENED] = |
268 | g_signal_new ("window_opened", |
269 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
270 | G_SIGNAL_RUN_LAST, |
271 | G_STRUCT_OFFSET (VnckScreenClass, window_opened)((glong) __builtin_offsetof(VnckScreenClass, window_opened)), |
272 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
273 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WINDOW(vnck_window_get_type ())); |
274 | |
275 | /** |
276 | * VnckScreen::window-closed: |
277 | * @screen: the #VnckScreen which emitted the signal. |
278 | * @window: the closed #VnckWindow. |
279 | * |
280 | * Emitted when a #VnckWindow is closed on @screen. |
281 | */ |
282 | signals[WINDOW_CLOSED] = |
283 | g_signal_new ("window_closed", |
284 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
285 | G_SIGNAL_RUN_LAST, |
286 | G_STRUCT_OFFSET (VnckScreenClass, window_closed)((glong) __builtin_offsetof(VnckScreenClass, window_closed)), |
287 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
288 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WINDOW(vnck_window_get_type ())); |
289 | |
290 | /** |
291 | * VnckScreen::workspace-created: |
292 | * @screen: the #VnckScreen which emitted the signal. |
293 | * @space: the workspace that has been created. |
294 | * |
295 | * Emitted when a #VnckWorkspace is created on @screen. |
296 | */ |
297 | signals[WORKSPACE_CREATED] = |
298 | g_signal_new ("workspace_created", |
299 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
300 | G_SIGNAL_RUN_LAST, |
301 | G_STRUCT_OFFSET (VnckScreenClass, workspace_created)((glong) __builtin_offsetof(VnckScreenClass, workspace_created )), |
302 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
303 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WORKSPACE(vnck_workspace_get_type ())); |
304 | |
305 | /** |
306 | * VnckScreen::workspace-destroyed: |
307 | * @screen: the #VnckScreen which emitted the signal. |
308 | * @space: the workspace that has been destroyed. |
309 | * |
310 | * Emitted when a #VnckWorkspace is destroyed on @screen. |
311 | */ |
312 | signals[WORKSPACE_DESTROYED] = |
313 | g_signal_new ("workspace_destroyed", |
314 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
315 | G_SIGNAL_RUN_LAST, |
316 | G_STRUCT_OFFSET (VnckScreenClass, workspace_destroyed)((glong) __builtin_offsetof(VnckScreenClass, workspace_destroyed )), |
317 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
318 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WORKSPACE(vnck_workspace_get_type ())); |
319 | |
320 | /** |
321 | * VnckScreen::application-opened: |
322 | * @screen: the #VnckScreen which emitted the signal. |
323 | * @app: the opened #VnckApplication. |
324 | * |
325 | * Emitted when a new #VnckApplication is opened on @screen. |
326 | */ |
327 | signals[APPLICATION_OPENED] = |
328 | g_signal_new ("application_opened", |
329 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
330 | G_SIGNAL_RUN_LAST, |
331 | G_STRUCT_OFFSET (VnckScreenClass, application_opened)((glong) __builtin_offsetof(VnckScreenClass, application_opened )), |
332 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
333 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_APPLICATION(vnck_application_get_type ())); |
334 | |
335 | /** |
336 | * VnckScreen::application-closed: |
337 | * @screen: the #VnckScreen which emitted the signal. |
338 | * @app: the closed #VnckApplication. |
339 | * |
340 | * Emitted when a #VnckApplication is closed on @screen. |
341 | */ |
342 | signals[APPLICATION_CLOSED] = |
343 | g_signal_new ("application_closed", |
344 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
345 | G_SIGNAL_RUN_LAST, |
346 | G_STRUCT_OFFSET (VnckScreenClass, application_closed)((glong) __builtin_offsetof(VnckScreenClass, application_closed )), |
347 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
348 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_APPLICATION(vnck_application_get_type ())); |
349 | |
350 | /** |
351 | * VnckScreen::class-group-opened: |
352 | * @screen: the #VnckScreen which emitted the signal. |
353 | * @class_group: the opened #VnckClassGroup. |
354 | * |
355 | * Emitted when a new #VnckClassGroup is opened on @screen. |
356 | * |
357 | * Since: 2.20 |
358 | */ |
359 | signals[CLASS_GROUP_OPENED] = |
360 | g_signal_new ("class_group_opened", |
361 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
362 | G_SIGNAL_RUN_LAST, |
363 | G_STRUCT_OFFSET (VnckScreenClass, class_group_opened)((glong) __builtin_offsetof(VnckScreenClass, class_group_opened )), |
364 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
365 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_CLASS_GROUP(vnck_class_group_get_type ())); |
366 | |
367 | /** |
368 | * VnckScreen::class-group-closed: |
369 | * @screen: the #VnckScreen which emitted the signal. |
370 | * @class_group: the closed #VnckClassGroup. |
371 | * |
372 | * Emitted when a #VnckClassGroup is closed on @screen. |
373 | * |
374 | * Since: 2.20 |
375 | */ |
376 | signals[CLASS_GROUP_CLOSED] = |
377 | g_signal_new ("class_group_closed", |
378 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
379 | G_SIGNAL_RUN_LAST, |
380 | G_STRUCT_OFFSET (VnckScreenClass, class_group_closed)((glong) __builtin_offsetof(VnckScreenClass, class_group_closed )), |
381 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
382 | G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_CLASS_GROUP(vnck_class_group_get_type ())); |
383 | |
384 | /** |
385 | * VnckScreen::background-changed: |
386 | * @screen: the #VnckScreen which emitted the signal. |
387 | * |
388 | * Emitted when the background on the root window of @screen has changed. |
389 | */ |
390 | signals[BACKGROUND_CHANGED] = |
391 | g_signal_new ("background_changed", |
392 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
393 | G_SIGNAL_RUN_LAST, |
394 | G_STRUCT_OFFSET (VnckScreenClass, background_changed)((glong) __builtin_offsetof(VnckScreenClass, background_changed )), |
395 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
396 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
397 | |
398 | /** |
399 | * VnckScreen::showing-desktop-changed: |
400 | * @screen: the #VnckScreen which emitted the signal. |
401 | * |
402 | * Emitted when "showing the desktop" mode of @screen is toggled. |
403 | * |
404 | * Since: 2.20 |
405 | */ |
406 | signals[SHOWING_DESKTOP_CHANGED] = |
407 | g_signal_new ("showing_desktop_changed", |
408 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
409 | G_SIGNAL_RUN_LAST, |
410 | G_STRUCT_OFFSET (VnckScreenClass, showing_desktop_changed)((glong) __builtin_offsetof(VnckScreenClass, showing_desktop_changed )), |
411 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
412 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
413 | |
414 | /** |
415 | * VnckScreen::viewports-changed: |
416 | * @screen: the #VnckScreen which emitted the signal. |
417 | * |
418 | * Emitted when a viewport position has changed in a #VnckWorkspace of |
419 | * @screen or when a #VnckWorkspace of @screen gets or loses its viewport. |
420 | * |
421 | * Since: 2.20 |
422 | */ |
423 | signals[VIEWPORTS_CHANGED] = |
424 | g_signal_new ("viewports_changed", |
425 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
426 | G_SIGNAL_RUN_LAST, |
427 | G_STRUCT_OFFSET (VnckScreenClass, viewports_changed)((glong) __builtin_offsetof(VnckScreenClass, viewports_changed )), |
428 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
429 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
430 | |
431 | /** |
432 | * VnckScreen::window-manager-changed: |
433 | * @screen: the #VnckScreen which emitted the signal. |
434 | * |
435 | * Emitted when the window manager on @screen has changed. |
436 | * |
437 | * Since: 2.20 |
438 | */ |
439 | signals[WM_CHANGED] = |
440 | g_signal_new ("window_manager_changed", |
441 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), |
442 | G_SIGNAL_RUN_LAST, |
443 | G_STRUCT_OFFSET (VnckScreenClass, window_manager_changed)((glong) __builtin_offsetof(VnckScreenClass, window_manager_changed )), |
444 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
445 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
446 | } |
447 | |
448 | static void |
449 | vnck_screen_finalize (GObject *object) |
450 | { |
451 | VnckScreen *screen; |
452 | GList *tmp; |
453 | gpointer weak_pointer; |
454 | GTimeVal *testing; |
455 | |
456 | screen = VNCK_SCREEN (object)((((VnckScreen*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((vnck_screen_get_type ())))))); |
457 | |
458 | _vnck_select_input (screen->priv->xscreen, |
459 | screen->priv->xroot, |
460 | screen->priv->orig_event_mask, |
461 | FALSE(0)); |
462 | |
463 | unqueue_update (screen); |
464 | |
465 | for (tmp = screen->priv->stacked_windows; tmp; tmp = tmp->next) |
466 | { |
467 | screen->priv->mapped_windows = g_list_remove (screen->priv->mapped_windows, |
468 | tmp->data); |
469 | _vnck_window_destroy (VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_window_get_type ()))))))); |
470 | } |
471 | |
472 | for (tmp = screen->priv->mapped_windows; tmp; tmp = tmp->next) |
473 | _vnck_window_destroy (VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_window_get_type ()))))))); |
474 | |
475 | for (tmp = screen->priv->workspaces; tmp; tmp = tmp->next) |
476 | g_object_unref (tmp->data); |
477 | |
478 | g_list_free (screen->priv->mapped_windows); |
479 | screen->priv->mapped_windows = NULL((void*)0); |
480 | g_list_free (screen->priv->stacked_windows); |
481 | screen->priv->stacked_windows = NULL((void*)0); |
482 | |
483 | g_list_free (screen->priv->workspaces); |
484 | screen->priv->workspaces = NULL((void*)0); |
485 | |
486 | weak_pointer = &screen->priv->active_window; |
487 | if (screen->priv->active_window != NULL((void*)0)) |
488 | g_object_remove_weak_pointer (G_OBJECT (screen->priv->active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen->priv->active_window)), (((GType) ((20) << (2)))))))), |
489 | weak_pointer); |
490 | screen->priv->active_window = NULL((void*)0); |
491 | |
492 | weak_pointer = &screen->priv->previously_active_window; |
493 | if (screen->priv->previously_active_window != NULL((void*)0)) |
494 | g_object_remove_weak_pointer (G_OBJECT (screen->priv->previously_active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen->priv->previously_active_window)), (((GType ) ((20) << (2)))))))), |
495 | weak_pointer); |
496 | screen->priv->previously_active_window = NULL((void*)0); |
497 | |
498 | g_free (screen->priv->wm_name); |
499 | screen->priv->wm_name = NULL((void*)0); |
500 | |
501 | screens[screen->priv->number] = NULL((void*)0); |
502 | |
503 | #ifdef HAVE_STARTUP_NOTIFICATION1 |
504 | sn_display_unref (screen->priv->sn_display); |
505 | screen->priv->sn_display = NULL((void*)0); |
506 | #endif |
507 | |
508 | G_OBJECT_CLASS (vnck_screen_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((vnck_screen_parent_class)), (((GType) ((20) << (2) )))))))->finalize (object); |
509 | } |
510 | |
511 | #ifdef HAVE_STARTUP_NOTIFICATION1 |
512 | static void |
513 | sn_error_trap_push (SnDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)), |
514 | Display *xdisplay) |
515 | { |
516 | _vnck_error_trap_push (xdisplay); |
517 | } |
518 | |
519 | static void |
520 | sn_error_trap_pop (SnDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)), |
521 | Display *xdisplay) |
522 | { |
523 | _vnck_error_trap_pop (xdisplay); |
524 | } |
525 | #endif /* HAVE_STARTUP_NOTIFICATION */ |
526 | |
527 | static void |
528 | vnck_screen_construct (Display *display, |
529 | VnckScreen *screen, |
530 | int number) |
531 | { |
532 | /* Create the initial state of the screen. */ |
533 | screen->priv->xroot = RootWindow (display, number)((&((_XPrivDisplay)(display))->screens[number])->root ); |
534 | screen->priv->xscreen = ScreenOfDisplay (display, number)(&((_XPrivDisplay)(display))->screens[number]); |
535 | screen->priv->number = number; |
536 | |
537 | #ifdef HAVE_STARTUP_NOTIFICATION1 |
538 | screen->priv->sn_display = sn_display_new (display, |
539 | sn_error_trap_push, |
540 | sn_error_trap_pop); |
541 | #endif |
542 | |
543 | screen->priv->bg_pixmap = None0L; |
544 | |
545 | screen->priv->orig_event_mask = _vnck_select_input (screen->priv->xscreen, |
546 | screen->priv->xroot, |
547 | PropertyChangeMask(1L<<22), |
548 | TRUE(!(0))); |
549 | |
550 | screen->priv->need_update_workspace_list = TRUE(!(0)); |
551 | screen->priv->need_update_stack_list = TRUE(!(0)); |
552 | screen->priv->need_update_viewport_settings = TRUE(!(0)); |
553 | screen->priv->need_update_active_workspace = TRUE(!(0)); |
554 | screen->priv->need_update_active_window = TRUE(!(0)); |
555 | screen->priv->need_update_workspace_layout = TRUE(!(0)); |
556 | screen->priv->need_update_workspace_names = TRUE(!(0)); |
557 | screen->priv->need_update_bg_pixmap = TRUE(!(0)); |
558 | screen->priv->need_update_showing_desktop = TRUE(!(0)); |
559 | screen->priv->need_update_wm = TRUE(!(0)); |
560 | |
561 | queue_update (screen); |
562 | } |
563 | |
564 | /** |
565 | * vnck_screen_get: |
566 | * @index: screen number, starting from 0. |
567 | * |
568 | * Gets the #VnckScreen for a given screen on the default display. |
569 | * |
570 | * Return value: (transfer none): the #VnckScreen for screen @index, or %NULL |
571 | * if no such screen exists. The returned #VnckScreen is owned by libvnck and |
572 | * must not be referenced or unreferenced. |
573 | **/ |
574 | VnckScreen* |
575 | vnck_screen_get (int index) |
576 | { |
577 | Display *display; |
578 | |
579 | display = _vnck_get_default_display (); |
580 | |
581 | g_return_val_if_fail (display != NULL, NULL)do { if ((display != ((void*)0))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "display != NULL"); return (((void*)0)); } } while (0); |
582 | |
583 | if (index >= ScreenCount (display)(((_XPrivDisplay)(display))->nscreens)) |
584 | return NULL((void*)0); |
585 | |
586 | if (screens == NULL((void*)0)) |
587 | { |
588 | screens = g_new0 (VnckScreen*, ScreenCount (display))((VnckScreen* *) g_malloc0_n (((((_XPrivDisplay)(display))-> nscreens)), sizeof (VnckScreen*))); |
589 | _vnck_event_filter_init (); |
590 | } |
591 | |
592 | if (screens[index] == NULL((void*)0)) |
593 | { |
594 | screens[index] = g_object_new (VNCK_TYPE_SCREEN(vnck_screen_get_type ()), NULL((void*)0)); |
595 | |
596 | vnck_screen_construct (display, screens[index], index); |
597 | } |
598 | |
599 | return screens[index]; |
600 | } |
601 | |
602 | VnckScreen* |
603 | _vnck_screen_get_existing (int number) |
604 | { |
605 | Display *display; |
606 | |
607 | display = _vnck_get_default_display (); |
608 | |
609 | g_return_val_if_fail (display != NULL, NULL)do { if ((display != ((void*)0))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "display != NULL"); return (((void*)0)); } } while (0); |
610 | g_return_val_if_fail (number < ScreenCount (display), NULL)do { if ((number < (((_XPrivDisplay)(display))->nscreens ))) { } else { g_return_if_fail_warning ("Vnck", ((const char *) (__func__)), "number < ScreenCount (display)"); return ( ((void*)0)); } } while (0); |
611 | |
612 | if (screens != NULL((void*)0)) |
613 | return screens[number]; |
614 | else |
615 | return NULL((void*)0); |
616 | } |
617 | |
618 | /** |
619 | * vnck_screen_get_default: |
620 | * |
621 | * Gets the default #VnckScreen on the default display. |
622 | * |
623 | * Return value: (transfer none) (nullable): the default #VnckScreen. The returned |
624 | * #VnckScreen is owned by libvnck and must not be referenced or unreferenced. This |
625 | * can return %NULL if not on X11. |
626 | **/ |
627 | VnckScreen* |
628 | vnck_screen_get_default (void) |
629 | { |
630 | int default_screen; |
631 | Display *default_display = _vnck_get_default_display (); |
632 | |
633 | if (default_display == NULL((void*)0)) |
634 | return NULL((void*)0); |
635 | |
636 | default_screen = DefaultScreen (default_display)(((_XPrivDisplay)(default_display))->default_screen); |
637 | |
638 | return vnck_screen_get (default_screen); |
639 | } |
640 | |
641 | /** |
642 | * vnck_screen_get_for_root: |
643 | * @root_window_id: an X window ID. |
644 | * |
645 | * Gets the #VnckScreen for the root window at @root_window_id, or |
646 | * %NULL if no #VnckScreen exists for this root window. |
647 | * |
648 | * This function does not work if vnck_screen_get() was not called for the |
649 | * sought #VnckScreen before, and returns %NULL. |
650 | * |
651 | * Return value: (transfer none): the #VnckScreen for the root window at |
652 | * @root_window_id, or %NULL. The returned #VnckScreen is owned by libvnck and |
653 | * must not be referenced or unreferenced. |
654 | **/ |
655 | VnckScreen* |
656 | vnck_screen_get_for_root (gulong root_window_id) |
657 | { |
658 | int i; |
659 | Display *display; |
660 | |
661 | if (screens == NULL((void*)0)) |
662 | return NULL((void*)0); |
663 | |
664 | i = 0; |
665 | display = _vnck_get_default_display (); |
666 | |
667 | while (i < ScreenCount (display)(((_XPrivDisplay)(display))->nscreens)) |
668 | { |
669 | if (screens[i] != NULL((void*)0) && screens[i]->priv->xroot == root_window_id) |
670 | return screens[i]; |
671 | |
672 | ++i; |
673 | } |
674 | |
675 | return NULL((void*)0); |
676 | } |
677 | |
678 | /** |
679 | * vnck_screen_get_number: |
680 | * @screen: a #VnckScreen. |
681 | * |
682 | * Gets the index of @screen on the display to which it belongs. The first |
683 | * #VnckScreen has an index of 0. |
684 | * |
685 | * Return value: the index of @space on @screen, or -1 on errors. |
686 | * |
687 | * Since: 2.20 |
688 | **/ |
689 | int |
690 | vnck_screen_get_number (VnckScreen *screen) |
691 | { |
692 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (-1); } } while (0); |
693 | |
694 | return screen->priv->number; |
695 | } |
696 | |
697 | /** |
698 | * vnck_screen_get_workspaces: |
699 | * @screen: a #VnckScreen. |
700 | * |
701 | * Gets the list of #VnckWorkspace on @screen. The list is ordered: the |
702 | * first element in the list is the first #VnckWorkspace, etc.. |
703 | * |
704 | * Return value: (element-type VnckWorkspace) (transfer none): the list of |
705 | * #VnckWorkspace on @screen. The list should not be modified nor freed, as it |
706 | * is owned by @screen. |
707 | * |
708 | * Since: 2.20 |
709 | **/ |
710 | GList* |
711 | vnck_screen_get_workspaces (VnckScreen *screen) |
712 | { |
713 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
714 | |
715 | return screen->priv->workspaces; |
716 | } |
717 | |
718 | /** |
719 | * vnck_screen_get_workspace: |
720 | * @screen: a #VnckScreen. |
721 | * @workspace: a workspace index, starting from 0. |
722 | * |
723 | * Gets the #VnckWorkspace numbered @workspace on @screen. |
724 | * |
725 | * Return value: (transfer none): the #VnckWorkspace numbered @workspace on |
726 | * @screen, or %NULL if no such workspace exists. The returned #VnckWorkspace |
727 | * is owned by libvnck and must not be referenced or unreferenced. |
728 | **/ |
729 | VnckWorkspace* |
730 | vnck_screen_get_workspace (VnckScreen *screen, |
731 | int workspace) |
732 | { |
733 | GList *list; |
734 | |
735 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
736 | |
737 | /* We trust this function with property-provided numbers, it |
738 | * must reliably return NULL on bad data |
739 | */ |
740 | list = g_list_nth (screen->priv->workspaces, workspace); |
741 | |
742 | if (list == NULL((void*)0)) |
743 | return NULL((void*)0); |
744 | |
745 | return VNCK_WORKSPACE (list->data)((((VnckWorkspace*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((list->data)), ((vnck_workspace_get_type ())))))); |
746 | } |
747 | |
748 | /** |
749 | * vnck_screen_get_active_workspace: |
750 | * @screen: a #VnckScreen. |
751 | * |
752 | * Gets the active #VnckWorkspace on @screen. May return %NULL sometimes, |
753 | * if libvnck is in a weird state due to the asynchronous nature of the |
754 | * interaction with the window manager. |
755 | * |
756 | * Return value: (transfer none): the active #VnckWorkspace on @screen, or |
757 | * %NULL. The returned #VnckWorkspace is owned by libvnck and must not be |
758 | * referenced or unreferenced. |
759 | **/ |
760 | VnckWorkspace* |
761 | vnck_screen_get_active_workspace (VnckScreen *screen) |
762 | { |
763 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
764 | |
765 | return screen->priv->active_workspace; |
766 | } |
767 | |
768 | /** |
769 | * vnck_screen_get_active_window: |
770 | * @screen: a #VnckScreen. |
771 | * |
772 | * Gets the active #VnckWindow on @screen. May return %NULL sometimes, since |
773 | * not all window managers guarantee that a window is always active. |
774 | * |
775 | * Return value: (transfer none): the active #VnckWindow on @screen, or %NULL. |
776 | * The returned #VnckWindow is owned by libvnck and must not be referenced or |
777 | * unreferenced. |
778 | **/ |
779 | VnckWindow* |
780 | vnck_screen_get_active_window (VnckScreen *screen) |
781 | { |
782 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
783 | |
784 | return screen->priv->active_window; |
785 | } |
786 | |
787 | /** |
788 | * vnck_screen_get_previously_active_window: |
789 | * @screen: a #VnckScreen. |
790 | * |
791 | * Gets the previously active #VnckWindow on @screen. May return %NULL |
792 | * sometimes, since not all window managers guarantee that a window is always |
793 | * active. |
794 | * |
795 | * Return value: (transfer none): the previously active #VnckWindow on @screen, |
796 | * or %NULL. The returned #VnckWindow is owned by libvnck and must not be |
797 | * referenced or unreferenced. |
798 | * |
799 | * Since: 2.8 |
800 | **/ |
801 | VnckWindow* |
802 | vnck_screen_get_previously_active_window (VnckScreen *screen) |
803 | { |
804 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
805 | |
806 | return screen->priv->previously_active_window; |
807 | } |
808 | |
809 | /** |
810 | * vnck_screen_get_windows: |
811 | * @screen: a #VnckScreen. |
812 | * |
813 | * Gets the list of #VnckWindow on @screen. The list is not in a defined |
814 | * order, but should be "stable" (windows should not be reordered in it). |
815 | * However, the stability of the list is established by the window manager, so |
816 | * don't blame libvnck if it breaks down. |
817 | * |
818 | * Return value: (element-type VnckWindow) (transfer none): the list of |
819 | * #VnckWindow on @screen, or %NULL if there is no window on @screen. The list |
820 | * should not be modified nor freed, as it is owned by @screen. |
821 | **/ |
822 | GList* |
823 | vnck_screen_get_windows (VnckScreen *screen) |
824 | { |
825 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
826 | |
827 | return screen->priv->mapped_windows; |
828 | } |
829 | |
830 | /** |
831 | * vnck_screen_get_windows_stacked: |
832 | * @screen: a #VnckScreen. |
833 | * |
834 | * Gets the list of #VnckWindow on @screen in bottom-to-top order. |
835 | * |
836 | * Return value: (element-type VnckWindow) (transfer none): the list of |
837 | * #VnckWindow in stacking order on @screen, or %NULL if there is no window on |
838 | * @screen. The list should not be modified nor freed, as it is owned by |
839 | * @screen. |
840 | **/ |
841 | GList* |
842 | vnck_screen_get_windows_stacked (VnckScreen *screen) |
843 | { |
844 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
845 | |
846 | return screen->priv->stacked_windows; |
847 | } |
848 | |
849 | /** |
850 | * _vnck_screen_get_cdk_screen: |
851 | * @screen: a #VnckScreen. |
852 | * |
853 | * Gets the <classname>CdkScreen</classname referring to the same screen as |
854 | * @screen. |
855 | * |
856 | * Return value: the <classname>CdkScreen</classname referring to the same |
857 | * screen as @screen. |
858 | **/ |
859 | CdkScreen * |
860 | _vnck_screen_get_cdk_screen (VnckScreen *screen) |
861 | { |
862 | Display *display; |
863 | CdkDisplay *cdkdisplay; |
864 | |
865 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
866 | |
867 | display = DisplayOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->display); |
868 | cdkdisplay = _vnck_cdk_display_lookup_from_display (display); |
869 | if (!cdkdisplay) |
870 | return NULL((void*)0); |
871 | |
872 | if (screen->priv->number != 0) |
873 | return NULL((void*)0); |
874 | |
875 | return cdk_display_get_default_screen (cdkdisplay); |
876 | } |
877 | |
878 | /** |
879 | * vnck_screen_force_update: |
880 | * @screen: a #VnckScreen. |
881 | * |
882 | * Synchronously and immediately updates the list of #VnckWindow on @screen. |
883 | * This bypasses the standard update mechanism, where the list of #VnckWindow |
884 | * is updated in the idle loop. |
885 | * |
886 | * This is usually a bad idea for both performance and correctness reasons (to |
887 | * get things right, you need to write model-view code that tracks changes, not |
888 | * get a static list of open windows). However, this function can be useful for |
889 | * small applications that just do something and then exit. |
890 | **/ |
891 | void |
892 | vnck_screen_force_update (VnckScreen *screen) |
893 | { |
894 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
895 | |
896 | do_update_now (screen); |
897 | } |
898 | |
899 | /** |
900 | * vnck_screen_get_workspace_count: |
901 | * @screen: a #VnckScreen. |
902 | * |
903 | * Gets the number of #VnckWorkspace on @screen. |
904 | * |
905 | * Return value: the number of #VnckWorkspace on @screen. |
906 | **/ |
907 | int |
908 | vnck_screen_get_workspace_count (VnckScreen *screen) |
909 | { |
910 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0); |
911 | |
912 | return g_list_length (screen->priv->workspaces); |
913 | } |
914 | |
915 | /** |
916 | * vnck_screen_change_workspace_count: |
917 | * @screen: a #VnckScreen. |
918 | * @count: the number of #VnckWorkspace to request. |
919 | * |
920 | * Asks the window manager to change the number of #VnckWorkspace on @screen. |
921 | * |
922 | * Since: 2.2 |
923 | **/ |
924 | void |
925 | vnck_screen_change_workspace_count (VnckScreen *screen, |
926 | int count) |
927 | { |
928 | Display *display; |
929 | XEvent xev; |
930 | |
931 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
932 | g_return_if_fail (count >= 1)do { if ((count >= 1)) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "count >= 1"); return ; } } while (0); |
933 | |
934 | display = DisplayOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->display); |
935 | |
936 | xev.xclient.type = ClientMessage33; |
937 | xev.xclient.serial = 0; |
938 | xev.xclient.window = screen->priv->xroot; |
939 | xev.xclient.send_event = True1; |
940 | xev.xclient.display = display; |
941 | xev.xclient.message_type = _vnck_atom_get ("_NET_NUMBER_OF_DESKTOPS")cdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS"); |
942 | xev.xclient.format = 32; |
943 | xev.xclient.data.l[0] = count; |
944 | |
945 | _vnck_error_trap_push (display); |
946 | XSendEvent (display, |
947 | screen->priv->xroot, |
948 | False0, |
949 | SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19), |
950 | &xev); |
951 | _vnck_error_trap_pop (display); |
952 | } |
953 | |
954 | void |
955 | _vnck_screen_process_property_notify (VnckScreen *screen, |
956 | XEvent *xevent) |
957 | { |
958 | /* most frequently-changed properties first */ |
959 | if (xevent->xproperty.atom == |
960 | _vnck_atom_get ("_NET_ACTIVE_WINDOW")cdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW")) |
961 | { |
962 | screen->priv->need_update_active_window = TRUE(!(0)); |
963 | queue_update (screen); |
964 | } |
965 | else if (xevent->xproperty.atom == |
966 | _vnck_atom_get ("_NET_CURRENT_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP")) |
967 | { |
968 | screen->priv->need_update_active_workspace = TRUE(!(0)); |
969 | queue_update (screen); |
970 | } |
971 | else if (xevent->xproperty.atom == |
972 | _vnck_atom_get ("_NET_CLIENT_LIST_STACKING")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST_STACKING") || |
973 | xevent->xproperty.atom == |
974 | _vnck_atom_get ("_NET_CLIENT_LIST")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST")) |
975 | { |
976 | screen->priv->need_update_stack_list = TRUE(!(0)); |
977 | queue_update (screen); |
978 | } |
979 | else if (xevent->xproperty.atom == |
980 | _vnck_atom_get ("_NET_DESKTOP_VIEWPORT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_VIEWPORT")) |
981 | { |
982 | screen->priv->need_update_viewport_settings = TRUE(!(0)); |
983 | queue_update (screen); |
984 | } |
985 | else if (xevent->xproperty.atom == |
986 | _vnck_atom_get ("_NET_DESKTOP_GEOMETRY")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_GEOMETRY")) |
987 | { |
988 | screen->priv->need_update_viewport_settings = TRUE(!(0)); |
989 | queue_update (screen); |
990 | } |
991 | else if (xevent->xproperty.atom == |
992 | _vnck_atom_get ("_NET_NUMBER_OF_DESKTOPS")cdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS")) |
993 | { |
994 | screen->priv->need_update_workspace_list = TRUE(!(0)); |
995 | queue_update (screen); |
996 | } |
997 | else if (xevent->xproperty.atom == |
998 | _vnck_atom_get ("_NET_DESKTOP_LAYOUT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_LAYOUT")) |
999 | { |
1000 | screen->priv->need_update_workspace_layout = TRUE(!(0)); |
1001 | queue_update (screen); |
1002 | } |
1003 | else if (xevent->xproperty.atom == |
1004 | _vnck_atom_get ("_NET_DESKTOP_NAMES")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES")) |
1005 | { |
1006 | screen->priv->need_update_workspace_names = TRUE(!(0)); |
1007 | queue_update (screen); |
1008 | } |
1009 | else if (xevent->xproperty.atom == |
1010 | _vnck_atom_get ("_XROOTPMAP_ID")cdk_x11_get_xatom_by_name ("_XROOTPMAP_ID")) |
1011 | { |
1012 | screen->priv->need_update_bg_pixmap = TRUE(!(0)); |
1013 | queue_update (screen); |
1014 | } |
1015 | else if (xevent->xproperty.atom == |
1016 | _vnck_atom_get ("_NET_SHOWING_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_SHOWING_DESKTOP")) |
1017 | { |
1018 | screen->priv->need_update_showing_desktop = TRUE(!(0)); |
1019 | queue_update (screen); |
1020 | } |
1021 | else if (xevent->xproperty.atom == |
1022 | _vnck_atom_get ("_NET_SUPPORTING_WM_CHECK")cdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK")) |
1023 | { |
1024 | screen->priv->need_update_wm = TRUE(!(0)); |
1025 | queue_update (screen); |
1026 | } |
1027 | } |
1028 | |
1029 | /** |
1030 | * vnck_screen_calc_workspace_layout: |
1031 | * @screen: a #VnckScreen. |
1032 | * @num_workspaces: the number of #VnckWorkspace on @screen, or -1 to let |
1033 | * vnck_screen_calc_workspace_layout() find this number. |
1034 | * @space_index: the index of a #VnckWorkspace. |
1035 | * @layout: return location for the layout of #VnckWorkspace with additional |
1036 | * information. |
1037 | * |
1038 | * Calculates the layout of #VnckWorkspace, with additional information like |
1039 | * the row and column of the #VnckWorkspace with index @space_index. |
1040 | * |
1041 | * Since: 2.12 |
1042 | * Deprecated:2.20: |
1043 | */ |
1044 | /* TODO: when we make this private, remove num_workspaces since we can get it |
1045 | * from screen! */ |
1046 | void |
1047 | vnck_screen_calc_workspace_layout (VnckScreen *screen, |
1048 | int num_workspaces, |
1049 | int space_index, |
1050 | VnckWorkspaceLayout *layout) |
1051 | { |
1052 | int rows, cols; |
1053 | int grid_area; |
1054 | int *grid; |
1055 | int i, r, c; |
1056 | int current_row, current_col; |
1057 | |
1058 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
1059 | g_return_if_fail (layout != NULL)do { if ((layout != ((void*)0))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "layout != NULL"); return ; } } while (0); |
1060 | |
1061 | if (num_workspaces < 0) |
1062 | num_workspaces = vnck_screen_get_workspace_count (screen); |
1063 | |
1064 | rows = screen->priv->rows_of_workspaces; |
1065 | cols = screen->priv->columns_of_workspaces; |
1066 | |
1067 | if (rows <= 0 && cols <= 0) |
1068 | cols = num_workspaces; |
1069 | |
1070 | if (rows <= 0) |
1071 | rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0); |
1072 | if (cols <= 0) |
1073 | cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0); |
1074 | |
1075 | /* paranoia */ |
1076 | if (rows < 1) |
1077 | rows = 1; |
1078 | if (cols < 1) |
1079 | cols = 1; |
1080 | |
1081 | g_assert (rows != 0 && cols != 0)do { if (rows != 0 && cols != 0) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1081, ((const char*) (__func__ )), "rows != 0 && cols != 0"); } while (0); |
1082 | |
1083 | grid_area = rows * cols; |
1084 | |
1085 | grid = g_new (int, grid_area)((int *) g_malloc_n ((grid_area), sizeof (int))); |
1086 | |
1087 | current_row = -1; |
1088 | current_col = -1; |
Value stored to 'current_col' is never read | |
1089 | i = 0; |
1090 | |
1091 | switch (screen->priv->starting_corner) |
1092 | { |
1093 | case VNCK_LAYOUT_CORNER_TOPLEFT: |
1094 | if (screen->priv->vertical_workspaces) |
1095 | { |
1096 | c = 0; |
1097 | while (c < cols) |
1098 | { |
1099 | r = 0; |
1100 | while (r < rows) |
1101 | { |
1102 | grid[r*cols+c] = i; |
1103 | ++i; |
1104 | ++r; |
1105 | } |
1106 | ++c; |
1107 | } |
1108 | } |
1109 | else |
1110 | { |
1111 | r = 0; |
1112 | while (r < rows) |
1113 | { |
1114 | c = 0; |
1115 | while (c < cols) |
1116 | { |
1117 | grid[r*cols+c] = i; |
1118 | ++i; |
1119 | ++c; |
1120 | } |
1121 | ++r; |
1122 | } |
1123 | } |
1124 | break; |
1125 | case VNCK_LAYOUT_CORNER_TOPRIGHT: |
1126 | if (screen->priv->vertical_workspaces) |
1127 | { |
1128 | c = cols - 1; |
1129 | while (c >= 0) |
1130 | { |
1131 | r = 0; |
1132 | while (r < rows) |
1133 | { |
1134 | grid[r*cols+c] = i; |
1135 | ++i; |
1136 | ++r; |
1137 | } |
1138 | --c; |
1139 | } |
1140 | } |
1141 | else |
1142 | { |
1143 | r = 0; |
1144 | while (r < rows) |
1145 | { |
1146 | c = cols - 1; |
1147 | while (c >= 0) |
1148 | { |
1149 | grid[r*cols+c] = i; |
1150 | ++i; |
1151 | --c; |
1152 | } |
1153 | ++r; |
1154 | } |
1155 | } |
1156 | break; |
1157 | case VNCK_LAYOUT_CORNER_BOTTOMLEFT: |
1158 | if (screen->priv->vertical_workspaces) |
1159 | { |
1160 | c = 0; |
1161 | while (c < cols) |
1162 | { |
1163 | r = rows - 1; |
1164 | while (r >= 0) |
1165 | { |
1166 | grid[r*cols+c] = i; |
1167 | ++i; |
1168 | --r; |
1169 | } |
1170 | ++c; |
1171 | } |
1172 | } |
1173 | else |
1174 | { |
1175 | r = rows - 1; |
1176 | while (r >= 0) |
1177 | { |
1178 | c = 0; |
1179 | while (c < cols) |
1180 | { |
1181 | grid[r*cols+c] = i; |
1182 | ++i; |
1183 | ++c; |
1184 | } |
1185 | --r; |
1186 | } |
1187 | } |
1188 | break; |
1189 | case VNCK_LAYOUT_CORNER_BOTTOMRIGHT: |
1190 | if (screen->priv->vertical_workspaces) |
1191 | { |
1192 | c = cols - 1; |
1193 | while (c >= 0) |
1194 | { |
1195 | r = rows - 1; |
1196 | while (r >= 0) |
1197 | { |
1198 | grid[r*cols+c] = i; |
1199 | ++i; |
1200 | --r; |
1201 | } |
1202 | --c; |
1203 | } |
1204 | } |
1205 | else |
1206 | { |
1207 | r = rows - 1; |
1208 | while (r >= 0) |
1209 | { |
1210 | c = cols - 1; |
1211 | while (c >= 0) |
1212 | { |
1213 | grid[r*cols+c] = i; |
1214 | ++i; |
1215 | --c; |
1216 | } |
1217 | --r; |
1218 | } |
1219 | } |
1220 | break; |
1221 | default: |
1222 | break; |
1223 | } |
1224 | |
1225 | current_row = 0; |
1226 | current_col = 0; |
1227 | r = 0; |
1228 | while (r < rows) |
1229 | { |
1230 | c = 0; |
1231 | while (c < cols) |
1232 | { |
1233 | if (grid[r*cols+c] == space_index) |
1234 | { |
1235 | current_row = r; |
1236 | current_col = c; |
1237 | } |
1238 | else if (grid[r*cols+c] >= num_workspaces) |
1239 | { |
1240 | /* flag nonexistent spaces with -1 */ |
1241 | grid[r*cols+c] = -1; |
1242 | } |
1243 | ++c; |
1244 | } |
1245 | ++r; |
1246 | } |
1247 | layout->rows = rows; |
1248 | layout->cols = cols; |
1249 | layout->grid = grid; |
1250 | layout->grid_area = grid_area; |
1251 | layout->current_row = current_row; |
1252 | layout->current_col = current_col; |
1253 | } |
1254 | |
1255 | /** |
1256 | * vnck_screen_free_workspace_layout: |
1257 | * @layout: a #VnckWorkspaceLayout. |
1258 | * |
1259 | * Frees the content of @layout. This does not free @layout itself, so you |
1260 | * might want to free @layout yourself after calling this. |
1261 | * |
1262 | * Since: 2.12 |
1263 | * Deprecated:2.20: |
1264 | */ |
1265 | void |
1266 | vnck_screen_free_workspace_layout (VnckWorkspaceLayout *layout) |
1267 | { |
1268 | g_return_if_fail (layout != NULL)do { if ((layout != ((void*)0))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "layout != NULL"); return ; } } while (0); |
1269 | |
1270 | g_free (layout->grid); |
1271 | } |
1272 | |
1273 | static void |
1274 | set_active_window (VnckScreen *screen, |
1275 | VnckWindow *window) |
1276 | { |
1277 | gpointer weak_pointer; |
1278 | |
1279 | weak_pointer = &screen->priv->active_window; |
1280 | |
1281 | /* we need the weak pointer since the active window might be shared between |
1282 | * two screens, and so the value for one screen might become invalid when |
1283 | * the window is destroyed on another screen */ |
1284 | if (screen->priv->active_window != NULL((void*)0)) |
1285 | g_object_remove_weak_pointer (G_OBJECT (screen->priv->active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen->priv->active_window)), (((GType) ((20) << (2)))))))), |
1286 | weak_pointer); |
1287 | |
1288 | screen->priv->active_window = window; |
1289 | if (screen->priv->active_window != NULL((void*)0)) |
1290 | g_object_add_weak_pointer (G_OBJECT (screen->priv->active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen->priv->active_window)), (((GType) ((20) << (2)))))))), |
1291 | weak_pointer); |
1292 | } |
1293 | |
1294 | static void |
1295 | set_previously_active_window (VnckScreen *screen, |
1296 | VnckWindow *window) |
1297 | { |
1298 | gpointer weak_pointer; |
1299 | |
1300 | weak_pointer = &screen->priv->previously_active_window; |
1301 | |
1302 | /* we need the weak pointer since the active window might be shared between |
1303 | * two screens, and so the value for one screen might become invalid when |
1304 | * the window is destroyed on another screen */ |
1305 | if (screen->priv->previously_active_window != NULL((void*)0)) |
1306 | g_object_remove_weak_pointer (G_OBJECT (screen->priv->previously_active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen->priv->previously_active_window)), (((GType ) ((20) << (2)))))))), |
1307 | weak_pointer); |
1308 | |
1309 | screen->priv->previously_active_window = window; |
1310 | if (screen->priv->previously_active_window != NULL((void*)0)) |
1311 | g_object_add_weak_pointer (G_OBJECT (screen->priv->previously_active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen->priv->previously_active_window)), (((GType ) ((20) << (2)))))))), |
1312 | weak_pointer); |
1313 | } |
1314 | |
1315 | static gboolean |
1316 | lists_equal (GList *a, |
1317 | GList *b) |
1318 | { |
1319 | GList *a_iter; |
1320 | GList *b_iter; |
1321 | |
1322 | a_iter = a; |
1323 | b_iter = b; |
1324 | |
1325 | while (a_iter && b_iter) |
1326 | { |
1327 | if (a_iter->data != b_iter->data) |
1328 | return FALSE(0); |
1329 | |
1330 | a_iter = a_iter->next; |
1331 | b_iter = b_iter->next; |
1332 | } |
1333 | |
1334 | if (a_iter || b_iter) |
1335 | return FALSE(0); |
1336 | |
1337 | return TRUE(!(0)); |
1338 | } |
1339 | |
1340 | static int |
1341 | wincmp (const void *a, |
1342 | const void *b) |
1343 | { |
1344 | const Window *aw = a; |
1345 | const Window *bw = b; |
1346 | |
1347 | if (*aw < *bw) |
1348 | return -1; |
1349 | else if (*aw > *bw) |
1350 | return 1; |
1351 | else |
1352 | return 0; |
1353 | } |
1354 | |
1355 | static gboolean |
1356 | arrays_contain_same_windows (Window *a, |
1357 | int a_len, |
1358 | Window *b, |
1359 | int b_len) |
1360 | { |
1361 | Window *a_tmp; |
1362 | Window *b_tmp; |
1363 | gboolean result; |
1364 | |
1365 | if (a_len != b_len) |
1366 | return FALSE(0); |
1367 | |
1368 | if (a_len == 0) |
1369 | return TRUE(!(0)); /* both are empty */ |
1370 | |
1371 | a_tmp = g_new (Window, a_len)((Window *) g_malloc_n ((a_len), sizeof (Window))); |
1372 | b_tmp = g_new (Window, b_len)((Window *) g_malloc_n ((b_len), sizeof (Window))); |
1373 | |
1374 | memcpy (a_tmp, a, a_len * sizeof (Window)); |
1375 | memcpy (b_tmp, b, b_len * sizeof (Window)); |
1376 | |
1377 | qsort (a_tmp, a_len, sizeof (Window), wincmp); |
1378 | qsort (b_tmp, b_len, sizeof (Window), wincmp); |
1379 | |
1380 | result = memcmp (a_tmp, b_tmp, sizeof (Window) * a_len) == 0; |
1381 | |
1382 | g_free (a_tmp); |
1383 | g_free (b_tmp); |
1384 | |
1385 | return result; |
1386 | } |
1387 | |
1388 | static void |
1389 | update_client_list (VnckScreen *screen) |
1390 | { |
1391 | /* stacking order */ |
1392 | Window *stack; |
1393 | int stack_length; |
1394 | /* mapping order */ |
1395 | Window *mapping; |
1396 | int mapping_length; |
1397 | GList *new_stack_list; |
1398 | GList *new_list; |
1399 | GList *created; |
1400 | GList *closed; |
1401 | GList *created_apps, *closed_apps; |
1402 | GList *created_class_groups, *closed_class_groups; |
1403 | GList *tmp; |
1404 | int i; |
1405 | GHashTable *new_hash; |
1406 | static int reentrancy_guard = 0; |
1407 | gboolean active_changed; |
1408 | gboolean stack_changed; |
1409 | gboolean list_changed; |
1410 | |
1411 | g_return_if_fail (reentrancy_guard == 0)do { if ((reentrancy_guard == 0)) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "reentrancy_guard == 0" ); return; } } while (0); |
1412 | |
1413 | if (!screen->priv->need_update_stack_list) |
1414 | return; |
1415 | |
1416 | ++reentrancy_guard; |
1417 | |
1418 | screen->priv->need_update_stack_list = FALSE(0); |
1419 | |
1420 | stack = NULL((void*)0); |
1421 | stack_length = 0; |
1422 | _vnck_get_window_list (screen->priv->xscreen, |
1423 | screen->priv->xroot, |
1424 | _vnck_atom_get ("_NET_CLIENT_LIST_STACKING")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST_STACKING"), |
1425 | &stack, |
1426 | &stack_length); |
1427 | |
1428 | mapping = NULL((void*)0); |
1429 | mapping_length = 0; |
1430 | _vnck_get_window_list (screen->priv->xscreen, |
1431 | screen->priv->xroot, |
1432 | _vnck_atom_get ("_NET_CLIENT_LIST")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST"), |
1433 | &mapping, |
1434 | &mapping_length); |
1435 | |
1436 | if (!arrays_contain_same_windows (stack, stack_length, |
1437 | mapping, mapping_length)) |
1438 | { |
1439 | /* Don't update until we're in a consistent state */ |
1440 | g_free (stack); |
1441 | g_free (mapping); |
1442 | --reentrancy_guard; |
1443 | return; |
1444 | } |
1445 | |
1446 | created = NULL((void*)0); |
1447 | closed = NULL((void*)0); |
1448 | created_apps = NULL((void*)0); |
1449 | closed_apps = NULL((void*)0); |
1450 | created_class_groups = NULL((void*)0); |
1451 | closed_class_groups = NULL((void*)0); |
1452 | |
1453 | new_hash = g_hash_table_new (NULL((void*)0), NULL((void*)0)); |
1454 | |
1455 | new_list = NULL((void*)0); |
1456 | i = 0; |
1457 | while (i < mapping_length) |
1458 | { |
1459 | VnckWindow *window; |
1460 | |
1461 | window = vnck_window_get (mapping[i]); |
1462 | |
1463 | if (window == NULL((void*)0)) |
1464 | { |
1465 | Window leader; |
1466 | VnckApplication *app; |
1467 | const char *res_class; |
1468 | VnckClassGroup *class_group; |
1469 | |
1470 | window = _vnck_window_create (mapping[i], |
1471 | screen, |
1472 | screen->priv->window_order++); |
1473 | |
1474 | created = g_list_prepend (created, window); |
1475 | |
1476 | /* Application */ |
1477 | |
1478 | leader = vnck_window_get_group_leader (window); |
1479 | |
1480 | app = vnck_application_get (leader); |
1481 | if (app == NULL((void*)0)) |
1482 | { |
1483 | app = _vnck_application_create (leader, screen); |
1484 | created_apps = g_list_prepend (created_apps, app); |
1485 | } |
1486 | |
1487 | _vnck_application_add_window (app, window); |
1488 | |
1489 | /* Class group */ |
1490 | |
1491 | res_class = vnck_window_get_class_group_name (window); |
1492 | |
1493 | class_group = vnck_class_group_get (res_class); |
1494 | if (class_group == NULL((void*)0)) |
1495 | { |
1496 | class_group = _vnck_class_group_create (screen, res_class); |
1497 | created_class_groups = g_list_prepend (created_class_groups, class_group); |
1498 | } |
1499 | |
1500 | _vnck_class_group_add_window (class_group, window); |
1501 | } |
1502 | |
1503 | new_list = g_list_prepend (new_list, window); |
1504 | |
1505 | g_hash_table_insert (new_hash, window, window); |
1506 | |
1507 | ++i; |
1508 | } |
1509 | |
1510 | /* put list back in order */ |
1511 | new_list = g_list_reverse (new_list); |
1512 | |
1513 | /* Now we need to find windows in the old list that aren't |
1514 | * in this new list |
1515 | */ |
1516 | tmp = screen->priv->mapped_windows; |
1517 | while (tmp != NULL((void*)0)) |
1518 | { |
1519 | VnckWindow *window = tmp->data; |
1520 | |
1521 | if (g_hash_table_lookup (new_hash, window) == NULL((void*)0)) |
1522 | { |
1523 | VnckApplication *app; |
1524 | VnckClassGroup *class_group; |
1525 | |
1526 | closed = g_list_prepend (closed, window); |
1527 | |
1528 | /* Remove from the app */ |
1529 | |
1530 | app = vnck_window_get_application (window); |
1531 | _vnck_application_remove_window (app, window); |
1532 | |
1533 | if (vnck_application_get_windows (app) == NULL((void*)0)) |
1534 | closed_apps = g_list_prepend (closed_apps, app); |
1535 | |
1536 | /* Remove from the class group */ |
1537 | |
1538 | class_group = vnck_window_get_class_group (window); |
1539 | _vnck_class_group_remove_window (class_group, window); |
1540 | |
1541 | if (vnck_class_group_get_windows (class_group) == NULL((void*)0)) |
1542 | closed_class_groups = g_list_prepend (closed_class_groups, class_group); |
1543 | } |
1544 | |
1545 | tmp = tmp->next; |
1546 | } |
1547 | |
1548 | g_hash_table_destroy (new_hash); |
1549 | |
1550 | /* Now get the mapping in list form */ |
1551 | new_stack_list = NULL((void*)0); |
1552 | i = 0; |
1553 | while (i < stack_length) |
1554 | { |
1555 | VnckWindow *window; |
1556 | |
1557 | window = vnck_window_get (stack[i]); |
1558 | |
1559 | g_assert (window != NULL)do { if (window != ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1559, ((const char*) (__func__ )), "window != NULL"); } while (0); |
1560 | |
1561 | new_stack_list = g_list_prepend (new_stack_list, window); |
1562 | |
1563 | ++i; |
1564 | } |
1565 | |
1566 | g_free (stack); |
1567 | g_free (mapping); |
1568 | |
1569 | /* put list back in order */ |
1570 | new_stack_list = g_list_reverse (new_stack_list); |
1571 | |
1572 | /* Now new_stack_list becomes screen->priv->stack_windows, new_list |
1573 | * becomes screen->priv->mapped_windows, and we emit the opened/closed |
1574 | * signals as appropriate |
1575 | */ |
1576 | |
1577 | stack_changed = !lists_equal (screen->priv->stacked_windows, new_stack_list); |
1578 | list_changed = !lists_equal (screen->priv->mapped_windows, new_list); |
1579 | |
1580 | if (!(stack_changed || list_changed)) |
1581 | { |
1582 | g_assert (created == NULL)do { if (created == ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1582, ((const char*) (__func__ )), "created == NULL"); } while (0); |
1583 | g_assert (closed == NULL)do { if (closed == ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1583, ((const char*) (__func__ )), "closed == NULL"); } while (0); |
1584 | g_assert (created_apps == NULL)do { if (created_apps == ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1584, ((const char*) (__func__ )), "created_apps == NULL"); } while (0); |
1585 | g_assert (closed_apps == NULL)do { if (closed_apps == ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1585, ((const char*) (__func__ )), "closed_apps == NULL"); } while (0); |
1586 | g_assert (created_class_groups == NULL)do { if (created_class_groups == ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1586, ((const char*) (__func__ )), "created_class_groups == NULL"); } while (0); |
1587 | g_assert (closed_class_groups == NULL)do { if (closed_class_groups == ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1587, ((const char*) (__func__ )), "closed_class_groups == NULL"); } while (0); |
1588 | g_list_free (new_stack_list); |
1589 | g_list_free (new_list); |
1590 | --reentrancy_guard; |
1591 | return; |
1592 | } |
1593 | |
1594 | g_list_free (screen->priv->mapped_windows); |
1595 | g_list_free (screen->priv->stacked_windows); |
1596 | screen->priv->mapped_windows = new_list; |
1597 | screen->priv->stacked_windows = new_stack_list; |
1598 | |
1599 | /* Here we could get reentrancy if someone ran the main loop in |
1600 | * signal callbacks; though that would be a bit pathological, so we |
1601 | * don't handle it, but we do warn about it using reentrancy_guard |
1602 | */ |
1603 | |
1604 | /* Sequence is: class_group_opened, application_opened, window_opened, |
1605 | * window_closed, application_closed, class_group_closed. We have to do all |
1606 | * window list changes BEFORE doing any other signals, so that any observers |
1607 | * have valid state for the window structure before they take further action |
1608 | */ |
1609 | for (tmp = created_class_groups; tmp; tmp = tmp->next) |
1610 | emit_class_group_opened (screen, VNCK_CLASS_GROUP (tmp->data)((((VnckClassGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_class_group_get_type ()))))))); |
1611 | |
1612 | for (tmp = created_apps; tmp; tmp = tmp->next) |
1613 | emit_application_opened (screen, VNCK_APPLICATION (tmp->data)((((VnckApplication*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_application_get_type ()))))))); |
1614 | |
1615 | for (tmp = created; tmp; tmp = tmp->next) |
1616 | emit_window_opened (screen, VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_window_get_type ()))))))); |
1617 | |
1618 | active_changed = FALSE(0); |
1619 | for (tmp = closed; tmp; tmp = tmp->next) |
1620 | { |
1621 | VnckWindow *window; |
1622 | |
1623 | window = VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_window_get_type ())))))); |
1624 | |
1625 | if (window == screen->priv->previously_active_window) |
1626 | { |
1627 | set_previously_active_window (screen, NULL((void*)0)); |
1628 | } |
1629 | |
1630 | if (window == screen->priv->active_window) |
1631 | { |
1632 | set_previously_active_window (screen, screen->priv->active_window); |
1633 | set_active_window (screen, NULL((void*)0)); |
1634 | active_changed = TRUE(!(0)); |
1635 | } |
1636 | |
1637 | emit_window_closed (screen, window); |
1638 | } |
1639 | |
1640 | for (tmp = closed_apps; tmp; tmp = tmp->next) |
1641 | emit_application_closed (screen, VNCK_APPLICATION (tmp->data)((((VnckApplication*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_application_get_type ()))))))); |
1642 | |
1643 | for (tmp = closed_class_groups; tmp; tmp = tmp->next) |
1644 | emit_class_group_closed (screen, VNCK_CLASS_GROUP (tmp->data)((((VnckClassGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_class_group_get_type ()))))))); |
1645 | |
1646 | if (stack_changed) |
1647 | emit_window_stacking_changed (screen); |
1648 | |
1649 | if (active_changed) |
1650 | emit_active_window_changed (screen); |
1651 | |
1652 | /* Now free the closed windows */ |
1653 | for (tmp = closed; tmp; tmp = tmp->next) |
1654 | _vnck_window_destroy (VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_window_get_type ()))))))); |
1655 | |
1656 | /* Free the closed apps */ |
1657 | for (tmp = closed_apps; tmp; tmp = tmp->next) |
1658 | _vnck_application_destroy (VNCK_APPLICATION (tmp->data)((((VnckApplication*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_application_get_type ()))))))); |
1659 | |
1660 | /* Free the closed class groups */ |
1661 | for (tmp = closed_class_groups; tmp; tmp = tmp->next) |
1662 | _vnck_class_group_destroy (VNCK_CLASS_GROUP (tmp->data)((((VnckClassGroup*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_class_group_get_type ()))))))); |
1663 | |
1664 | g_list_free (closed); |
1665 | g_list_free (created); |
1666 | g_list_free (closed_apps); |
1667 | g_list_free (created_apps); |
1668 | g_list_free (closed_class_groups); |
1669 | g_list_free (created_class_groups); |
1670 | |
1671 | --reentrancy_guard; |
1672 | |
1673 | /* Maybe the active window is now valid if it wasn't */ |
1674 | if (screen->priv->active_window == NULL((void*)0)) |
1675 | { |
1676 | screen->priv->need_update_active_window = TRUE(!(0)); |
1677 | queue_update (screen); |
1678 | } |
1679 | } |
1680 | |
1681 | static void |
1682 | update_workspace_list (VnckScreen *screen) |
1683 | { |
1684 | int n_spaces; |
1685 | int old_n_spaces; |
1686 | GList *tmp; |
1687 | GList *deleted; |
1688 | GList *created; |
1689 | static int reentrancy_guard = 0; |
1690 | |
1691 | g_return_if_fail (reentrancy_guard == 0)do { if ((reentrancy_guard == 0)) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "reentrancy_guard == 0" ); return; } } while (0); |
1692 | |
1693 | if (!screen->priv->need_update_workspace_list) |
1694 | return; |
1695 | |
1696 | screen->priv->need_update_workspace_list = FALSE(0); |
1697 | |
1698 | ++reentrancy_guard; |
1699 | |
1700 | n_spaces = 0; |
1701 | if (!_vnck_get_cardinal (screen->priv->xscreen, |
1702 | screen->priv->xroot, |
1703 | _vnck_atom_get ("_NET_NUMBER_OF_DESKTOPS")cdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS"), |
1704 | &n_spaces)) |
1705 | n_spaces = 1; |
1706 | |
1707 | if (n_spaces <= 0) |
1708 | { |
1709 | g_warning ("Someone set a weird number of desktops in _NET_NUMBER_OF_DESKTOPS, assuming the value is 1\n"); |
1710 | n_spaces = 1; |
1711 | } |
1712 | |
1713 | old_n_spaces = g_list_length (screen->priv->workspaces); |
1714 | |
1715 | deleted = NULL((void*)0); |
1716 | created = NULL((void*)0); |
1717 | |
1718 | if (old_n_spaces == n_spaces) |
1719 | { |
1720 | --reentrancy_guard; |
1721 | return; /* nothing changed */ |
1722 | } |
1723 | else if (old_n_spaces > n_spaces) |
1724 | { |
1725 | /* Need to delete some workspaces */ |
1726 | deleted = g_list_nth (screen->priv->workspaces, n_spaces); |
1727 | if (deleted->prev) |
1728 | deleted->prev->next = NULL((void*)0); |
1729 | deleted->prev = NULL((void*)0); |
1730 | |
1731 | if (deleted == screen->priv->workspaces) |
1732 | screen->priv->workspaces = NULL((void*)0); |
1733 | } |
1734 | else |
1735 | { |
1736 | int i; |
1737 | |
1738 | g_assert (old_n_spaces < n_spaces)do { if (old_n_spaces < n_spaces) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1738, ((const char*) (__func__ )), "old_n_spaces < n_spaces"); } while (0); |
1739 | |
1740 | /* Need to create some workspaces */ |
1741 | i = 0; |
1742 | while (i < (n_spaces - old_n_spaces)) |
1743 | { |
1744 | VnckWorkspace *space; |
1745 | |
1746 | space = _vnck_workspace_create (old_n_spaces + i, screen); |
1747 | |
1748 | screen->priv->workspaces = g_list_append (screen->priv->workspaces, |
1749 | space); |
1750 | |
1751 | created = g_list_prepend (created, space); |
1752 | |
1753 | ++i; |
1754 | } |
1755 | |
1756 | created = g_list_reverse (created); |
1757 | } |
1758 | |
1759 | /* Here we allow reentrancy, going into the main |
1760 | * loop could confuse us |
1761 | */ |
1762 | tmp = deleted; |
1763 | while (tmp != NULL((void*)0)) |
1764 | { |
1765 | VnckWorkspace *space = VNCK_WORKSPACE (tmp->data)((((VnckWorkspace*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_workspace_get_type ())))))); |
1766 | |
1767 | if (space == screen->priv->active_workspace) |
1768 | { |
1769 | screen->priv->active_workspace = NULL((void*)0); |
1770 | emit_active_workspace_changed (screen, space); |
1771 | } |
1772 | |
1773 | emit_workspace_destroyed (screen, space); |
1774 | |
1775 | tmp = tmp->next; |
1776 | } |
1777 | |
1778 | tmp = created; |
1779 | while (tmp != NULL((void*)0)) |
1780 | { |
1781 | emit_workspace_created (screen, VNCK_WORKSPACE (tmp->data)((((VnckWorkspace*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tmp->data)), ((vnck_workspace_get_type ()))))))); |
1782 | |
1783 | tmp = tmp->next; |
1784 | } |
1785 | g_list_free (created); |
1786 | |
1787 | tmp = deleted; |
1788 | while (tmp != NULL((void*)0)) |
1789 | { |
1790 | g_object_unref (tmp->data); |
1791 | |
1792 | tmp = tmp->next; |
1793 | } |
1794 | g_list_free (deleted); |
1795 | |
1796 | /* Active workspace property may now be interpretable, |
1797 | * if it was a number larger than the active count previously |
1798 | */ |
1799 | if (screen->priv->active_workspace == NULL((void*)0)) |
1800 | { |
1801 | screen->priv->need_update_active_workspace = TRUE(!(0)); |
1802 | queue_update (screen); |
1803 | } |
1804 | |
1805 | --reentrancy_guard; |
1806 | } |
1807 | |
1808 | static void |
1809 | update_viewport_settings (VnckScreen *screen) |
1810 | { |
1811 | int i, n_spaces; |
1812 | VnckWorkspace *space; |
1813 | gulong *p_coord; |
1814 | int n_coord; |
1815 | gboolean do_update; |
1816 | int space_width, space_height; |
1817 | gboolean got_viewport_prop; |
1818 | |
1819 | if (!screen->priv->need_update_viewport_settings) |
1820 | return; |
1821 | |
1822 | screen->priv->need_update_viewport_settings = FALSE(0); |
1823 | |
1824 | do_update = FALSE(0); |
1825 | |
1826 | n_spaces = vnck_screen_get_workspace_count (screen); |
1827 | |
1828 | /* If no property, use the screen's size */ |
1829 | space_width = vnck_screen_get_width (screen); |
1830 | space_height = vnck_screen_get_height (screen); |
1831 | |
1832 | p_coord = NULL((void*)0); |
1833 | n_coord = 0; |
1834 | if (_vnck_get_cardinal_list (screen->priv->xscreen, |
1835 | screen->priv->xroot, |
1836 | _vnck_atom_get ("_NET_DESKTOP_GEOMETRY")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_GEOMETRY"), |
1837 | &p_coord, &n_coord) && |
1838 | p_coord != NULL((void*)0)) |
1839 | { |
1840 | if (n_coord == 2) |
1841 | { |
1842 | space_width = p_coord[0]; |
1843 | space_height = p_coord[1]; |
1844 | |
1845 | if (space_width < vnck_screen_get_width (screen)) |
1846 | space_width = vnck_screen_get_width (screen); |
1847 | |
1848 | if (space_height < vnck_screen_get_height (screen)) |
1849 | space_height = vnck_screen_get_height (screen); |
1850 | } |
1851 | |
1852 | g_free (p_coord); |
1853 | } |
1854 | |
1855 | for (i = 0; i < n_spaces; i++) |
1856 | { |
1857 | space = vnck_screen_get_workspace (screen, i); |
1858 | g_assert (space != NULL)do { if (space != ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1858, ((const char*) (__func__ )), "space != NULL"); } while (0); |
1859 | |
1860 | if (_vnck_workspace_set_geometry (space, space_width, space_height)) |
1861 | do_update = TRUE(!(0)); |
1862 | } |
1863 | |
1864 | got_viewport_prop = FALSE(0); |
1865 | |
1866 | p_coord = NULL((void*)0); |
1867 | n_coord = 0; |
1868 | if (_vnck_get_cardinal_list (screen->priv->xscreen, |
1869 | screen->priv->xroot, |
1870 | _vnck_atom_get ("_NET_DESKTOP_VIEWPORT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_VIEWPORT"), |
1871 | &p_coord, &n_coord) && |
1872 | p_coord != NULL((void*)0)) |
1873 | { |
1874 | if (n_coord == 2 * n_spaces) |
1875 | { |
1876 | int screen_width, screen_height; |
1877 | |
1878 | got_viewport_prop = TRUE(!(0)); |
1879 | |
1880 | screen_width = vnck_screen_get_width (screen); |
1881 | screen_height = vnck_screen_get_height (screen); |
1882 | |
1883 | for (i = 0; i < n_spaces; i++) |
1884 | { |
1885 | int x = 2 * i; |
1886 | int y = 2 * i + 1; |
1887 | |
1888 | space = vnck_screen_get_workspace (screen, i); |
1889 | g_assert (space != NULL)do { if (space != ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1889, ((const char*) (__func__ )), "space != NULL"); } while (0); |
1890 | |
1891 | /* p_coord[x] is unsigned, and thus >= 0 */ |
1892 | if ((int) p_coord[x] > space_width - screen_width) |
1893 | p_coord[x] = space_width - screen_width; |
1894 | |
1895 | /* p_coord[y] is unsigned, and thus >= 0 */ |
1896 | if ((int) p_coord[y] > space_height - screen_height) |
1897 | p_coord[y] = space_height - screen_height; |
1898 | |
1899 | if (_vnck_workspace_set_viewport (space, |
1900 | p_coord[x], p_coord[y])) |
1901 | do_update = TRUE(!(0)); |
1902 | } |
1903 | } |
1904 | |
1905 | g_free (p_coord); |
1906 | } |
1907 | |
1908 | if (!got_viewport_prop) |
1909 | { |
1910 | for (i = 0; i < n_spaces; i++) |
1911 | { |
1912 | space = vnck_screen_get_workspace (screen, i); |
1913 | g_assert (space != NULL)do { if (space != ((void*)0)) ; else g_assertion_message_expr ("Vnck", "../libvnck/screen.c", 1913, ((const char*) (__func__ )), "space != NULL"); } while (0); |
1914 | |
1915 | if (_vnck_workspace_set_viewport (space, 0, 0)) |
1916 | do_update = TRUE(!(0)); |
1917 | } |
1918 | } |
1919 | |
1920 | if (do_update) |
1921 | emit_viewports_changed (screen); |
1922 | } |
1923 | |
1924 | static void |
1925 | update_active_workspace (VnckScreen *screen) |
1926 | { |
1927 | int number; |
1928 | VnckWorkspace *previous_space; |
1929 | VnckWorkspace *space; |
1930 | |
1931 | if (!screen->priv->need_update_active_workspace) |
1932 | return; |
1933 | |
1934 | screen->priv->need_update_active_workspace = FALSE(0); |
1935 | |
1936 | number = 0; |
1937 | if (!_vnck_get_cardinal (screen->priv->xscreen, |
1938 | screen->priv->xroot, |
1939 | _vnck_atom_get ("_NET_CURRENT_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP"), |
1940 | &number)) |
1941 | number = -1; |
1942 | |
1943 | space = vnck_screen_get_workspace (screen, number); |
1944 | |
1945 | if (space == screen->priv->active_workspace) |
1946 | return; |
1947 | |
1948 | previous_space = screen->priv->active_workspace; |
1949 | screen->priv->active_workspace = space; |
1950 | |
1951 | emit_active_workspace_changed (screen, previous_space); |
1952 | } |
1953 | |
1954 | static void |
1955 | update_active_window (VnckScreen *screen) |
1956 | { |
1957 | VnckWindow *window; |
1958 | Window xwindow; |
1959 | |
1960 | if (!screen->priv->need_update_active_window) |
1961 | return; |
1962 | |
1963 | screen->priv->need_update_active_window = FALSE(0); |
1964 | |
1965 | xwindow = None0L; |
1966 | _vnck_get_window (screen->priv->xscreen, |
1967 | screen->priv->xroot, |
1968 | _vnck_atom_get ("_NET_ACTIVE_WINDOW")cdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"), |
1969 | &xwindow); |
1970 | |
1971 | window = vnck_window_get (xwindow); |
1972 | |
1973 | if (window == screen->priv->active_window) |
1974 | return; |
1975 | |
1976 | set_previously_active_window (screen, screen->priv->active_window); |
1977 | set_active_window (screen, window); |
1978 | |
1979 | emit_active_window_changed (screen); |
1980 | } |
1981 | |
1982 | static void |
1983 | update_workspace_layout (VnckScreen *screen) |
1984 | { |
1985 | gulong *list; |
1986 | int n_items; |
1987 | |
1988 | if (!screen->priv->need_update_workspace_layout) |
1989 | return; |
1990 | |
1991 | screen->priv->need_update_workspace_layout = FALSE(0); |
1992 | |
1993 | list = NULL((void*)0); |
1994 | n_items = 0; |
1995 | if (_vnck_get_cardinal_list (screen->priv->xscreen, |
1996 | screen->priv->xroot, |
1997 | _vnck_atom_get ("_NET_DESKTOP_LAYOUT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_LAYOUT"), |
1998 | &list, |
1999 | &n_items)) |
2000 | { |
2001 | if (n_items == 3 || n_items == 4) |
2002 | { |
2003 | int cols, rows; |
2004 | |
2005 | switch (list[0]) |
2006 | { |
2007 | case _NET_WM_ORIENTATION_HORZ0: |
2008 | screen->priv->vertical_workspaces = FALSE(0); |
2009 | break; |
2010 | case _NET_WM_ORIENTATION_VERT1: |
2011 | screen->priv->vertical_workspaces = TRUE(!(0)); |
2012 | break; |
2013 | default: |
2014 | g_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n"); |
2015 | break; |
2016 | } |
2017 | |
2018 | cols = list[1]; |
2019 | rows = list[2]; |
2020 | |
2021 | if (rows <= 0 && cols <= 0) |
2022 | { |
2023 | g_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols); |
2024 | } |
2025 | else |
2026 | { |
2027 | int num_workspaces; |
2028 | |
2029 | num_workspaces = vnck_screen_get_workspace_count (screen); |
2030 | |
2031 | if (rows > 0) |
2032 | screen->priv->rows_of_workspaces = rows; |
2033 | else |
2034 | screen->priv->rows_of_workspaces = |
2035 | num_workspaces / cols |
2036 | + ((num_workspaces % cols) > 0 ? 1 : 0); |
2037 | |
2038 | if (cols > 0) |
2039 | screen->priv->columns_of_workspaces = cols; |
2040 | else |
2041 | screen->priv->columns_of_workspaces = |
2042 | num_workspaces / rows |
2043 | + ((num_workspaces % rows) > 0 ? 1 : 0); |
2044 | } |
2045 | if (n_items == 4) |
2046 | { |
2047 | switch (list[3]) |
2048 | { |
2049 | case _NET_WM_TOPLEFT0: |
2050 | screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPLEFT; |
2051 | break; |
2052 | case _NET_WM_TOPRIGHT1: |
2053 | screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPRIGHT; |
2054 | break; |
2055 | case _NET_WM_BOTTOMRIGHT2: |
2056 | screen->priv->starting_corner = VNCK_LAYOUT_CORNER_BOTTOMRIGHT; |
2057 | break; |
2058 | case _NET_WM_BOTTOMLEFT3: |
2059 | screen->priv->starting_corner = VNCK_LAYOUT_CORNER_BOTTOMLEFT; |
2060 | break; |
2061 | default: |
2062 | g_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n"); |
2063 | break; |
2064 | } |
2065 | } |
2066 | else |
2067 | screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPLEFT; |
2068 | } |
2069 | else |
2070 | { |
2071 | g_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 (3 is accepted for backwards compat)\n", n_items); |
2072 | } |
2073 | g_free (list); |
2074 | } |
2075 | } |
2076 | |
2077 | static void |
2078 | update_workspace_names (VnckScreen *screen) |
2079 | { |
2080 | char **names; |
2081 | int i; |
2082 | GList *tmp; |
2083 | GList *copy; |
2084 | |
2085 | if (!screen->priv->need_update_workspace_names) |
2086 | return; |
2087 | |
2088 | screen->priv->need_update_workspace_names = FALSE(0); |
2089 | |
2090 | names = _vnck_get_utf8_list (screen->priv->xscreen, |
2091 | screen->priv->xroot, |
2092 | _vnck_atom_get ("_NET_DESKTOP_NAMES")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES")); |
2093 | |
2094 | copy = g_list_copy (screen->priv->workspaces); |
2095 | |
2096 | i = 0; |
2097 | tmp = copy; |
2098 | while (tmp != NULL((void*)0)) |
2099 | { |
2100 | if (names && names[i]) |
2101 | { |
2102 | _vnck_workspace_update_name (tmp->data, names[i]); |
2103 | ++i; |
2104 | } |
2105 | else |
2106 | _vnck_workspace_update_name (tmp->data, NULL((void*)0)); |
2107 | |
2108 | tmp = tmp->next; |
2109 | } |
2110 | |
2111 | g_strfreev (names); |
2112 | |
2113 | g_list_free (copy); |
2114 | } |
2115 | |
2116 | static void |
2117 | update_bg_pixmap (VnckScreen *screen) |
2118 | { |
2119 | Pixmap p; |
2120 | |
2121 | if (!screen->priv->need_update_bg_pixmap) |
2122 | return; |
2123 | |
2124 | screen->priv->need_update_bg_pixmap = FALSE(0); |
2125 | |
2126 | p = None0L; |
2127 | _vnck_get_pixmap (screen->priv->xscreen, |
2128 | screen->priv->xroot, |
2129 | _vnck_atom_get ("_XROOTPMAP_ID")cdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"), |
2130 | &p); |
2131 | /* may have failed, so p may still be None */ |
2132 | |
2133 | screen->priv->bg_pixmap = p; |
2134 | |
2135 | emit_background_changed (screen); |
2136 | } |
2137 | |
2138 | static void |
2139 | update_showing_desktop (VnckScreen *screen) |
2140 | { |
2141 | int showing_desktop; |
2142 | |
2143 | if (!screen->priv->need_update_showing_desktop) |
2144 | return; |
2145 | |
2146 | screen->priv->need_update_showing_desktop = FALSE(0); |
2147 | |
2148 | showing_desktop = FALSE(0); |
2149 | _vnck_get_cardinal (screen->priv->xscreen, |
2150 | screen->priv->xroot, |
2151 | _vnck_atom_get ("_NET_SHOWING_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_SHOWING_DESKTOP"), |
2152 | &showing_desktop); |
2153 | |
2154 | screen->priv->showing_desktop = showing_desktop != 0; |
2155 | |
2156 | emit_showing_desktop_changed (screen); |
2157 | } |
2158 | |
2159 | static void |
2160 | update_wm (VnckScreen *screen) |
2161 | { |
2162 | Window wm_window; |
2163 | |
2164 | if (!screen->priv->need_update_wm) |
2165 | return; |
2166 | |
2167 | screen->priv->need_update_wm = FALSE(0); |
2168 | |
2169 | wm_window = None0L; |
2170 | _vnck_get_window (screen->priv->xscreen, |
2171 | screen->priv->xroot, |
2172 | _vnck_atom_get ("_NET_SUPPORTING_WM_CHECK")cdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK"), |
2173 | &wm_window); |
2174 | |
2175 | g_free (screen->priv->wm_name); |
2176 | |
2177 | if (wm_window != None0L) |
2178 | screen->priv->wm_name = _vnck_get_utf8_property (screen->priv->xscreen, |
2179 | wm_window, |
2180 | _vnck_atom_get ("_NET_WM_NAME")cdk_x11_get_xatom_by_name ("_NET_WM_NAME")); |
2181 | else |
2182 | screen->priv->wm_name = NULL((void*)0); |
2183 | |
2184 | emit_wm_changed (screen); |
2185 | } |
2186 | |
2187 | static void |
2188 | do_update_now (VnckScreen *screen) |
2189 | { |
2190 | if (screen->priv->update_handler) |
2191 | { |
2192 | g_source_remove (screen->priv->update_handler); |
2193 | screen->priv->update_handler = 0; |
2194 | } |
2195 | |
2196 | /* if number of workspaces changes, we have to |
2197 | * update the per-workspace information as well |
2198 | * in case the WM changed the per-workspace info |
2199 | * first and number of spaces second. |
2200 | */ |
2201 | if (screen->priv->need_update_workspace_list) |
2202 | { |
2203 | screen->priv->need_update_viewport_settings = TRUE(!(0)); |
2204 | screen->priv->need_update_workspace_names = TRUE(!(0)); |
2205 | } |
2206 | |
2207 | /* First get our big-picture state in order */ |
2208 | update_workspace_list (screen); |
2209 | update_client_list (screen); |
2210 | |
2211 | /* Then note any smaller-scale changes */ |
2212 | update_active_workspace (screen); |
2213 | update_viewport_settings (screen); |
2214 | update_active_window (screen); |
2215 | update_workspace_layout (screen); |
2216 | update_workspace_names (screen); |
2217 | update_showing_desktop (screen); |
2218 | update_wm (screen); |
2219 | |
2220 | update_bg_pixmap (screen); |
2221 | } |
2222 | |
2223 | static gboolean |
2224 | update_idle (gpointer data) |
2225 | { |
2226 | VnckScreen *screen; |
2227 | |
2228 | screen = data; |
2229 | |
2230 | screen->priv->update_handler = 0; |
2231 | |
2232 | do_update_now (screen); |
2233 | |
2234 | return FALSE(0); |
2235 | } |
2236 | |
2237 | static void |
2238 | queue_update (VnckScreen *screen) |
2239 | { |
2240 | if (screen->priv->update_handler != 0) |
2241 | return; |
2242 | |
2243 | screen->priv->update_handler = g_idle_add (update_idle, screen); |
2244 | } |
2245 | |
2246 | static void |
2247 | unqueue_update (VnckScreen *screen) |
2248 | { |
2249 | if (screen->priv->update_handler != 0) |
2250 | { |
2251 | g_source_remove (screen->priv->update_handler); |
2252 | screen->priv->update_handler = 0; |
2253 | } |
2254 | } |
2255 | |
2256 | static void |
2257 | emit_active_window_changed (VnckScreen *screen) |
2258 | { |
2259 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2260 | signals[ACTIVE_WINDOW_CHANGED], |
2261 | 0, screen->priv->previously_active_window); |
2262 | } |
2263 | |
2264 | static void |
2265 | emit_active_workspace_changed (VnckScreen *screen, |
2266 | VnckWorkspace *previous_space) |
2267 | { |
2268 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2269 | signals[ACTIVE_WORKSPACE_CHANGED], |
2270 | 0, previous_space); |
2271 | } |
2272 | |
2273 | static void |
2274 | emit_window_stacking_changed (VnckScreen *screen) |
2275 | { |
2276 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2277 | signals[WINDOW_STACKING_CHANGED], |
2278 | 0); |
2279 | } |
2280 | |
2281 | static void |
2282 | emit_window_opened (VnckScreen *screen, |
2283 | VnckWindow *window) |
2284 | { |
2285 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2286 | signals[WINDOW_OPENED], |
2287 | 0, window); |
2288 | } |
2289 | |
2290 | static void |
2291 | emit_window_closed (VnckScreen *screen, |
2292 | VnckWindow *window) |
2293 | { |
2294 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2295 | signals[WINDOW_CLOSED], |
2296 | 0, window); |
2297 | } |
2298 | |
2299 | static void |
2300 | emit_workspace_created (VnckScreen *screen, |
2301 | VnckWorkspace *space) |
2302 | { |
2303 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2304 | signals[WORKSPACE_CREATED], |
2305 | 0, space); |
2306 | } |
2307 | |
2308 | static void |
2309 | emit_workspace_destroyed (VnckScreen *screen, |
2310 | VnckWorkspace *space) |
2311 | { |
2312 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2313 | signals[WORKSPACE_DESTROYED], |
2314 | 0, space); |
2315 | } |
2316 | |
2317 | static void |
2318 | emit_application_opened (VnckScreen *screen, |
2319 | VnckApplication *app) |
2320 | { |
2321 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2322 | signals[APPLICATION_OPENED], |
2323 | 0, app); |
2324 | } |
2325 | |
2326 | static void |
2327 | emit_application_closed (VnckScreen *screen, |
2328 | VnckApplication *app) |
2329 | { |
2330 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2331 | signals[APPLICATION_CLOSED], |
2332 | 0, app); |
2333 | } |
2334 | |
2335 | static void |
2336 | emit_class_group_opened (VnckScreen *screen, |
2337 | VnckClassGroup *class_group) |
2338 | { |
2339 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2340 | signals[CLASS_GROUP_OPENED], |
2341 | 0, class_group); |
2342 | } |
2343 | |
2344 | static void |
2345 | emit_class_group_closed (VnckScreen *screen, |
2346 | VnckClassGroup *class_group) |
2347 | { |
2348 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2349 | signals[CLASS_GROUP_CLOSED], |
2350 | 0, class_group); |
2351 | } |
2352 | |
2353 | static void |
2354 | emit_background_changed (VnckScreen *screen) |
2355 | { |
2356 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2357 | signals[BACKGROUND_CHANGED], |
2358 | 0); |
2359 | } |
2360 | |
2361 | static void |
2362 | emit_showing_desktop_changed (VnckScreen *screen) |
2363 | { |
2364 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2365 | signals[SHOWING_DESKTOP_CHANGED], |
2366 | 0); |
2367 | } |
2368 | |
2369 | static void |
2370 | emit_viewports_changed (VnckScreen *screen) |
2371 | { |
2372 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2373 | signals[VIEWPORTS_CHANGED], |
2374 | 0); |
2375 | } |
2376 | |
2377 | static void |
2378 | emit_wm_changed (VnckScreen *screen) |
2379 | { |
2380 | g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((screen)), (((GType) ((20) << (2)))))))), |
2381 | signals[WM_CHANGED], |
2382 | 0); |
2383 | } |
2384 | |
2385 | /** |
2386 | * vnck_screen_get_window_manager_name: |
2387 | * @screen: a #VnckScreen. |
2388 | * |
2389 | * Gets the name of the window manager. |
2390 | * |
2391 | * Return value: the name of the window manager, or %NULL if the window manager |
2392 | * does not comply with the <ulink |
2393 | * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink> |
2394 | * specification. |
2395 | * |
2396 | * Since: 2.20 |
2397 | */ |
2398 | const char * |
2399 | vnck_screen_get_window_manager_name (VnckScreen *screen) |
2400 | { |
2401 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
2402 | |
2403 | return screen->priv->wm_name; |
2404 | } |
2405 | |
2406 | /** |
2407 | * vnck_screen_net_wm_supports: |
2408 | * @screen: a #VnckScreen. |
2409 | * @atom: a property atom. |
2410 | * |
2411 | * Gets whether the window manager for @screen supports a certain hint from |
2412 | * the <ulink |
2413 | * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">Extended |
2414 | * Window Manager Hints specification</ulink> (EWMH). |
2415 | * |
2416 | * When using this function, keep in mind that the window manager can change |
2417 | * over time; so you should not use this function in a way that impacts |
2418 | * persistent application state. A common bug is that your application can |
2419 | * start up before the window manager does when the user logs in, and before |
2420 | * the window manager starts vnck_screen_net_wm_supports() will return %FALSE |
2421 | * for every property. |
2422 | * |
2423 | * See also cdk_x11_screen_supports_net_wm_hint() in CDK. |
2424 | * |
2425 | * Return value: %TRUE if the window manager for @screen supports the @atom |
2426 | * hint, %FALSE otherwise. |
2427 | */ |
2428 | gboolean |
2429 | vnck_screen_net_wm_supports (VnckScreen *screen, |
2430 | const char *atom) |
2431 | { |
2432 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return ((0)); } } while (0); |
2433 | |
2434 | return cdk_x11_screen_supports_net_wm_hint (_vnck_screen_get_cdk_screen (screen), |
2435 | cdk_atom_intern (atom, FALSE(0))); |
2436 | } |
2437 | |
2438 | /** |
2439 | * vnck_screen_get_background_pixmap: |
2440 | * @screen: a #VnckScreen. |
2441 | * |
2442 | * Gets the X window ID of the background pixmap of @screen. |
2443 | * |
2444 | * Returns: the X window ID of the background pixmap of @screen. |
2445 | */ |
2446 | gulong |
2447 | vnck_screen_get_background_pixmap (VnckScreen *screen) |
2448 | { |
2449 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), None)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (0L); } } while (0); |
2450 | |
2451 | return screen->priv->bg_pixmap; |
2452 | } |
2453 | |
2454 | /** |
2455 | * vnck_screen_get_width: |
2456 | * @screen: a #VnckScreen. |
2457 | * |
2458 | * Gets the width of @screen. |
2459 | * |
2460 | * Returns: the width of @screen. |
2461 | */ |
2462 | int |
2463 | vnck_screen_get_width (VnckScreen *screen) |
2464 | { |
2465 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0); |
2466 | |
2467 | return WidthOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->width); |
2468 | } |
2469 | |
2470 | /** |
2471 | * vnck_screen_get_height: |
2472 | * @screen: a #VnckScreen. |
2473 | * |
2474 | * Gets the height of @screen. |
2475 | * |
2476 | * Returns: the height of @screen. |
2477 | */ |
2478 | int |
2479 | vnck_screen_get_height (VnckScreen *screen) |
2480 | { |
2481 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0); |
2482 | |
2483 | return HeightOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->height); |
2484 | } |
2485 | |
2486 | Screen * |
2487 | _vnck_screen_get_xscreen (VnckScreen *screen) |
2488 | { |
2489 | return screen->priv->xscreen; |
2490 | } |
2491 | |
2492 | /** |
2493 | * vnck_screen_get_workspace_layout: |
2494 | * @screen: a #VnckScreen. |
2495 | * @orientation: return location for the orientation used in the #VnckWorkspace |
2496 | * layout. See vnck_pager_set_orientation() for more information. |
2497 | * @rows: return location for the number of rows in the #VnckWorkspace layout. |
2498 | * @columns: return location for the number of columns in the #VnckWorkspace |
2499 | * layout. |
2500 | * @starting_corner: return location for the starting corner in the |
2501 | * #VnckWorkspace layout (i.e. the corner containing the first #VnckWorkspace). |
2502 | * |
2503 | * Gets the layout of #VnckWorkspace on @screen. |
2504 | */ |
2505 | /* TODO: when we are sure about this API, add this function, |
2506 | * VnckLayoutOrientation, VnckLayoutCorner and a "layout-changed" signal. But |
2507 | * to make it really better, use a VnckScreenLayout struct. We might also want |
2508 | * to wait for deprecation of VnckWorkspaceLayout. */ |
2509 | void |
2510 | _vnck_screen_get_workspace_layout (VnckScreen *screen, |
2511 | _VnckLayoutOrientation *orientation, |
2512 | int *rows, |
2513 | int *columns, |
2514 | _VnckLayoutCorner *starting_corner) |
2515 | { |
2516 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
2517 | |
2518 | if (orientation) |
2519 | *orientation = screen->priv->vertical_workspaces ? |
2520 | VNCK_LAYOUT_ORIENTATION_VERTICAL : |
2521 | VNCK_LAYOUT_ORIENTATION_HORIZONTAL; |
2522 | |
2523 | if (rows) |
2524 | *rows = screen->priv->rows_of_workspaces; |
2525 | |
2526 | if (columns) |
2527 | *columns = screen->priv->columns_of_workspaces; |
2528 | |
2529 | if (starting_corner) |
2530 | *starting_corner = screen->priv->starting_corner; |
2531 | } |
2532 | |
2533 | /** |
2534 | * vnck_screen_try_set_workspace_layout: |
2535 | * @screen: a #VnckScreen. |
2536 | * @current_token: a token. Use 0 if you do not called |
2537 | * vnck_screen_try_set_workspace_layout() before, or if you did not keep the |
2538 | * old token. |
2539 | * @rows: the number of rows to use for the #VnckWorkspace layout. |
2540 | * @columns: the number of columns to use for the #VnckWorkspace layout. |
2541 | * |
2542 | * Tries to modify the layout of #VnckWorkspace on @screen. To do this, tries |
2543 | * to acquire ownership of the layout. If the current process is the owner of |
2544 | * the layout, @current_token is used to determine if the caller is the owner |
2545 | * (there might be more than one part of the same process trying to set the |
2546 | * layout). Since no more than one application should set this property of |
2547 | * @screen at a time, setting the layout is not guaranteed to work. |
2548 | * |
2549 | * If @rows is 0, the actual number of rows will be determined based on |
2550 | * @columns and the number of #VnckWorkspace. If @columns is 0, the actual |
2551 | * number of columns will be determined based on @rows and the number of |
2552 | * #VnckWorkspace. @rows and @columns must not be 0 at the same time. |
2553 | * |
2554 | * You have to release the ownership of the layout with |
2555 | * vnck_screen_release_workspace_layout() when you do not need it anymore. |
2556 | * |
2557 | * Return value: a token to use for future calls to |
2558 | * vnck_screen_try_set_workspace_layout() and to |
2559 | * vnck_screen_release_workspace_layout(), or 0 if the layout could not be set. |
2560 | */ |
2561 | int |
2562 | vnck_screen_try_set_workspace_layout (VnckScreen *screen, |
2563 | int current_token, |
2564 | int rows, |
2565 | int columns) |
2566 | { |
2567 | int retval; |
2568 | |
2569 | g_return_val_if_fail (VNCK_IS_SCREEN (screen),do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0) |
2570 | VNCK_NO_MANAGER_TOKEN)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0); |
2571 | g_return_val_if_fail (rows != 0 || columns != 0,do { if ((rows != 0 || columns != 0)) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "rows != 0 || columns != 0" ); return (0); } } while (0) |
2572 | VNCK_NO_MANAGER_TOKEN)do { if ((rows != 0 || columns != 0)) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__)), "rows != 0 || columns != 0" ); return (0); } } while (0); |
2573 | |
2574 | retval = _vnck_try_desktop_layout_manager (screen->priv->xscreen, current_token); |
2575 | |
2576 | if (retval != VNCK_NO_MANAGER_TOKEN0) |
2577 | { |
2578 | _vnck_set_desktop_layout (screen->priv->xscreen, rows, columns); |
2579 | } |
2580 | |
2581 | return retval; |
2582 | } |
2583 | |
2584 | /** |
2585 | * vnck_screen_release_workspace_layout: |
2586 | * @screen: a #VnckScreen. |
2587 | * @current_token: the token obtained through |
2588 | * vnck_screen_try_set_workspace_layout(). |
2589 | * |
2590 | * Releases the ownership of the layout of #VnckWorkspace on @screen. |
2591 | * @current_token is used to verify that the caller is the owner of the layout. |
2592 | * If the verification fails, nothing happens. |
2593 | */ |
2594 | void |
2595 | vnck_screen_release_workspace_layout (VnckScreen *screen, |
2596 | int current_token) |
2597 | { |
2598 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
2599 | |
2600 | _vnck_release_desktop_layout_manager (screen->priv->xscreen, |
2601 | current_token); |
2602 | |
2603 | } |
2604 | |
2605 | /** |
2606 | * vnck_screen_get_showing_desktop: |
2607 | * @screen: a #VnckScreen. |
2608 | * |
2609 | * Gets whether @screen is in the "showing the desktop" mode. This mode is |
2610 | * changed when a #VnckScreen::showing-desktop-changed signal gets emitted. |
2611 | * |
2612 | * Return value: %TRUE if @window is fullscreen, %FALSE otherwise. |
2613 | * |
2614 | * Since: 2.2 |
2615 | **/ |
2616 | gboolean |
2617 | vnck_screen_get_showing_desktop (VnckScreen *screen) |
2618 | { |
2619 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return ((0)); } } while (0); |
2620 | |
2621 | return screen->priv->showing_desktop; |
2622 | } |
2623 | |
2624 | /** |
2625 | * vnck_screen_toggle_showing_desktop: |
2626 | * @screen: a #VnckScreen. |
2627 | * @show: whether to activate the "showing the desktop" mode on @screen. |
2628 | * |
2629 | * Asks the window manager to set the "showing the desktop" mode on @screen |
2630 | * according to @show. |
2631 | * |
2632 | * Since: 2.2 |
2633 | **/ |
2634 | void |
2635 | vnck_screen_toggle_showing_desktop (VnckScreen *screen, |
2636 | gboolean show) |
2637 | { |
2638 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
2639 | |
2640 | _vnck_toggle_showing_desktop (screen->priv->xscreen, |
2641 | show); |
2642 | } |
2643 | |
2644 | |
2645 | /** |
2646 | * vnck_screen_move_viewport: |
2647 | * @screen: a #VnckScreen. |
2648 | * @x: X offset in pixels of viewport. |
2649 | * @y: Y offset in pixels of viewport. |
2650 | * |
2651 | * Asks the window manager to move the viewport of the current #VnckWorkspace |
2652 | * on @screen. |
2653 | * |
2654 | * Since: 2.4 |
2655 | */ |
2656 | void |
2657 | vnck_screen_move_viewport (VnckScreen *screen, |
2658 | int x, |
2659 | int y) |
2660 | { |
2661 | g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return; } } while (0); |
2662 | g_return_if_fail (x >= 0)do { if ((x >= 0)) { } else { g_return_if_fail_warning ("Vnck" , ((const char*) (__func__)), "x >= 0"); return; } } while (0); |
2663 | g_return_if_fail (y >= 0)do { if ((y >= 0)) { } else { g_return_if_fail_warning ("Vnck" , ((const char*) (__func__)), "y >= 0"); return; } } while (0); |
2664 | |
2665 | _vnck_change_viewport (screen->priv->xscreen, x, y); |
2666 | } |
2667 | |
2668 | #ifdef HAVE_STARTUP_NOTIFICATION1 |
2669 | SnDisplay* |
2670 | _vnck_screen_get_sn_display (VnckScreen *screen) |
2671 | { |
2672 | g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((vnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Vnck", ((const char*) (__func__ )), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while (0); |
2673 | |
2674 | return screen->priv->sn_display; |
2675 | } |
2676 | #endif /* HAVE_STARTUP_NOTIFICATION */ |
2677 | |
2678 | void |
2679 | _vnck_screen_change_workspace_name (VnckScreen *screen, |
2680 | int number, |
2681 | const char *name) |
2682 | { |
2683 | int n_spaces; |
2684 | char **names; |
2685 | int i; |
2686 | |
2687 | n_spaces = vnck_screen_get_workspace_count (screen); |
2688 | |
2689 | names = g_new0 (char*, n_spaces + 1)((char* *) g_malloc0_n ((n_spaces + 1), sizeof (char*))); |
2690 | |
2691 | i = 0; |
2692 | while (i < n_spaces) |
2693 | { |
2694 | if (i == number) |
2695 | names[i] = (char*) name; |
2696 | else |
2697 | { |
2698 | VnckWorkspace *workspace; |
2699 | workspace = vnck_screen_get_workspace (screen, i); |
2700 | if (workspace) |
2701 | names[i] = (char*) vnck_workspace_get_name (workspace); |
2702 | else |
2703 | names[i] = (char*) ""; /* maybe this should be a g_warning() */ |
2704 | } |
2705 | |
2706 | ++i; |
2707 | } |
2708 | |
2709 | _vnck_set_utf8_list (screen->priv->xscreen, |
2710 | screen->priv->xroot, |
2711 | _vnck_atom_get ("_NET_DESKTOP_NAMES")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES"), |
2712 | names); |
2713 | |
2714 | g_free (names); |
2715 | } |
2716 | |
2717 | void |
2718 | _vnck_screen_shutdown_all (void) |
2719 | { |
2720 | int i; |
2721 | Display *display; |
2722 | |
2723 | if (screens == NULL((void*)0)) |
2724 | return; |
2725 | |
2726 | display = _vnck_get_default_display (); |
2727 | |
2728 | for (i = 0; i < ScreenCount (display)(((_XPrivDisplay)(display))->nscreens); ++i) |
2729 | { |
2730 | if (screens[i] != NULL((void*)0)) { |
2731 | g_object_unref (screens[i]); |
2732 | screens[i] = NULL((void*)0); |
2733 | } |
2734 | } |
2735 | |
2736 | g_free (screens); |
2737 | screens = NULL((void*)0); |
2738 | } |