window.c 95 KB
Newer Older
Havoc Pennington's avatar
...    
Havoc Pennington committed
1
/* window object */
Vincent Untz's avatar
Vincent Untz committed
2
/* vim: set sw=2 et: */
Havoc Pennington's avatar
...    
Havoc Pennington committed
3
4
5

/*
 * Copyright (C) 2001 Havoc Pennington
6
7
 * Copyright (C) 2003 Kim Woelders
 * Copyright (C) 2003 Red Hat, Inc.
8
 * Copyright (C) 2006-2007 Vincent Untz
Havoc Pennington's avatar
...    
Havoc Pennington committed
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
21
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Havoc Pennington's avatar
...    
Havoc Pennington committed
22
23
 */

Vincent Untz's avatar
updated    
Vincent Untz committed
24
25
26
#include <config.h>

#include <glib/gi18n-lib.h>
Havoc Pennington's avatar
Havoc Pennington committed
27
#include <string.h>
28
29
#include <time.h>

Havoc Pennington's avatar
...    
Havoc Pennington committed
30
#include "window.h"
31
#include "class-group.h"
32
#include "util.h"
Havoc Pennington's avatar
Havoc Pennington committed
33
34
#include "xutils.h"
#include "private.h"
35
#include "wnck-enum-types.h"
36
#include "wnck-icon-cache-private.h"
Havoc Pennington's avatar
...    
Havoc Pennington committed
37

Vincent Untz's avatar
Vincent Untz committed
38
39
40
41
42
43
44
/**
 * SECTION:window
 * @short_description: an object representing a window.
 * @see_also: #WnckWorkspace, #WnckApplication, #WnckClassGroup
 * @stability: Unstable
 *
 * The #WnckWindow objects are always owned by libwnck and must not be
Vincent Untz's avatar
Vincent Untz committed
45
 * referenced or unreferenced.
Vincent Untz's avatar
Vincent Untz committed
46
47
 */

48
#define FALLBACK_NAME _("Untitled window")
49
#define ALL_WORKSPACES ((int) 0xFFFFFFFF)
Havoc Pennington's avatar
Havoc Pennington committed
50

51
/* Keep 0-7 in sync with the numbers in the WindowState enum. Yeah I'm
52
53
 * a loser.
 */
54
55
56
57
58
59
60
61
#define COMPRESS_STATE(window)                          \
  ( ((window)->priv->is_minimized        << 0) |        \
    ((window)->priv->is_maximized_horz   << 1) |        \
    ((window)->priv->is_maximized_vert   << 2) |        \
    ((window)->priv->is_shaded           << 3) |        \
    ((window)->priv->skip_pager          << 4) |        \
    ((window)->priv->skip_taskbar        << 5) |        \
    ((window)->priv->is_sticky           << 6) |        \
62
    ((window)->priv->is_hidden           << 7) |        \
63
    ((window)->priv->is_fullscreen       << 8) |        \
64
    ((window)->priv->demands_attention   << 9) |        \
65
    ((window)->priv->is_urgent           << 10)|        \
66
67
    ((window)->priv->is_above            << 11)|        \
    ((window)->priv->is_below            << 12))
Havoc Pennington's avatar
...    
Havoc Pennington committed
68
69
70

struct _WnckWindowPrivate
{
Havoc Pennington's avatar
Havoc Pennington committed
71
  Window xwindow;
72
73
  WnckScreen *screen;
  WnckApplication *app;
74
  WnckClassGroup *class_group;
75
  gboolean has_group_leader;
76
  Window group_leader;
Havoc Pennington's avatar
Havoc Pennington committed
77
  Window transient_for;
Martin Pitt's avatar
Martin Pitt committed
78
  int orig_event_mask;
79
  GdkRectangle icon_geometry;
Havoc Pennington's avatar
Havoc Pennington committed
80
81
  char *name;
  char *icon_name;
82
83
  char *session_id;
  char *session_id_utf8;
84
  char *role;
85
86
  int pid;
  int workspace;
87
  gint sort_order;
Havoc Pennington's avatar
Havoc Pennington committed
88

Havoc Pennington's avatar
Havoc Pennington committed
89
  WnckWindowType wintype;
Vincent Untz's avatar
Vincent Untz committed
90

Havoc Pennington's avatar
Havoc Pennington committed
91
92
93
  GdkPixbuf *icon;
  GdkPixbuf *mini_icon;

94
  WnckIconCache *icon_cache;
Vincent Untz's avatar
Vincent Untz committed
95

96
  WnckWindowActions actions;
97
98
99
100
101

  int x;
  int y;
  int width;
  int height;
102

103
104
105
106
107
  int left_frame;
  int right_frame;
  int top_frame;
  int bottom_frame;

108
  char *startup_id;
109
110
111

  char *res_class;
  char *res_name;
Vincent Untz's avatar
Vincent Untz committed
112

113
114
115
116
  /* true if transient_for points to root window,
   * not another app window
   */
  guint transient_for_root : 1;
Vincent Untz's avatar
Vincent Untz committed
117

Havoc Pennington's avatar
Havoc Pennington committed
118
  /* window state */
Havoc Pennington's avatar
Havoc Pennington committed
119
120
121
122
  guint is_minimized : 1;
  guint is_maximized_horz : 1;
  guint is_maximized_vert : 1;
  guint is_shaded : 1;
123
  guint is_above : 1;
124
  guint is_below : 1;
Havoc Pennington's avatar
Havoc Pennington committed
125
126
127
  guint skip_pager : 1;
  guint skip_taskbar : 1;
  guint is_sticky : 1;
128
  guint is_hidden : 1;
129
  guint is_fullscreen : 1;
130
  guint demands_attention : 1;
131
  guint is_urgent : 1;
132

133
134
  time_t needs_attention_time;

135
136
137
138
  /* _NET_WM_STATE_HIDDEN doesn't map directly into an
   * externally-visible state (it determines the WM_STATE
   * interpretation)
   */
Vincent Untz's avatar
Vincent Untz committed
139
  guint net_wm_state_hidden : 1;
140
  guint wm_state_iconic : 1;
Vincent Untz's avatar
Vincent Untz committed
141

Havoc Pennington's avatar
Havoc Pennington committed
142
  /* idle handler for updates */
Havoc Pennington's avatar
Havoc Pennington committed
143
  guint update_handler;
Havoc Pennington's avatar
...    
Havoc Pennington committed
144

Havoc Pennington's avatar
Havoc Pennington committed
145
146
147
148
149
  /* if you add flags, be sure to set them
   * when we create the window so we get an initial update
   */
  guint need_update_name : 1;
  guint need_update_state : 1;
150
  guint need_update_wm_state : 1;
Havoc Pennington's avatar
Havoc Pennington committed
151
  guint need_update_icon_name : 1;
152
  guint need_update_workspace : 1;
153
  guint need_update_actions : 1;
Havoc Pennington's avatar
Havoc Pennington committed
154
  guint need_update_wintype : 1;
155
156
  guint need_update_transient_for : 1;
  guint need_update_startup_id : 1;
157
  guint need_update_wmclass : 1;
158
  guint need_update_wmhints : 1;
159
  guint need_update_frame_extents : 1;
160
  guint need_update_role : 1;
161
162
163

  guint need_emit_name_changed : 1;
  guint need_emit_icon_changed : 1;
164
  guint need_emit_class_changed : 1;
165
  guint need_emit_role_changed : 1;
166
  guint need_emit_type_changed : 1;
Havoc Pennington's avatar
...    
Havoc Pennington committed
167
168
};

169
G_DEFINE_TYPE_WITH_PRIVATE (WnckWindow, wnck_window, G_TYPE_OBJECT);
Vincent Untz's avatar
Vincent Untz committed
170

Havoc Pennington's avatar
...    
Havoc Pennington committed
171
enum {
Havoc Pennington's avatar
Havoc Pennington committed
172
173
  NAME_CHANGED,
  STATE_CHANGED,
174
  WORKSPACE_CHANGED,
Havoc Pennington's avatar
Havoc Pennington committed
175
  ICON_CHANGED,
176
  ACTIONS_CHANGED,
177
  GEOMETRY_CHANGED,
178
  CLASS_CHANGED,
179
  ROLE_CHANGED,
180
  TYPE_CHANGED,
Havoc Pennington's avatar
...    
Havoc Pennington committed
181
182
183
184
185
  LAST_SIGNAL
};

static void wnck_window_finalize    (GObject        *object);

186
187
188
189
190
static void emit_name_changed      (WnckWindow      *window);
static void emit_state_changed     (WnckWindow      *window,
                                    WnckWindowState  changed_mask,
                                    WnckWindowState  new_state);
static void emit_workspace_changed (WnckWindow      *window);
Havoc Pennington's avatar
Havoc Pennington committed
191
static void emit_icon_changed      (WnckWindow      *window);
192
193
194
static void emit_actions_changed   (WnckWindow       *window,
                                    WnckWindowActions changed_mask,
                                    WnckWindowActions new_actions);
195
static void emit_geometry_changed  (WnckWindow      *window);
196
197
static void emit_class_changed     (WnckWindow      *window);
static void emit_role_changed      (WnckWindow      *window);
198
static void emit_type_changed      (WnckWindow      *window);
Havoc Pennington's avatar
Havoc Pennington committed
199
200
201

static void update_name      (WnckWindow *window);
static void update_state     (WnckWindow *window);
202
static void update_wm_state  (WnckWindow *window);
Havoc Pennington's avatar
Havoc Pennington committed
203
static void update_icon_name (WnckWindow *window);
204
static void update_workspace (WnckWindow *window);
205
static void update_actions   (WnckWindow *window);
Havoc Pennington's avatar
Havoc Pennington committed
206
207
static void update_wintype   (WnckWindow *window);
static void update_transient_for (WnckWindow *window);
208
static void update_startup_id (WnckWindow *window);
209
static void update_wmclass   (WnckWindow *window);
210
static void update_frame_extents (WnckWindow *window);
211
static void update_role      (WnckWindow *window);
Havoc Pennington's avatar
Havoc Pennington committed
212
213
214
static void unqueue_update   (WnckWindow *window);
static void queue_update     (WnckWindow *window);
static void force_update_now (WnckWindow *window);
Havoc Pennington's avatar
...    
Havoc Pennington committed
215

216
217
218
static WnckWindow* find_last_transient_for (GList *windows,
                                            Window xwindow);

Havoc Pennington's avatar
...    
Havoc Pennington committed
219
220
221
222
static guint signals[LAST_SIGNAL] = { 0 };

static void
wnck_window_init (WnckWindow *window)
Havoc Pennington's avatar
Havoc Pennington committed
223
{
224
  window->priv = wnck_window_get_instance_private (window);
Havoc Pennington's avatar
...    
Havoc Pennington committed
225

226
  window->priv->icon_cache = _wnck_icon_cache_new ();
227
  window->priv->icon_geometry.width = -1; /* invalid cached value */
228
229
230
231
  window->priv->workspace = -1;
  window->priv->sort_order = G_MAXINT;

  /* FIXME: should we have an invalid window type for this? */
232
  window->priv->wintype = WNCK_WINDOW_NORMAL;
Havoc Pennington's avatar
...    
Havoc Pennington committed
233
234
235
236
237
238
}

static void
wnck_window_class_init (WnckWindowClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Havoc Pennington's avatar
Havoc Pennington committed
239

Havoc Pennington's avatar
...    
Havoc Pennington committed
240
241
  object_class->finalize = wnck_window_finalize;

Vincent Untz's avatar
Vincent Untz committed
242
243
244
245
246
247
  /**
   * WnckWindow::name-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the name of @window changes.
   */
Havoc Pennington's avatar
Havoc Pennington committed
248
249
250
251
252
  signals[NAME_CHANGED] =
    g_signal_new ("name_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, name_changed),
253
                  NULL, NULL, NULL,
Havoc Pennington's avatar
Havoc Pennington committed
254
255
                  G_TYPE_NONE, 0);

Vincent Untz's avatar
Vincent Untz committed
256
257
258
  /**
   * WnckWindow::state-changed:
   * @window: the #WnckWindow which emitted the signal.
Vincent Untz's avatar
Vincent Untz committed
259
   * @changed_mask: the bitmask containing bits set for all states of @window
Vincent Untz's avatar
Vincent Untz committed
260
   * that have changed.
Vincent Untz's avatar
Vincent Untz committed
261
262
263
264
   * @new_state: the new state of @window.
   *
   * Emitted when the state of @window changes. This can happen when @window is
   * (un)minimized, (un)maximized, (un)sticked, (un)shaded, (un)made above,
265
266
   * (un)made below, (un)set fullscreen, when it needs attention, etc. See
   * #WnckWindowState for the complete list of states that might have changed.
Vincent Untz's avatar
Vincent Untz committed
267
   */
Havoc Pennington's avatar
Havoc Pennington committed
268
269
270
271
272
  signals[STATE_CHANGED] =
    g_signal_new ("state_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, state_changed),
273
                  NULL, NULL, NULL,
274
275
                  G_TYPE_NONE, 2,
                  WNCK_TYPE_WINDOW_STATE, WNCK_TYPE_WINDOW_STATE);
276

Vincent Untz's avatar
Vincent Untz committed
277
278
279
280
281
282
283
  /**
   * WnckWindow::workspace-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the current workspace of @window changes, or if @window has
   * been pinned or unpinned.
   */
284
285
286
287
288
  signals[WORKSPACE_CHANGED] =
    g_signal_new ("workspace_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, workspace_changed),
289
                  NULL, NULL, NULL,
290
                  G_TYPE_NONE, 0);
Havoc Pennington's avatar
Havoc Pennington committed
291

Vincent Untz's avatar
Vincent Untz committed
292
293
294
295
296
297
  /**
   * WnckWindow::icon-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the icon of @window changes.
   */
Havoc Pennington's avatar
Havoc Pennington committed
298
299
300
301
302
  signals[ICON_CHANGED] =
    g_signal_new ("icon_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, icon_changed),
303
                  NULL, NULL, NULL,
Havoc Pennington's avatar
Havoc Pennington committed
304
305
                  G_TYPE_NONE, 0);

Vincent Untz's avatar
Vincent Untz committed
306
307
308
  /**
   * WnckWindow::actions-changed:
   * @window: the #WnckWindow which emitted the signal.
Vincent Untz's avatar
Vincent Untz committed
309
   * @changed_mask: the bitmask containing bits set for all actions
Vincent Untz's avatar
Vincent Untz committed
310
   * availabilities for @window that have changed.
Vincent Untz's avatar
Vincent Untz committed
311
312
313
314
   * @new_state: the new actions availabilities for @window.
   *
   * Emitted when the actions availabilities for @window change.
   */
315
316
317
318
319
  signals[ACTIONS_CHANGED] =
    g_signal_new ("actions_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, actions_changed),
320
                  NULL, NULL, NULL,
321
322
323
                  G_TYPE_NONE, 2,
                  WNCK_TYPE_WINDOW_ACTIONS,
                  WNCK_TYPE_WINDOW_ACTIONS);
324

Vincent Untz's avatar
Vincent Untz committed
325
326
327
328
329
330
  /**
   * WnckWindow::geometry-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the geometry of @window changes.
   */
331
332
333
334
335
  signals[GEOMETRY_CHANGED] =
    g_signal_new ("geometry_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, geometry_changed),
336
                  NULL, NULL, NULL,
Vincent Untz's avatar
Vincent Untz committed
337
                  G_TYPE_NONE, 0);
338
339
340
341
342
343
344
345
346
347
348
349

  /**
   * WnckWindow::class-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the class name or instance name of @window changes.
   */
  signals[CLASS_CHANGED] =
    g_signal_new ("class_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, class_changed),
350
                  NULL, NULL, NULL,
351
                  G_TYPE_NONE, 0);
352
353
354
355
356
357
358
359
360
361
362
363

  /**
   * WnckWindow::role-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the role of @window changes.
   */
  signals[ROLE_CHANGED] =
    g_signal_new ("role_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, role_changed),
364
                  NULL, NULL, NULL,
365
                  G_TYPE_NONE, 0);
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

  /**
   * WnckWindow::type-changed:
   * @window: the #WnckWindow which emitted the signal.
   *
   * Emitted when the EWMH type hint of the window changes.
   *
   * Since: 3.20
   */
  signals[TYPE_CHANGED] =
    g_signal_new ("type_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (WnckWindowClass, type_changed),
                  NULL, NULL, NULL,
                  G_TYPE_NONE, 0);
Havoc Pennington's avatar
...    
Havoc Pennington committed
382
383
384
385
386
387
388
389
390
}

static void
wnck_window_finalize (GObject *object)
{
  WnckWindow *window;

  window = WNCK_WINDOW (object);

391
392
393
394
395
  _wnck_select_input (WNCK_SCREEN_XSCREEN (window->priv->screen),
                      window->priv->xwindow,
                      window->priv->orig_event_mask,
                      FALSE);

Havoc Pennington's avatar
Havoc Pennington committed
396
  unqueue_update (window);
397

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
  if (window->priv->app)
    g_object_unref (G_OBJECT (window->priv->app));
  window->priv->app = NULL;

  if (window->priv->class_group)
    g_object_unref (G_OBJECT (window->priv->class_group));
  window->priv->class_group = NULL;

  g_free (window->priv->name);
  window->priv->name = NULL;
  g_free (window->priv->icon_name);
  window->priv->icon_name = NULL;
  g_free (window->priv->session_id);
  window->priv->session_id = NULL;
  g_free (window->priv->session_id_utf8);
  window->priv->session_id_utf8 = NULL;

415
416
  if (window->priv->icon)
    g_object_unref (G_OBJECT (window->priv->icon));
417
  window->priv->icon = NULL;
418
419
420

  if (window->priv->mini_icon)
    g_object_unref (G_OBJECT (window->priv->mini_icon));
421
  window->priv->mini_icon = NULL;
Vincent Untz's avatar
Vincent Untz committed
422

423
  _wnck_icon_cache_free (window->priv->icon_cache);
424
  window->priv->icon_cache = NULL;
Havoc Pennington's avatar
Havoc Pennington committed
425

426
  g_free (window->priv->startup_id);
427
  window->priv->startup_id = NULL;
428
  g_free (window->priv->res_class);
429
  window->priv->res_class = NULL;
430
  g_free (window->priv->res_name);
431
  window->priv->res_name = NULL;
Havoc Pennington's avatar
Havoc Pennington committed
432

433
434
  window->priv->xwindow = None;

Vincent Untz's avatar
Vincent Untz committed
435
  G_OBJECT_CLASS (wnck_window_parent_class)->finalize (object);
Havoc Pennington's avatar
...    
Havoc Pennington committed
436
}
Havoc Pennington's avatar
Havoc Pennington committed
437
438
439

/**
 * wnck_window_get:
Vincent Untz's avatar
Vincent Untz committed
440
 * @xwindow: an X window ID.
Havoc Pennington's avatar
Havoc Pennington committed
441
 *
442
 * Gets a preexisting #WnckWindow for the X window @xwindow. This will not
Vincent Untz's avatar
Vincent Untz committed
443
444
 * create a #WnckWindow if none exists. The function is robust against bogus
 * window IDs.
Havoc Pennington's avatar
Havoc Pennington committed
445
 *
Tomeu Vizoso's avatar
Tomeu Vizoso committed
446
447
 * Return value: (transfer none): the #WnckWindow for @xwindow. The returned
 * #WnckWindow is owned by libwnck and must not be referenced or unreferenced.
Havoc Pennington's avatar
Havoc Pennington committed
448
449
450
451
 **/
WnckWindow*
wnck_window_get (gulong xwindow)
{
Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
452
  return wnck_handle_get_window (_wnck_get_handle (), xwindow);
Havoc Pennington's avatar
Havoc Pennington committed
453
454
}

455
456
/**
 * wnck_window_get_screen:
Vincent Untz's avatar
Vincent Untz committed
457
 * @window: a #WnckWindow.
Havoc Pennington's avatar
Havoc Pennington committed
458
 *
459
 * Gets the #WnckScreen @window is on.
Havoc Pennington's avatar
Havoc Pennington committed
460
 *
Tomeu Vizoso's avatar
Tomeu Vizoso committed
461
462
 * Return value: (transfer none): the #WnckScreen @window is on. The returned
 * #WnckScreen is owned by libwnck and must not be referenced or unreferenced.
463
464
465
466
467
468
469
470
471
 **/
WnckScreen*
wnck_window_get_screen (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

  return window->priv->screen;
}

Havoc Pennington's avatar
Havoc Pennington committed
472
WnckWindow*
473
_wnck_window_create (Window      xwindow,
474
475
                     WnckScreen *screen,
                     gint        sort_order)
Havoc Pennington's avatar
Havoc Pennington committed
476
{
477
  WnckHandle *handle;
Havoc Pennington's avatar
Havoc Pennington committed
478
  WnckWindow *window;
479
  Screen     *xscreen;
Havoc Pennington's avatar
Havoc Pennington committed
480

Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
481
482
  handle = wnck_screen_get_handle (screen);
  window = wnck_handle_get_window (handle, xwindow);
Havoc Pennington's avatar
Havoc Pennington committed
483

484
  g_return_val_if_fail (window == NULL, NULL);
Havoc Pennington's avatar
Havoc Pennington committed
485

486
487
  xscreen = WNCK_SCREEN_XSCREEN (screen);

Havoc Pennington's avatar
Havoc Pennington committed
488
489
  window = g_object_new (WNCK_TYPE_WINDOW, NULL);
  window->priv->xwindow = xwindow;
490
  window->priv->screen = screen;
Havoc Pennington's avatar
Havoc Pennington committed
491

492
  _wnck_handle_insert_window (handle, &window->priv->xwindow, window);
Havoc Pennington's avatar
Havoc Pennington committed
493

494
  /* Handle now owns one ref, caller gets none */
Havoc Pennington's avatar
Havoc Pennington committed
495

496
  /* Note that xwindow may correspond to a WnckApplication's xwindow,
497
498
   * that's why we select the union of the mask we want for Application
   * and the one we want for window
499
   */
Martin Pitt's avatar
Martin Pitt committed
500
  window->priv->orig_event_mask =_wnck_select_input (xscreen,
501
502
503
                                                     window->priv->xwindow,
                                                     WNCK_APP_WINDOW_EVENT_MASK,
                                                     TRUE);
504

505
506
507
  /* Default the group leader to the window itself; it is set in
   * update_wmhints() if a different group leader is specified.
   */
508
  window->priv->has_group_leader = FALSE;
509
  window->priv->group_leader = window->priv->xwindow;
510
511

  window->priv->session_id =
512
    _wnck_get_session_id (xscreen, window->priv->xwindow);
513
514

  window->priv->pid =
515
    _wnck_get_pid (screen, window->priv->xwindow);
Havoc Pennington's avatar
Havoc Pennington committed
516

517
518
519
520
  window->priv->x = 0;
  window->priv->y = 0;
  window->priv->width = 0;
  window->priv->height = 0;
521
  _wnck_get_window_geometry (xscreen,
522
			     xwindow,
523
524
525
526
                             &window->priv->x,
                             &window->priv->y,
                             &window->priv->width,
                             &window->priv->height);
527
528

  window->priv->sort_order = sort_order;
Vincent Untz's avatar
Vincent Untz committed
529

Havoc Pennington's avatar
Havoc Pennington committed
530
531
532
  window->priv->need_update_name = TRUE;
  window->priv->need_update_state = TRUE;
  window->priv->need_update_icon_name = TRUE;
533
  window->priv->need_update_wm_state = TRUE;
534
  window->priv->need_update_workspace = TRUE;
Havoc Pennington's avatar
Havoc Pennington committed
535
  window->priv->need_update_actions = TRUE;
Havoc Pennington's avatar
Havoc Pennington committed
536
537
  window->priv->need_update_wintype = TRUE;
  window->priv->need_update_transient_for = TRUE;
538
  window->priv->need_update_startup_id = TRUE;
539
  window->priv->need_update_wmclass = TRUE;
540
  window->priv->need_update_wmhints = TRUE;
541
  window->priv->need_update_frame_extents = TRUE;
542
  window->priv->need_update_role = TRUE;
543
544
  window->priv->need_emit_name_changed = FALSE;
  window->priv->need_emit_icon_changed = FALSE;
545
  window->priv->need_emit_class_changed = FALSE;
546
  window->priv->need_emit_role_changed = FALSE;
547
  window->priv->need_emit_type_changed = FALSE;
Havoc Pennington's avatar
Havoc Pennington committed
548
  force_update_now (window);
Havoc Pennington's avatar
Havoc Pennington committed
549

Havoc Pennington's avatar
Havoc Pennington committed
550
551
552
553
554
555
  return window;
}

void
_wnck_window_destroy (WnckWindow *window)
{
556
  WnckHandle *handle;
557
  Window xwindow = window->priv->xwindow;
Martin Pitt's avatar
Martin Pitt committed
558

559
  g_return_if_fail (WNCK_IS_WINDOW (window));
Havoc Pennington's avatar
Havoc Pennington committed
560

Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
561
  handle = wnck_screen_get_handle (window->priv->screen);
562

Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
563
  g_return_if_fail (wnck_handle_get_window (handle, xwindow) == window);
Havoc Pennington's avatar
Havoc Pennington committed
564

565
  _wnck_handle_remove_window (handle, &xwindow);
Havoc Pennington's avatar
Havoc Pennington committed
566

567
  /* Removing from handle also removes the only ref WnckWindow had */
Havoc Pennington's avatar
Havoc Pennington committed
568

Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
569
  g_return_if_fail (wnck_handle_get_window (handle, xwindow) == NULL);
Havoc Pennington's avatar
Havoc Pennington committed
570
571
}

572
573
574
575
576
577
static Display *
_wnck_window_get_display (WnckWindow *window)
{
  return DisplayOfScreen (WNCK_SCREEN_XSCREEN (window->priv->screen));
}

578
579
/**
 * wnck_window_has_name:
Vincent Untz's avatar
Vincent Untz committed
580
 * @window: a #WnckWindow.
581
582
 *
 * Checks whether or not @window has a name. wnck_window_get_name()
Vincent Untz's avatar
Vincent Untz committed
583
584
 * will always return some value, even if @window has no name set;
 * wnck_window_has_name() can be used to tell if that name is
585
586
587
588
 * real or not.
 *
 * For icons titles, use wnck_window_has_icon_name() instead.
 *
Vincent Untz's avatar
Vincent Untz committed
589
590
 * Return value: %TRUE if wnck_window_get_name() returns @window<!-- -->'s
 * name, %FALSE if it returns a fallback name.
Vincent Untz's avatar
Vincent Untz committed
591
592
 *
 * Since: 2.16
593
594
595
596
597
598
599
600
601
 **/
gboolean
wnck_window_has_name (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);

  return window->priv->name != NULL;
}

Havoc Pennington's avatar
Havoc Pennington committed
602
603
/**
 * wnck_window_get_name:
Vincent Untz's avatar
Vincent Untz committed
604
 * @window: a #WnckWindow.
Havoc Pennington's avatar
Havoc Pennington committed
605
 *
606
 * Gets the name of @window, as it should be displayed in a pager
Vincent Untz's avatar
Vincent Untz committed
607
608
609
 * or tasklist. Always returns some value, even if @window has no name
 * set; use wnck_window_has_name() if you need to know whether the returned
 * name is "real" or not.
Havoc Pennington's avatar
Havoc Pennington committed
610
611
 *
 * For icons titles, use wnck_window_get_icon_name() instead.
Havoc Pennington's avatar
Havoc Pennington committed
612
 *
Vincent Untz's avatar
Vincent Untz committed
613
614
 * Return value: the name of @window, or a fallback name if no name is
 * available.
Havoc Pennington's avatar
Havoc Pennington committed
615
616
617
618
619
 **/
const char*
wnck_window_get_name (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
Havoc Pennington's avatar
Havoc Pennington committed
620

621
622
623
624
625
626
627
628
629
630
631
632
  if (window->priv->name)
    return window->priv->name;
  else
    return FALLBACK_NAME;
}

/**
 * wnck_window_has_icon_name:
 * @window: a #WnckWindow
 *
 * Checks whether or not @window has an icon name.
 * wnck_window_get_icon_name() will always return some value, even if
Vincent Untz's avatar
Vincent Untz committed
633
634
 * @window has no icon name set; wnck_window_has_icon_name() can
 * be used to tell if that icon name is real or not.
635
636
637
 *
 * (Note that if wnck_window_has_icon_name() returns %FALSE, but
 * wnck_window_has_name() returns %TRUE, then the name returned by
Vincent Untz's avatar
Vincent Untz committed
638
 * wnck_window_get_icon_name() is @window<!-- -->'s name. Only when both
639
640
641
 * methods return %FALSE does wnck_window_get_icon_name() return a
 * generic fallback name.)
 *
Vincent Untz's avatar
Vincent Untz committed
642
643
 * Return value: %TRUE if wnck_window_get_icon_name() returns
 * @window<!-- -->'s icon name, %FALSE if it returns a fallback name.
Vincent Untz's avatar
Vincent Untz committed
644
645
 *
 * Since: 2.16
646
647
648
649
650
651
652
 **/
gboolean
wnck_window_has_icon_name (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);

  return window->priv->icon_name != NULL;
Havoc Pennington's avatar
Havoc Pennington committed
653
654
655
656
657
}

/**
 * wnck_window_get_icon_name:
 * @window: a #WnckWindow
Havoc Pennington's avatar
Havoc Pennington committed
658
 *
659
 * Gets the icon name of @window, as it should be displayed for an icon
Vincent Untz's avatar
Vincent Untz committed
660
661
662
 * (minimized state). Always returns some value, even if @window has no icon
 * name set; use wnck_window_has_icon_name() if you need to know whether the
 * returned icon name is "real" or not.
Havoc Pennington's avatar
Havoc Pennington committed
663
 *
Vincent Untz's avatar
Vincent Untz committed
664
665
666
 * Contrast with wnck_window_get_name(), which returns @window<!-- -->'s
 * title, not its icon title.
 *
Vincent Untz's avatar
Vincent Untz committed
667
668
 * Return value: the icon name of @window, or a fallback icon name if no icon
 * name is available.
Havoc Pennington's avatar
Havoc Pennington committed
669
670
671
672
673
674
675
676
 **/
const char*
wnck_window_get_icon_name (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

  if (window->priv->icon_name)
    return window->priv->icon_name;
677
  else if (window->priv->name)
Havoc Pennington's avatar
Havoc Pennington committed
678
    return window->priv->name;
679
680
  else
    return FALLBACK_NAME;
Havoc Pennington's avatar
Havoc Pennington committed
681
682
}

683
684
685
686
687
688
689
690
char *
_wnck_window_get_name_for_display (WnckWindow *window,
                                   gboolean    use_icon_name,
                                   gboolean    use_state_decorations)
{
  const char *name;

  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
Vincent Untz's avatar
Vincent Untz committed
691

692
693
  if (use_icon_name && wnck_window_has_icon_name (window))
    name = wnck_window_get_icon_name (window);
Vincent Untz's avatar
Vincent Untz committed
694
  else
695
    name = wnck_window_get_name (window);
Vincent Untz's avatar
Vincent Untz committed
696

697
698
699
700
701
702
703
704
705
706
707
708
709
710
  if (use_state_decorations)
    {
      if (window->priv->is_shaded)
        return g_strdup_printf ("=%s=", name);
      else if (window->priv->is_minimized)
        return g_strdup_printf ("[%s]", name);
      else
        return g_strdup (name);
    }
  else
    return g_strdup (name);
}


Vincent Untz's avatar
Vincent Untz committed
711
712
713
714
/**
 * wnck_window_get_application:
 * @window: a #WnckWindow.
 *
715
 * Gets the #WnckApplication to which @window belongs.
Vincent Untz's avatar
Vincent Untz committed
716
 *
Tomeu Vizoso's avatar
Tomeu Vizoso committed
717
718
719
 * Return value: (transfer none): the #WnckApplication to which @window belongs.
 * The returned #WnckApplication is owned by libwnck and must not be referenced
 * or unreferenced.
Vincent Untz's avatar
Vincent Untz committed
720
 **/
721
722
723
724
725
726
727
728
WnckApplication*
wnck_window_get_application  (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

  return window->priv->app;
}

Vincent Untz's avatar
Vincent Untz committed
729
730
731
732
/**
 * wnck_window_get_transient:
 * @window: a #WnckWindow.
 *
733
 * Gets the #WnckWindow for which @window is transient.
Vincent Untz's avatar
Vincent Untz committed
734
 *
735
736
737
738
 * Return value: (transfer none): the #WnckWindow for which @window is
 * transient, or %NULL if @window is not transient for any #WnckWindow.
 * The returned #WnckWindow is owned by libwnck and must not be referenced or
 * unreferenced.
Vincent Untz's avatar
Vincent Untz committed
739
740
 *
 * Since: 2.12
Vincent Untz's avatar
Vincent Untz committed
741
 **/
742
743
744
WnckWindow*
wnck_window_get_transient (WnckWindow *window)
{
745
746
  WnckHandle *handle;

Kjartan Maraas's avatar
Kjartan Maraas committed
747
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
748

Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
749
  handle = wnck_screen_get_handle (window->priv->screen);
750

Alberts Muktupāvels's avatar
Alberts Muktupāvels committed
751
  return wnck_handle_get_window (handle, window->priv->transient_for);
752
753
}

Vincent Untz's avatar
Vincent Untz committed
754
755
756
757
/**
 * wnck_window_get_group_leader:
 * @window: a #WnckWindow.
 *
758
 * Gets the group leader of the group of windows to which @window belongs.
Vincent Untz's avatar
Vincent Untz committed
759
760
761
762
763
 *
 * Return value: the group leader of the group of windows to which @window
 * belongs, or the X window ID of @window if @window does not belong to any
 * group.
 **/
764
765
766
767
gulong
wnck_window_get_group_leader (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), None);
Havoc Pennington's avatar
Havoc Pennington committed
768

769
770
771
  return window->priv->group_leader;
}

772
773
774
775
776
777
gboolean
_wnck_window_get_has_group_leader (WnckWindow *window)
{
  return window->priv->has_group_leader;
}

Vincent Untz's avatar
Vincent Untz committed
778
779
780
781
/**
 * wnck_window_get_xid:
 * @window: a #WnckWindow.
 *
782
 * Gets the X window ID of @window.
Vincent Untz's avatar
Vincent Untz committed
783
784
785
 *
 * Return value: the X window ID of @window.
 **/
Alexander Larsson's avatar
Alexander Larsson committed
786
787
788
789
790
791
792
793
gulong
wnck_window_get_xid (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), None);

  return window->priv->xwindow;
}

Vincent Untz's avatar
Vincent Untz committed
794
795
796
797
/**
 * wnck_window_get_class_group:
 * @window: a #WnckWindow.
 *
798
 * Gets the #WnckClassGroup to which @window belongs.
Vincent Untz's avatar
Vincent Untz committed
799
 *
Tomeu Vizoso's avatar
Tomeu Vizoso committed
800
801
802
 * Return value: (transfer none): the #WnckClassGroup to which @window belongs.
 * The returned #WnckClassGroup is owned by libwnck and must not be referenced
 * or unreferenced.
Vincent Untz's avatar
Vincent Untz committed
803
804
 *
 * Since: 2.2
Vincent Untz's avatar
Vincent Untz committed
805
 **/
806
807
808
809
810
811
812
813
WnckClassGroup *
wnck_window_get_class_group (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

  return window->priv->class_group;
}

814
815
/**
 * wnck_window_get_session_id:
Vincent Untz's avatar
Vincent Untz committed
816
 * @window: a #WnckWindow.
Havoc Pennington's avatar
Havoc Pennington committed
817
 *
818
 * Gets the session ID for @window in Latin-1 encoding.
819
 * NOTE: this is invalid UTF-8. You can't display this
Vincent Untz's avatar
Vincent Untz committed
820
 * string in a GTK+ widget without converting to UTF-8.
821
 * See wnck_window_get_session_id_utf8().
Havoc Pennington's avatar
Havoc Pennington committed
822
 *
Vincent Untz's avatar
Vincent Untz committed
823
824
 * Return value: the session ID for @window in Latin-1, or %NULL if @window has
 * no session ID.
825
826
827
828
829
830
831
832
833
 **/
const char*
wnck_window_get_session_id (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

  return window->priv->session_id;
}

Vincent Untz's avatar
Vincent Untz committed
834
835
836
837
/**
 * wnck_window_get_session_id_utf8:
 * @window: a #WnckWindow.
 *
838
 * Gets the session ID for @window in UTF-8 encoding.
Vincent Untz's avatar
Vincent Untz committed
839
840
841
842
843
844
845
 * The session ID should be in Latin-1 encoding, so the conversion should work,
 * but a broken client could set a session ID that might not be convertable to
 * UTF-8.
 *
 * Return value: the session ID for @window in UTF-8, or %NULL if @window has
 * no session ID.
 **/
846
847
848
849
850
const char*
wnck_window_get_session_id_utf8 (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

851
852
  if (window->priv->session_id_utf8 == NULL &&
      window->priv->session_id != NULL)
853
854
855
    {
      GString *str;
      char *p;
Havoc Pennington's avatar
Havoc Pennington committed
856

857
858
859
860
861
862
863
864
865
866
867
      str = g_string_new ("");

      p = window->priv->session_id;
      while (*p)
        {
          g_string_append_unichar (str, g_utf8_get_char (p));
          p = g_utf8_next_char (p);
        }

      window->priv->session_id_utf8 = g_string_free (str, FALSE);
    }
Havoc Pennington's avatar
Havoc Pennington committed
868

869
870
871
  return window->priv->session_id_utf8;
}

872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
/**
 * wnck_window_get_role:
 * @window: a #WnckWindow.
 *
 * Gets the role for @window.
 * The role uniquely identifies a window among all windows that have the same
 * client leader window.
 *
 * Return value: role for @window, or %NULL if @window has no role.
 **/
const char*
wnck_window_get_role (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);

  return window->priv->role;
}

890
891
/**
 * wnck_window_get_pid:
Vincent Untz's avatar
Vincent Untz committed
892
 * @window: a #WnckWindow.
Havoc Pennington's avatar
Havoc Pennington committed
893
 *
894
 * Gets the process ID of @window.
Havoc Pennington's avatar
Havoc Pennington committed
895
 *
Vincent Untz's avatar
Vincent Untz committed
896
 * Return value: the process ID of @window, or 0 if none is available.
897
898
899
900
901
902
903
904
905
 **/
int
wnck_window_get_pid (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), 0);

  return window->priv->pid;
}

906
907
/**
 * wnck_window_get_sort_order:
Vincent Untz's avatar
Vincent Untz committed
908
 * @window: a #WnckWindow.
909
 *
910
 * Gets the sort order of @window, used for ordering of @window in
Vincent Untz's avatar
Vincent Untz committed
911
912
 * #WnckSelector and #WnckTasklist. The sort order is an internal state in
 * libwnck. The initial value is defined when the window is created.
913
 *
Vincent Untz's avatar
Vincent Untz committed
914
 * Return value: the sort order of @window, or G_MAXINT if none is available.
Vincent Untz's avatar
Vincent Untz committed
915
916
 *
 * Since: 2.10
917
918
919
920
921
922
923
924
925
 **/
gint
wnck_window_get_sort_order (WnckWindow *window)
{
  g_return_val_if_fail (WNCK_IS_WINDOW (window), G_MAXINT);

  return window->priv->sort_order;
}

926
927
/**
 * wnck_window_set_sort_order:
Vincent Untz's avatar
Vincent Untz committed
928
929
 * @window: a #WnckWindow.
 * @order: new sort order for @window.
930
 *
Vincent Untz's avatar
Vincent Untz committed
931
932
 * Sets the sort order of @window. The sort order is used for ordering of
 * @window in #WnckSelector and #WnckTasklist.
933
934
 *
 * Since: 2.20
935
 **/
Vincent Untz's avatar
Vincent Untz committed
936
void        wnck_window_set_sort_order        (WnckWindow *window,
937
					       gint order)
Vincent Untz's avatar
Vincent Untz committed
938
{
939
  g_return_if_fail (WNCK_IS_WINDOW (window));
Vincent Untz's avatar
Vincent Untz committed
940

941
942
943
944
  window->priv->sort_order = order;
  return;
}

Havoc Pennington's avatar
Havoc Pennington committed
945
946
/**
 * wnck_window_get_window_type:
Vincent Untz's avatar
Vincent Untz committed
947
 * @window: a #WnckWindow.
Vincent Untz's avatar
Vincent Untz committed
948
 *
949
 * Gets the semantic type of @window.
Vincent Untz's avatar
Vincent Untz committed
950
 *
Vincent Untz's avatar
Vincent Untz committed
951
 * Return value: the semantic type of @window.
Havoc Pennington's avatar
Havoc Pennington committed
952
953
954
955
 **/
WnckWindowType
wnck_window_get_window_type (WnckWindow *window)
{
956
  /* FIXME: should we have an invalid window type for this? */
Havoc Pennington's avatar
Havoc Pennington committed
957
  g_return_val_if_fail (WNCK_IS_WINDOW (window), 0);
Vincent Untz's avatar
Vincent Untz committed
958

Havoc Pennington's avatar
Havoc Pennington committed
959
960
961
  return window->priv->wintype;
}

962
963
/**
 * wnck_window_set_window_type:
Vincent Untz's avatar
Vincent Untz committed
964
 * @window: a #WnckWindow.
965
 * @wintype: a semantic type.
Vincent Untz's avatar
Vincent Untz committed
966
 *
967
 * Sets the semantic type of @window to @wintype.
Vincent Untz's avatar
Vincent Untz committed
968
969
 *
 * Since: 2.12
970
971
972
973
974
 **/
void
wnck_window_set_window_type (WnckWindow *window, WnckWindowType wintype)
{
  Atom atom;
975
  Display *display;
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

  g_return_if_fail (WNCK_IS_WINDOW (window));

  switch (wintype) {
  case WNCK_WINDOW_NORMAL:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_NORMAL");
    break;
  case WNCK_WINDOW_DESKTOP:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_DESKTOP");
    break;
  case WNCK_WINDOW_DOCK:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_DOCK");
    break;
  case WNCK_WINDOW_DIALOG:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_DIALOG");
    break;
  case WNCK_WINDOW_TOOLBAR:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_TOOLBAR");
    break;
  case WNCK_WINDOW_MENU:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_MENU");
    break;
  case WNCK_WINDOW_UTILITY:
    atom = _wnck_atom_get ("_NET_WM_WINDOW_TYPE_UTILITY");
    break;
For faster browsing, not all history is shown. View entire blame