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