Bug Summary

File:_build/../libvnck/screen.c
Warning:line 1088, column 3
Value stored to 'current_col' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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