~ubuntu-branches/debian/sid/openbox/sid

« back to all changes in this revision

Viewing changes to openbox/client.c

  • Committer: Bazaar Package Importer
  • Author(s): Nico Golde, Nico Golde, Eugenio Paolantonio
  • Date: 2011-10-03 22:59:30 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20111003225930-tdvyax5tx63dyoez
Tags: 3.5.0-1
[Nico Golde]
* New upstream release (Closes: #638783).
  - Fix crashes in the menu code (Closes: #563891).
* Add Brazilian translation to openbox.desktop,
  thanks Sérgio Cipolla (Closes: #627912).
* Remove 06_fix_swap_byte_order.patch, applied upstream.
* Bump debhelper dependency to >= 7.0.50~ due to override.
* Remove CHANGELOG from openbox.docs to prevent double installation.
* Add 02_fix_freedesktop_compliance.dpatch desktop file to
  /usr/share/applications.

[Eugenio Paolantonio]
* debian/patches:
  - Disabled 03_place_windows_in_quadrants.patch
  - Updated 01_rc.xml.patch and 06_fix_swap_byte_order.patch
  - Removed 04_fix_ftbfs_no-add-needed.patch and 20_24bits_support.patch
* debian/control:
  - Added myself to the Uploaders.
  - Build-Depends: removed libxau-dev, libxft-dev and python-xdg;
    added libimlib2-dev
  - openbox Suggests: added python-xdg
  - libobrender21 renamed to libobrender27
  - libobparser21 renamed to libobt0
* debian/rules:
  - Rewrote using a simpler debhelper syntax
  - Moved the install pass to openbox.install
* debian/*.{install,links,dirs}:
  - Updated.
* debian/openbox.xsession:
  - Removed. Openbox now ships it by default.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include "debug.h"
22
22
#include "startupnotify.h"
23
23
#include "dock.h"
24
 
#include "xerror.h"
25
24
#include "screen.h"
26
25
#include "moveresize.h"
27
26
#include "ping.h"
28
27
#include "place.h"
29
 
#include "prop.h"
30
 
#include "extensions.h"
31
28
#include "frame.h"
32
29
#include "session.h"
33
30
#include "event.h"
42
39
#include "menuframe.h"
43
40
#include "keyboard.h"
44
41
#include "mouse.h"
45
 
#include "render/render.h"
 
42
#include "obrender/render.h"
46
43
#include "gettext.h"
 
44
#include "obt/display.h"
 
45
#include "obt/xqueue.h"
 
46
#include "obt/prop.h"
47
47
 
48
48
#ifdef HAVE_UNISTD_H
49
49
#  include <unistd.h>
108
108
static void client_call_notifies(ObClient *self, GSList *list);
109
109
static void client_ping_event(ObClient *self, gboolean dead);
110
110
static void client_prompt_kill(ObClient *self);
111
 
static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
112
 
                                       Time launch_time);
 
111
static gboolean client_can_steal_focus(ObClient *self,
 
112
                                       gboolean allow_other_desktop,
 
113
                                       gboolean request_from_user,
 
114
                                       Time steal_time, Time launch_time);
113
115
 
114
116
void client_startup(gboolean reconfig)
115
117
{
116
 
    if ((client_default_icon = RrImageCacheFind(ob_rr_icons,
117
 
                                                ob_rr_theme->def_win_icon,
118
 
                                                ob_rr_theme->def_win_icon_w,
119
 
                                                ob_rr_theme->def_win_icon_h)))
120
 
        RrImageRef(client_default_icon);
121
 
    else {
122
 
        client_default_icon = RrImageNew(ob_rr_icons);
123
 
        RrImageAddPicture(client_default_icon,
124
 
                          ob_rr_theme->def_win_icon,
125
 
                          ob_rr_theme->def_win_icon_w,
126
 
                          ob_rr_theme->def_win_icon_h);
127
 
    }
 
118
    client_default_icon = RrImageNewFromData(
 
119
        ob_rr_icons, ob_rr_theme->def_win_icon,
 
120
        ob_rr_theme->def_win_icon_w, ob_rr_theme->def_win_icon_h);
128
121
 
129
122
    if (reconfig) return;
130
123
 
151
144
 
152
145
void client_add_destroy_notify(ObClientCallback func, gpointer data)
153
146
{
154
 
    ClientCallback *d = g_new(ClientCallback, 1);
 
147
    ClientCallback *d = g_slice_new(ClientCallback);
155
148
    d->func = func;
156
149
    d->data = data;
157
150
    client_destroy_notifies = g_slist_prepend(client_destroy_notifies, d);
164
157
    for (it = client_destroy_notifies; it; it = g_slist_next(it)) {
165
158
        ClientCallback *d = it->data;
166
159
        if (d->func == func) {
167
 
            g_free(d);
 
160
            g_slice_free(ClientCallback, d);
168
161
            client_destroy_notifies =
169
162
                g_slist_delete_link(client_destroy_notifies, it);
170
163
            break;
187
180
    } else
188
181
        windows = NULL;
189
182
 
190
 
    PROP_SETA32(RootWindow(ob_display, ob_screen),
191
 
                net_client_list, window, (gulong*)windows, size);
 
183
    OBT_PROP_SETA32(obt_root(ob_screen), NET_CLIENT_LIST, WINDOW,
 
184
                    (gulong*)windows, size);
192
185
 
193
186
    if (windows)
194
187
        g_free(windows);
196
189
    stacking_set_list();
197
190
}
198
191
 
199
 
void client_manage_all(void)
200
 
{
201
 
    guint i, j, nchild;
202
 
    Window w, *children;
203
 
    XWMHints *wmhints;
204
 
    XWindowAttributes attrib;
205
 
 
206
 
    XQueryTree(ob_display, RootWindow(ob_display, ob_screen),
207
 
               &w, &w, &children, &nchild);
208
 
 
209
 
    /* remove all icon windows from the list */
210
 
    for (i = 0; i < nchild; i++) {
211
 
        if (children[i] == None) continue;
212
 
        wmhints = XGetWMHints(ob_display, children[i]);
213
 
        if (wmhints) {
214
 
            if ((wmhints->flags & IconWindowHint) &&
215
 
                (wmhints->icon_window != children[i]))
216
 
                for (j = 0; j < nchild; j++)
217
 
                    if (children[j] == wmhints->icon_window) {
218
 
                        children[j] = None;
219
 
                        break;
220
 
                    }
221
 
            XFree(wmhints);
222
 
        }
223
 
    }
224
 
 
225
 
    /* manage windows in reverse order from how they were originally mapped.
226
 
       this is an attempt to manage children windows before their parents, so
227
 
       that when the parent is mapped, it can find the child */
228
 
    for (i = 0; i < nchild; ++i) {
229
 
        if (children[i] == None)
230
 
            continue;
231
 
        if (XGetWindowAttributes(ob_display, children[i], &attrib)) {
232
 
            if (attrib.override_redirect) continue;
233
 
 
234
 
            if (attrib.map_state != IsUnmapped)
235
 
                client_manage(children[i], NULL);
236
 
        }
237
 
    }
238
 
    XFree(children);
239
 
}
240
 
 
241
192
void client_manage(Window window, ObPrompt *prompt)
242
193
{
243
194
    ObClient *self;
244
 
    XEvent e;
245
 
    XWindowAttributes attrib;
246
195
    XSetWindowAttributes attrib_set;
247
 
    XWMHints *wmhint;
248
 
    gboolean activate = FALSE;
 
196
    gboolean try_activate = FALSE;
 
197
    gboolean do_activate;
249
198
    ObAppSettings *settings;
250
199
    gboolean transient = FALSE;
251
 
    Rect place, *monitor;
252
 
    Time launch_time, map_time;
 
200
    Rect place;
 
201
    Time launch_time;
253
202
    guint32 user_time;
254
 
 
255
 
    grab_server(TRUE);
256
 
 
257
 
    /* check if it has already been unmapped by the time we started
258
 
       mapping. the grab does a sync so we don't have to here */
259
 
    if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) ||
260
 
        XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e))
261
 
    {
262
 
        XPutBackEvent(ob_display, &e);
263
 
 
264
 
        ob_debug("Trying to manage unmapped window. Aborting that.\n");
265
 
        grab_server(FALSE);
266
 
        return; /* don't manage it */
267
 
    }
268
 
 
269
 
    /* make sure it isn't an override-redirect window */
270
 
    if (!XGetWindowAttributes(ob_display, window, &attrib) ||
271
 
        attrib.override_redirect)
272
 
    {
273
 
        grab_server(FALSE);
274
 
        return; /* don't manage it */
275
 
    }
276
 
 
277
 
    /* is the window a docking app */
278
 
    if ((wmhint = XGetWMHints(ob_display, window))) {
279
 
        if ((wmhint->flags & StateHint) &&
280
 
            wmhint->initial_state == WithdrawnState)
281
 
        {
282
 
            dock_add(window, wmhint);
283
 
            grab_server(FALSE);
284
 
            XFree(wmhint);
285
 
            return;
286
 
        }
287
 
        XFree(wmhint);
288
 
    }
289
 
 
290
 
    ob_debug("Managing window: 0x%lx\n", window);
291
 
 
292
 
    map_time = event_get_server_time();
 
203
    gboolean obplaced;
 
204
 
 
205
    ob_debug("Managing window: 0x%lx", window);
293
206
 
294
207
    /* choose the events we want to receive on the CLIENT window
295
208
       (ObPrompt windows can request events too) */
296
209
    attrib_set.event_mask = CLIENT_EVENTMASK |
297
210
        (prompt ? prompt->event_mask : 0);
298
211
    attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
299
 
    XChangeWindowAttributes(ob_display, window,
 
212
    XChangeWindowAttributes(obt_display, window,
300
213
                            CWEventMask|CWDontPropagate, &attrib_set);
301
214
 
302
215
    /* create the ObClient struct, and populate it from the hints on the
303
216
       window */
304
 
    self = g_new0(ObClient, 1);
305
 
    self->obwin.type = Window_Client;
 
217
    self = g_slice_new0(ObClient);
 
218
    self->obwin.type = OB_WINDOW_CLASS_CLIENT;
306
219
    self->window = window;
307
220
    self->prompt = prompt;
308
221
    self->managed = TRUE;
315
228
    /* get all the stuff off the window */
316
229
    client_get_all(self, TRUE);
317
230
 
318
 
    ob_debug("Window type: %d\n", self->type);
319
 
    ob_debug("Window group: 0x%x\n", self->group?self->group->leader:0);
320
 
    ob_debug("Window name: %s class: %s role: %s\n", self->name, self->class, self->role);
 
231
    ob_debug("Window type: %d", self->type);
 
232
    ob_debug("Window group: 0x%x", self->group?self->group->leader:0);
 
233
    ob_debug("Window name: %s class: %s role: %s title: %s",
 
234
             self->name, self->class, self->role, self->title);
321
235
 
322
236
    /* per-app settings override stuff from client_get_all, and return the
323
237
       settings for other uses too. the returned settings is a shallow copy,
324
238
       that needs to be freed with g_free(). */
325
239
    settings = client_get_settings_state(self);
326
240
 
327
 
    /* now we have all of the window's information so we can set this up.
328
 
       do this before creating the frame, so it can tell that we are still
329
 
       mapping and doesn't go applying things right away */
330
 
    client_setup_decor_and_functions(self, FALSE);
331
 
 
332
241
    /* specify that if we exit, the window should not be destroyed and
333
242
       should be reparented back to root automatically, unless we are managing
334
243
       an internal ObPrompt window  */
335
244
    if (!self->prompt)
336
 
        XChangeSaveSet(ob_display, window, SetModeInsert);
 
245
        XChangeSaveSet(obt_display, window, SetModeInsert);
337
246
 
338
247
    /* create the decoration frame for the client window */
339
248
    self->frame = frame_new(self);
350
259
    /* tell startup notification that this app started */
351
260
    launch_time = sn_app_started(self->startup_id, self->class, self->name);
352
261
 
353
 
    if (!PROP_GET32(self->window, net_wm_user_time, cardinal, &user_time))
354
 
        user_time = map_time;
 
262
    if (!OBT_PROP_GET32(self->window, NET_WM_USER_TIME, CARDINAL, &user_time))
 
263
        user_time = event_time();
355
264
 
356
265
    /* do this after we have a frame.. it uses the frame to help determine the
357
266
       WM_STATE to apply. */
367
276
    if (ob_state() != OB_STATE_STARTING &&
368
277
        (!self->session || self->session->focused) &&
369
278
        /* this means focus=true for window is same as config_focus_new=true */
370
 
        ((config_focus_new || (settings && settings->focus == 1)) ||
 
279
        ((config_focus_new || settings->focus == 1) ||
371
280
         client_search_focus_tree_full(self)) &&
372
281
        /* NET_WM_USER_TIME 0 when mapping means don't focus */
373
282
        (user_time != 0) &&
374
283
        /* this checks for focus=false for the window */
375
284
        settings->focus != 0 &&
376
 
        focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE,
 
285
        focus_valid_target(self, self->desktop,
 
286
                           FALSE, FALSE, TRUE, TRUE, FALSE, FALSE,
377
287
                           settings->focus == 1))
378
288
    {
379
 
        activate = TRUE;
 
289
        try_activate = TRUE;
380
290
    }
381
291
 
382
292
    /* remove the client's border */
383
 
    XSetWindowBorderWidth(ob_display, self->window, 0);
 
293
    XSetWindowBorderWidth(obt_display, self->window, 0);
384
294
 
385
295
    /* adjust the frame to the client's size before showing or placing
386
296
       the window */
389
299
 
390
300
    /* where the frame was placed is where the window was originally */
391
301
    place = self->area;
392
 
    monitor = screen_physical_area_monitor(screen_find_monitor(&place));
 
302
 
 
303
    ob_debug("Going to try activate new window? %s",
 
304
             try_activate ? "yes" : "no");
 
305
    if (try_activate)
 
306
        do_activate = client_can_steal_focus(
 
307
            self, settings->focus == 1,
 
308
            (!!launch_time || settings->focus == 1),
 
309
            event_time(), launch_time);
 
310
    else
 
311
        do_activate = FALSE;
393
312
 
394
313
    /* figure out placement for the window if the window is new */
395
314
    if (ob_state() == OB_STATE_RUNNING) {
396
 
        ob_debug("Positioned: %s @ %d %d\n",
 
315
        ob_debug("Positioned: %s @ %d %d",
397
316
                 (!self->positioned ? "no" :
398
317
                  (self->positioned == PPosition ? "program specified" :
399
318
                   (self->positioned == USPosition ? "user specified" :
401
320
                     "program + user specified" :
402
321
                     "BADNESS !?")))), place.x, place.y);
403
322
 
404
 
        ob_debug("Sized: %s @ %d %d\n",
 
323
        ob_debug("Sized: %s @ %d %d",
405
324
                 (!self->sized ? "no" :
406
325
                  (self->sized == PSize ? "program specified" :
407
326
                   (self->sized == USSize ? "user specified" :
409
328
                     "program + user specified" :
410
329
                     "BADNESS !?")))), place.width, place.height);
411
330
 
412
 
        /* splash screens are also returned as TRUE for transient,
413
 
           and so will be forced on screen below */
414
 
        transient = place_client(self, &place.x, &place.y, settings);
 
331
        obplaced = place_client(self, do_activate, &place.x, &place.y,
 
332
                                settings);
 
333
 
 
334
        /* watch for buggy apps that ask to be placed at (0,0) when there is
 
335
           a strut there */
 
336
        if (!obplaced && place.x == 0 && place.y == 0 &&
 
337
            /* non-normal windows are allowed */
 
338
            client_normal(self) &&
 
339
            /* oldschool fullscreen windows are allowed */
 
340
            !client_is_oldfullscreen(self, &place))
 
341
        {
 
342
            Rect *r;
 
343
 
 
344
            r = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, NULL);
 
345
            if (r->x || r->y) {
 
346
                place.x = r->x;
 
347
                place.y = r->y;
 
348
                ob_debug("Moving buggy app from (0,0) to (%d,%d)", r->x, r->y);
 
349
            }
 
350
            g_slice_free(Rect, r);
 
351
        }
415
352
 
416
353
        /* make sure the window is visible. */
417
354
        client_find_onscreen(self, &place.x, &place.y,
427
364
                                it is up to the placement routines to avoid
428
365
                                the xinerama divides)
429
366
 
430
 
                                splash screens get "transient" set to TRUE by
431
 
                                the place_client call
 
367
                                children and splash screens are forced on
 
368
                                screen, but i don't remember why i decided to
 
369
                                do that.
432
370
                             */
433
371
                             ob_state() == OB_STATE_RUNNING &&
434
 
                             (transient ||
 
372
                             (self->type == OB_CLIENT_TYPE_DIALOG ||
 
373
                              self->type == OB_CLIENT_TYPE_SPLASH ||
435
374
                              (!((self->positioned & USPosition) ||
436
 
                                 (settings && settings->pos_given)) &&
 
375
                                 settings->pos_given) &&
437
376
                               client_normal(self) &&
438
377
                               !self->session &&
439
378
                               /* don't move oldschool fullscreen windows to
440
379
                                  fit inside the struts (fixes Acroread, which
441
380
                                  makes its fullscreen window fit the screen
442
381
                                  but it is not USSize'd or USPosition'd) */
443
 
                               !(self->decorations == 0 &&
444
 
                                 RECT_EQUAL(place, *monitor)))));
 
382
                               !client_is_oldfullscreen(self, &place))));
445
383
    }
446
384
 
447
385
    /* if the window isn't user-sized, then make it fit inside
461
399
          /* don't shrink oldschool fullscreen windows to fit inside the
462
400
             struts (fixes Acroread, which makes its fullscreen window
463
401
             fit the screen but it is not USSize'd or USPosition'd) */
464
 
          !(self->decorations == 0 && RECT_EQUAL(place, *monitor)))))
 
402
          !client_is_oldfullscreen(self, &place))))
465
403
    {
466
404
        Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &place);
467
405
 
473
411
        place.width = MIN(place.width, a->width);
474
412
        place.height = MIN(place.height, a->height);
475
413
 
476
 
        ob_debug("setting window size to %dx%d\n", place.width, place.height);
 
414
        ob_debug("setting window size to %dx%d", place.width, place.height);
477
415
 
478
416
        /* get the size of the client back */
479
417
        place.width -= self->frame->size.left + self->frame->size.right;
480
418
        place.height -= self->frame->size.top + self->frame->size.bottom;
481
419
 
482
 
        g_free(a);
 
420
        g_slice_free(Rect, a);
483
421
    }
484
422
 
485
423
    ob_debug("placing window 0x%x at %d, %d with size %d x %d. "
486
 
             "some restrictions may apply\n",
 
424
             "some restrictions may apply",
487
425
             self->window, place.x, place.y, place.width, place.height);
488
426
    if (self->session)
489
427
        ob_debug("  but session requested %d, %d  %d x %d instead, "
490
 
                 "overriding\n",
 
428
                 "overriding",
491
429
                 self->session->x, self->session->y,
492
430
                 self->session->w, self->session->h);
493
431
 
499
437
    client_apply_startup_state(self, place.x, place.y,
500
438
                               place.width, place.height);
501
439
 
502
 
    g_free(monitor);
503
 
    monitor = NULL;
504
 
 
505
 
    ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s\n",
506
 
                  activate ? "yes" : "no");
507
 
    if (activate) {
508
 
        activate = client_can_steal_focus(self, map_time, launch_time);
509
 
 
510
 
        if (!activate) {
 
440
    /* set the initial value of the desktop hint, when one wasn't requested
 
441
       on map. */
 
442
    OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, self->desktop);
 
443
 
 
444
    /* grab mouse bindings before showing the window */
 
445
    mouse_grab_for_client(self, TRUE);
 
446
 
 
447
    /* this has to happen before we try focus the window, but we want it to
 
448
       happen after the client's stacking has been determined or it looks bad
 
449
    */
 
450
    {
 
451
        gulong ignore_start;
 
452
        if (!config_focus_under_mouse)
 
453
            ignore_start = event_start_ignore_all_enters();
 
454
 
 
455
        client_show(self);
 
456
 
 
457
        if (!config_focus_under_mouse)
 
458
            event_end_ignore_all_enters(ignore_start);
 
459
    }
 
460
 
 
461
    /* activate/hilight/raise the window */
 
462
    if (try_activate) {
 
463
        if (do_activate) {
 
464
            gboolean stacked = client_restore_session_stacking(self);
 
465
            client_present(self, FALSE, !stacked, TRUE);
 
466
        }
 
467
        else {
511
468
            /* if the client isn't stealing focus, then hilite it so the user
512
469
               knows it is there, but don't do this if we're restoring from a
513
470
               session */
527
484
            stacking_raise(CLIENT_AS_WINDOW(self));
528
485
    }
529
486
 
530
 
    mouse_grab_for_client(self, TRUE);
531
 
 
532
 
    /* this has to happen before we try focus the window, but we want it to
533
 
       happen after the client's stacking has been determined or it looks bad
534
 
    */
535
 
    {
536
 
        gulong ignore_start;
537
 
        if (!config_focus_under_mouse)
538
 
            ignore_start = event_start_ignore_all_enters();
539
 
 
540
 
        client_show(self);
541
 
 
542
 
        if (!config_focus_under_mouse)
543
 
            event_end_ignore_all_enters(ignore_start);
544
 
    }
545
 
 
546
 
    if (activate) {
547
 
        gboolean stacked = client_restore_session_stacking(self);
548
 
        client_present(self, FALSE, !stacked, TRUE);
549
 
    }
550
 
 
551
487
    /* add to client list/map */
552
488
    client_list = g_list_append(client_list, self);
553
 
    g_hash_table_insert(window_map, &self->window, self);
 
489
    window_add(&self->window, CLIENT_AS_WINDOW(self));
554
490
 
555
491
    /* this has to happen after we're in the client_list */
556
492
    if (STRUT_EXISTS(self->strut))
560
496
    client_set_list();
561
497
 
562
498
    /* free the ObAppSettings shallow copy */
563
 
    g_free(settings);
 
499
    g_slice_free(ObAppSettings, settings);
564
500
 
565
 
    ob_debug("Managed window 0x%lx plate 0x%x (%s)\n",
 
501
    ob_debug("Managed window 0x%lx plate 0x%x (%s)",
566
502
             window, self->frame->window, self->class);
567
 
 
568
 
    return;
569
503
}
570
504
 
571
505
ObClient *client_fake_manage(Window window)
573
507
    ObClient *self;
574
508
    ObAppSettings *settings;
575
509
 
576
 
    ob_debug("Pretend-managing window: %lx\n", window);
 
510
    ob_debug("Pretend-managing window: %lx", window);
577
511
 
578
512
    /* do this minimal stuff to figure out the client's decorations */
579
513
 
580
 
    self = g_new0(ObClient, 1);
 
514
    self = g_slice_new0(ObClient);
581
515
    self->window = window;
582
516
 
583
517
    client_get_all(self, FALSE);
585
519
       uses too. this returns a shallow copy that needs to be freed */
586
520
    settings = client_get_settings_state(self);
587
521
 
588
 
    client_setup_decor_and_functions(self, FALSE);
589
 
 
590
522
    /* create the decoration frame for the client window and adjust its size */
591
523
    self->frame = frame_new(self);
592
 
    frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
593
 
 
594
 
    ob_debug("gave extents left %d right %d top %d bottom %d\n",
 
524
 
 
525
    client_apply_startup_state(self, self->area.x, self->area.y,
 
526
                               self->area.width, self->area.height);
 
527
 
 
528
    ob_debug("gave extents left %d right %d top %d bottom %d",
595
529
             self->frame->size.left, self->frame->size.right,
596
530
             self->frame->size.top, self->frame->size.bottom);
597
531
 
598
532
    /* free the ObAppSettings shallow copy */
599
 
    g_free(settings);
 
533
    g_slice_free(ObAppSettings, settings);
600
534
 
601
535
    return self;
602
536
}
612
546
    GSList *it;
613
547
    gulong ignore_start;
614
548
 
615
 
    ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)\n",
 
549
    ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)",
616
550
             self->window, self->frame->window,
617
551
             self->class, self->title ? self->title : "");
618
552
 
620
554
 
621
555
    /* we dont want events no more. do this before hiding the frame so we
622
556
       don't generate more events */
623
 
    XSelectInput(ob_display, self->window, NoEventMask);
 
557
    XSelectInput(obt_display, self->window, NoEventMask);
624
558
 
625
559
    /* ignore enter events from the unmap so it doesnt mess with the focus */
626
560
    if (!config_focus_under_mouse)
628
562
 
629
563
    frame_hide(self->frame);
630
564
    /* flush to send the hide to the server quickly */
631
 
    XFlush(ob_display);
 
565
    XFlush(obt_display);
632
566
 
633
567
    if (!config_focus_under_mouse)
634
568
        event_end_ignore_all_enters(ignore_start);
640
574
    /* remove the window from our save set, unless we are managing an internal
641
575
       ObPrompt window */
642
576
    if (!self->prompt)
643
 
        XChangeSaveSet(ob_display, self->window, SetModeDelete);
 
577
        XChangeSaveSet(obt_display, self->window, SetModeDelete);
644
578
 
645
579
    /* update the focus lists */
646
580
    focus_order_remove(self);
655
589
 
656
590
    client_list = g_list_remove(client_list, self);
657
591
    stacking_remove(self);
658
 
    g_hash_table_remove(window_map, &self->window);
 
592
    window_remove(self->window);
659
593
 
660
594
    /* once the client is out of the list, update the struts to remove its
661
595
       influence */
708
642
        self->decorations = 0; /* unmanaged windows have no decor */
709
643
 
710
644
        /* give the client its border back */
711
 
        XSetWindowBorderWidth(ob_display, self->window, self->border_width);
 
645
        XSetWindowBorderWidth(obt_display, self->window, self->border_width);
712
646
 
713
647
        client_move_resize(self, a.x, a.y, a.width, a.height);
714
648
    }
721
655
    if (ob_state() != OB_STATE_EXITING) {
722
656
        /* these values should not be persisted across a window
723
657
           unmapping/mapping */
724
 
        PROP_ERASE(self->window, net_wm_desktop);
725
 
        PROP_ERASE(self->window, net_wm_state);
726
 
        PROP_ERASE(self->window, wm_state);
 
658
        OBT_PROP_ERASE(self->window, NET_WM_DESKTOP);
 
659
        OBT_PROP_ERASE(self->window, NET_WM_STATE);
 
660
        OBT_PROP_ERASE(self->window, WM_STATE);
727
661
    } else {
728
662
        /* if we're left in an unmapped state, the client wont be mapped.
729
663
           this is bad, since we will no longer be managing the window on
730
664
           restart */
731
 
        XMapWindow(ob_display, self->window);
 
665
        XMapWindow(obt_display, self->window);
732
666
    }
733
667
 
734
668
    /* these should not be left on the window ever.  other window managers
735
669
       don't necessarily use them and it will mess them up (like compiz) */
736
 
    PROP_ERASE(self->window, net_wm_visible_name);
737
 
    PROP_ERASE(self->window, net_wm_visible_icon_name);
 
670
    OBT_PROP_ERASE(self->window, NET_WM_VISIBLE_NAME);
 
671
    OBT_PROP_ERASE(self->window, NET_WM_VISIBLE_ICON_NAME);
738
672
 
739
673
    /* update the list hints */
740
674
    client_set_list();
741
675
 
742
 
    ob_debug("Unmanaged window 0x%lx\n", self->window);
 
676
    ob_debug("Unmanaged window 0x%lx", self->window);
743
677
 
744
678
    /* free all data allocated in the client struct */
745
679
    RrImageUnref(self->icon_set);
754
688
    g_free(self->role);
755
689
    g_free(self->client_machine);
756
690
    g_free(self->sm_client_id);
757
 
    g_free(self);
 
691
    g_slice_free(ObClient, self);
758
692
}
759
693
 
760
694
void client_fake_unmanage(ObClient *self)
762
696
    /* this is all that got allocated to get the decorations */
763
697
 
764
698
    frame_free(self->frame);
765
 
    g_free(self);
 
699
    g_slice_free(ObClient, self);
766
700
}
767
701
 
768
 
static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
 
702
static gboolean client_can_steal_focus(ObClient *self,
 
703
                                       gboolean allow_other_desktop,
 
704
                                       gboolean request_from_user,
 
705
                                       Time steal_time,
769
706
                                       Time launch_time)
770
707
{
771
708
    gboolean steal;
772
709
    gboolean relative_focused;
773
 
    gboolean parent_focused;
774
710
 
775
711
    steal = TRUE;
776
712
 
777
 
    parent_focused = (focus_client != NULL &&
778
 
                      client_search_focus_parent(self));
779
713
    relative_focused = (focus_client != NULL &&
780
714
                        (client_search_focus_tree_full(self) != NULL ||
781
715
                         client_search_focus_group_full(self) != NULL));
782
716
 
783
717
    /* This is focus stealing prevention */
784
 
    ob_debug_type(OB_DEBUG_FOCUS,
785
 
                  "Want to focus window 0x%x at time %u "
786
 
                  "launched at %u (last user interaction time %u)\n",
787
 
                  self->window, steal_time, launch_time,
788
 
                  event_last_user_time);
789
 
 
790
 
    /* if it's on another desktop */
 
718
    ob_debug("Want to focus window 0x%x at time %u "
 
719
             "launched at %u (last user interaction time %u) "
 
720
             "request from %s, allow other desktop: %s",
 
721
             self->window, steal_time, launch_time,
 
722
             event_last_user_time,
 
723
             (request_from_user ? "user" : "other"),
 
724
             (allow_other_desktop ? "yes" : "no"));
 
725
 
 
726
    /*
 
727
      if no launch time is provided for an application, make one up.
 
728
 
 
729
      if the window is related to other existing windows
 
730
        and one of those windows was the last used
 
731
          then we will give it a launch time equal to the last user time,
 
732
          which will end up giving the window focus probably.
 
733
        else
 
734
          the window is related to other windows, but you are not working in
 
735
          them?
 
736
          seems suspicious, so we will give it a launch time of
 
737
          NOW - STEAL_INTERVAL,
 
738
          so it will be given focus only if we didn't use something else
 
739
          during the steal interval.
 
740
      else
 
741
        the window is all on its own, so we can't judge it.  give it a launch
 
742
        time equal to the last user time, so it will probably take focus.
 
743
 
 
744
      this way running things from a terminal will give them focus, but popups
 
745
      without a launch time shouldn't steal focus so easily.
 
746
    */
 
747
 
 
748
    if (!launch_time) {
 
749
        if (client_has_relative(self)) {
 
750
            if (event_last_user_time && client_search_focus_group_full(self)) {
 
751
                /* our relative is focused */
 
752
                launch_time = event_last_user_time;
 
753
                ob_debug("Unknown launch time, using %u - window in active "
 
754
                         "group", launch_time);
 
755
            }
 
756
            else if (!request_from_user) {
 
757
                /* has relatives which are not being used. suspicious */
 
758
                launch_time = event_time() - OB_EVENT_USER_TIME_DELAY;
 
759
                ob_debug("Unknown launch time, using %u - window in inactive "
 
760
                         "group", launch_time);
 
761
            }
 
762
            else {
 
763
                /* has relatives which are not being used, but the user seems
 
764
                   to want to go there! */
 
765
            launch_time = event_last_user_time;
 
766
            ob_debug("Unknown launch time, using %u - user request",
 
767
                     launch_time);
 
768
            }
 
769
        }
 
770
        else {
 
771
            /* the window is on its own, probably the user knows it is going
 
772
               to appear */
 
773
            launch_time = event_last_user_time;
 
774
            ob_debug("Unknown launch time, using %u - independent window",
 
775
                     launch_time);
 
776
        }
 
777
    }
 
778
 
 
779
    /* if it's on another desktop
 
780
       then if allow_other_desktop is true, we don't want to let it steal
 
781
       focus, unless it was launched after we changed desktops and the request
 
782
       came from the user
 
783
     */
791
784
    if (!(self->desktop == screen_desktop ||
792
785
          self->desktop == DESKTOP_ALL) &&
793
 
        /* the timestamp is from before you changed desktops */
794
 
        (!launch_time ||
795
 
         (screen_desktop_user_time &&
 
786
        (!allow_other_desktop ||
 
787
         (request_from_user && screen_desktop_user_time &&
796
788
          !event_time_after(launch_time, screen_desktop_user_time))))
797
789
    {
798
790
        steal = FALSE;
799
 
        ob_debug_type(OB_DEBUG_FOCUS,
800
 
                      "Not focusing the window because its on another "
801
 
                      "desktop\n");
 
791
        ob_debug("Not focusing the window because its on another desktop\n");
802
792
    }
803
793
    /* If something is focused... */
804
794
    else if (focus_client) {
805
795
        /* If the user is working in another window right now, then don't
806
796
           steal focus */
807
 
        if (!parent_focused &&
808
 
            event_last_user_time && launch_time &&
809
 
            event_time_after(event_last_user_time, launch_time) &&
810
 
            event_last_user_time != launch_time &&
 
797
        if (!relative_focused &&
 
798
            event_last_user_time &&
 
799
            /* last user time must be strictly > launch_time to block focus */
 
800
            (event_time_after(event_last_user_time, launch_time) &&
 
801
             event_last_user_time != launch_time) &&
811
802
            event_time_after(event_last_user_time,
812
803
                             steal_time - OB_EVENT_USER_TIME_DELAY))
813
804
        {
814
805
            steal = FALSE;
815
 
            ob_debug_type(OB_DEBUG_FOCUS,
816
 
                          "Not focusing the window because the user is "
817
 
                          "working in another window that is not "
818
 
                          "its parent\n");
819
 
        }
820
 
        /* If the new window is a transient (and its relatives aren't
821
 
           focused) */
822
 
        else if (client_has_parent(self) && !relative_focused) {
823
 
            steal = FALSE;
824
 
            ob_debug_type(OB_DEBUG_FOCUS,
825
 
                          "Not focusing the window because it is a "
826
 
                          "transient, and its relatives aren't focused\n");
827
 
        }
828
 
        /* Don't steal focus from globally active clients.
829
 
           I stole this idea from KWin. It seems nice.
830
 
        */
831
 
        else if (!(focus_client->can_focus ||
832
 
                   focus_client->focus_notify))
833
 
        {
834
 
            steal = FALSE;
835
 
            ob_debug_type(OB_DEBUG_FOCUS,
836
 
                          "Not focusing the window because a globally "
837
 
                          "active client has focus\n");
 
806
            ob_debug("Not focusing the window because the user is "
 
807
                     "working in another window that is not its relative");
838
808
        }
839
809
        /* Don't move focus if it's not going to go to this window
840
810
           anyway */
841
811
        else if (client_focus_target(self) != self) {
842
812
            steal = FALSE;
843
 
            ob_debug_type(OB_DEBUG_FOCUS,
844
 
                          "Not focusing the window because another window "
845
 
                          "would get the focus anyway\n");
 
813
            ob_debug("Not focusing the window because another window "
 
814
                     "would get the focus anyway");
846
815
        }
847
 
        /* Don't move focus if the window is not visible on the current
848
 
           desktop and none of its relatives are focused */
849
 
        else if (!(self->desktop == screen_desktop ||
850
 
                   self->desktop == DESKTOP_ALL) &&
851
 
                 !relative_focused)
852
 
        {
853
 
            steal = FALSE;
854
 
            ob_debug_type(OB_DEBUG_FOCUS,
855
 
                          "Not focusing the window because it is on "
856
 
                          "another desktop and no relatives are focused ");
 
816
        /* For requests that don't come from the user */
 
817
        else if (!request_from_user) {
 
818
            /* If the new window is a transient (and its relatives aren't
 
819
               focused) */
 
820
            if (client_has_parent(self) && !relative_focused) {
 
821
                steal = FALSE;
 
822
                ob_debug("Not focusing the window because it is a "
 
823
                         "transient, and its relatives aren't focused");
 
824
            }
 
825
            /* Don't steal focus from globally active clients.
 
826
               I stole this idea from KWin. It seems nice.
 
827
            */
 
828
            else if (!(focus_client->can_focus || focus_client->focus_notify))
 
829
            {
 
830
                steal = FALSE;
 
831
                ob_debug("Not focusing the window because a globally "
 
832
                         "active client has focus");
 
833
            }
 
834
            /* Don't move focus if the window is not visible on the current
 
835
               desktop and none of its relatives are focused */
 
836
            else if (!allow_other_desktop &&
 
837
                     !screen_compare_desktops(self->desktop, screen_desktop) &&
 
838
                     !relative_focused)
 
839
            {
 
840
                steal = FALSE;
 
841
                ob_debug("Not focusing the window because it is on "
 
842
                         "another desktop and no relatives are focused ");
 
843
            }
857
844
        }
858
845
    }
859
846
 
860
847
    if (!steal)
861
 
        ob_debug_type(OB_DEBUG_FOCUS,
862
 
                      "Focus stealing prevention activated for %s at "
863
 
                      "time %u (last user interaction time %u)\n",
864
 
                      self->title, steal_time, event_last_user_time);
 
848
        ob_debug("Focus stealing prevention activated for %s at "
 
849
                 "time %u (last user interaction time %u)",
 
850
                 self->title, steal_time, event_last_user_time);
 
851
    else
 
852
        ob_debug("Allowing focus stealing for %s at time %u (last user "
 
853
                 "interaction time %u)",
 
854
                 self->title, steal_time, event_last_user_time);
865
855
    return steal;
866
856
}
867
857
 
878
868
        ObAppSettings *app = it->data;
879
869
        gboolean match = TRUE;
880
870
 
881
 
        g_assert(app->name != NULL || app->class != NULL);
 
871
        g_assert(app->name != NULL || app->class != NULL ||
 
872
                 app->role != NULL || app->title != NULL ||
 
873
                 (signed)app->type >= 0);
882
874
 
883
 
        /* we know that either name or class is not NULL so it will have to
884
 
           match to use the rule */
885
875
        if (app->name &&
886
876
            !g_pattern_match(app->name, strlen(self->name), self->name, NULL))
887
877
            match = FALSE;
893
883
                 !g_pattern_match(app->role,
894
884
                                  strlen(self->role), self->role, NULL))
895
885
            match = FALSE;
896
 
        else if ((signed)app->type >= 0 && app->type != self->type)
897
 
            match = FALSE;
 
886
        else if (app->title &&
 
887
                 !g_pattern_match(app->title,
 
888
                                  strlen(self->title), self->title, NULL))
 
889
            match = FALSE;
 
890
        else if ((signed)app->type >= 0 && app->type != self->type) {
 
891
            match = FALSE;
 
892
        }
898
893
 
899
894
        if (match) {
900
 
            ob_debug("Window matching: %s\n", app->name);
 
895
            ob_debug("Window matching: %s", app->name);
901
896
 
902
897
            /* copy the settings to our struct, overriding the existing
903
898
               settings if they are not defaults */
952
947
    GList *it;
953
948
 
954
949
    ob_debug_type(OB_DEBUG_SM,
955
 
                  "Restore session for client %s\n", self->title);
 
950
                  "Restore session for client %s", self->title);
956
951
 
957
952
    if (!(it = session_state_find(self))) {
958
953
        ob_debug_type(OB_DEBUG_SM,
959
 
                      "Session data not found for client %s\n", self->title);
 
954
                      "Session data not found for client %s", self->title);
960
955
        return;
961
956
    }
962
957
 
963
958
    self->session = it->data;
964
959
 
965
 
    ob_debug_type(OB_DEBUG_SM, "Session data loaded for client %s\n",
 
960
    ob_debug_type(OB_DEBUG_SM, "Session data loaded for client %s",
966
961
                  self->title);
967
962
 
968
963
    RECT_SET_POINT(self->area, self->session->x, self->session->y);
972
967
        self->area.width = self->session->w;
973
968
    if (self->session->h > 0)
974
969
        self->area.height = self->session->h;
975
 
    XResizeWindow(ob_display, self->window,
 
970
    XResizeWindow(obt_display, self->window,
976
971
                  self->area.width, self->area.height);
977
972
 
978
973
    self->desktop = (self->session->desktop == DESKTOP_ALL ?
979
974
                     self->session->desktop :
980
975
                     MIN(screen_num_desktops - 1, self->session->desktop));
981
 
    PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
 
976
    OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, self->desktop);
982
977
 
983
978
    self->shaded = self->session->shaded;
984
979
    self->iconic = self->session->iconic;
1140
1135
        if (rudeb && !self->strut.bottom && *y + fh > a->y + a->height)
1141
1136
            *y = a->y + MAX(0, a->height - fh);
1142
1137
 
1143
 
        g_free(a);
 
1138
        g_slice_free(Rect, a);
1144
1139
    }
1145
1140
 
1146
1141
    /* get where the client should be */
1159
1154
    client_get_mwm_hints(self);
1160
1155
    /* this can change the mwmhints for special cases */
1161
1156
    client_get_type_and_transientness(self);
 
1157
    client_update_normal_hints(self);
 
1158
 
 
1159
    /* set up the decor/functions before getting the state.  the states may
 
1160
       affect which functions are available, but we want to know the maximum
 
1161
       decor/functions are available to this window, so we can then apply them
 
1162
       in client_apply_startup_state() */
 
1163
    client_setup_decor_and_functions(self, FALSE);
 
1164
 
1162
1165
    client_get_state(self);
1163
 
    client_update_normal_hints(self);
1164
1166
 
1165
1167
    /* get the session related properties, these can change decorations
1166
1168
       from per-app settings */
1167
1169
    client_get_session_ids(self);
1168
1170
 
1169
 
    /* save the values of the variables used for app rule matching */
1170
 
    client_save_app_rule_values(self);
1171
 
 
1172
1171
    /* now we got everything that can affect the decorations */
1173
1172
    if (!real)
1174
1173
        return;
1176
1175
    /* get this early so we have it for debugging */
1177
1176
    client_update_title(self);
1178
1177
 
 
1178
    /* save the values of the variables used for app rule matching */
 
1179
    client_save_app_rule_values(self);
 
1180
 
1179
1181
    client_update_protocols(self);
1180
1182
 
1181
1183
    client_update_wmhints(self);
1208
1210
 
1209
1211
static void client_get_startup_id(ObClient *self)
1210
1212
{
1211
 
    if (!(PROP_GETS(self->window, net_startup_id, utf8, &self->startup_id)))
 
1213
    if (!(OBT_PROP_GETS_UTF8(self->window, NET_STARTUP_ID, &self->startup_id)))
1212
1214
        if (self->group)
1213
 
            PROP_GETS(self->group->leader,
1214
 
                      net_startup_id, utf8, &self->startup_id);
 
1215
            OBT_PROP_GETS_UTF8(self->group->leader, NET_STARTUP_ID,
 
1216
                               &self->startup_id);
1215
1217
}
1216
1218
 
1217
1219
static void client_get_area(ObClient *self)
1219
1221
    XWindowAttributes wattrib;
1220
1222
    Status ret;
1221
1223
 
1222
 
    ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
 
1224
    ret = XGetWindowAttributes(obt_display, self->window, &wattrib);
1223
1225
    g_assert(ret != BadWindow);
1224
1226
 
1225
1227
    RECT_SET(self->area, wattrib.x, wattrib.y, wattrib.width, wattrib.height);
1226
1228
    POINT_SET(self->root_pos, wattrib.x, wattrib.y);
1227
1229
    self->border_width = wattrib.border_width;
1228
1230
 
1229
 
    ob_debug("client area: %d %d  %d %d  bw %d\n", wattrib.x, wattrib.y,
 
1231
    ob_debug("client area: %d %d  %d %d  bw %d", wattrib.x, wattrib.y,
1230
1232
             wattrib.width, wattrib.height, wattrib.border_width);
1231
1233
}
1232
1234
 
1234
1236
{
1235
1237
    guint32 d = screen_num_desktops; /* an always-invalid value */
1236
1238
 
1237
 
    if (PROP_GET32(self->window, net_wm_desktop, cardinal, &d)) {
 
1239
    if (OBT_PROP_GET32(self->window, NET_WM_DESKTOP, CARDINAL, &d)) {
1238
1240
        if (d >= screen_num_desktops && d != DESKTOP_ALL)
1239
1241
            self->desktop = screen_num_desktops - 1;
1240
1242
        else
1241
1243
            self->desktop = d;
1242
 
        ob_debug("client requested desktop 0x%x\n", self->desktop);
 
1244
        ob_debug("client requested desktop 0x%x", self->desktop);
1243
1245
    } else {
1244
1246
        GSList *it;
1245
1247
        gboolean first = TRUE;
1262
1264
        if (all != screen_num_desktops) {
1263
1265
            self->desktop = all;
1264
1266
 
1265
 
            ob_debug("client desktop set from parents: 0x%x\n",
 
1267
            ob_debug("client desktop set from parents: 0x%x",
1266
1268
                     self->desktop);
1267
1269
        }
1268
1270
        /* try get from the startup-notification protocol */
1270
1272
            if (self->desktop >= screen_num_desktops &&
1271
1273
                self->desktop != DESKTOP_ALL)
1272
1274
                self->desktop = screen_num_desktops - 1;
1273
 
            ob_debug("client desktop set from startup-notification: 0x%x\n",
 
1275
            ob_debug("client desktop set from startup-notification: 0x%x",
1274
1276
                     self->desktop);
1275
1277
        }
1276
1278
        /* defaults to the current desktop */
1277
1279
        else {
1278
1280
            self->desktop = screen_desktop;
1279
 
            ob_debug("client desktop set to the current desktop: %d\n",
 
1281
            ob_debug("client desktop set to the current desktop: %d",
1280
1282
                     self->desktop);
1281
1283
        }
1282
1284
    }
1287
1289
    guint32 *state;
1288
1290
    guint num;
1289
1291
 
1290
 
    if (PROP_GETA32(self->window, net_wm_state, atom, &state, &num)) {
 
1292
    if (OBT_PROP_GETA32(self->window, NET_WM_STATE, ATOM, &state, &num)) {
1291
1293
        gulong i;
1292
1294
        for (i = 0; i < num; ++i) {
1293
 
            if (state[i] == prop_atoms.net_wm_state_modal)
 
1295
            if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_MODAL))
1294
1296
                self->modal = TRUE;
1295
 
            else if (state[i] == prop_atoms.net_wm_state_shaded)
 
1297
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_SHADED))
1296
1298
                self->shaded = TRUE;
1297
 
            else if (state[i] == prop_atoms.net_wm_state_hidden)
 
1299
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_HIDDEN))
1298
1300
                self->iconic = TRUE;
1299
 
            else if (state[i] == prop_atoms.net_wm_state_skip_taskbar)
 
1301
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR))
1300
1302
                self->skip_taskbar = TRUE;
1301
 
            else if (state[i] == prop_atoms.net_wm_state_skip_pager)
 
1303
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER))
1302
1304
                self->skip_pager = TRUE;
1303
 
            else if (state[i] == prop_atoms.net_wm_state_fullscreen)
 
1305
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN))
1304
1306
                self->fullscreen = TRUE;
1305
 
            else if (state[i] == prop_atoms.net_wm_state_maximized_vert)
 
1307
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT))
1306
1308
                self->max_vert = TRUE;
1307
 
            else if (state[i] == prop_atoms.net_wm_state_maximized_horz)
 
1309
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ))
1308
1310
                self->max_horz = TRUE;
1309
 
            else if (state[i] == prop_atoms.net_wm_state_above)
 
1311
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_ABOVE))
1310
1312
                self->above = TRUE;
1311
 
            else if (state[i] == prop_atoms.net_wm_state_below)
 
1313
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_BELOW))
1312
1314
                self->below = TRUE;
1313
 
            else if (state[i] == prop_atoms.net_wm_state_demands_attention)
 
1315
            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION))
1314
1316
                self->demands_attention = TRUE;
1315
 
            else if (state[i] == prop_atoms.ob_wm_state_undecorated)
 
1317
            else if (state[i] == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
1316
1318
                self->undecorated = TRUE;
1317
1319
        }
1318
1320
 
1324
1326
{
1325
1327
    self->shaped = FALSE;
1326
1328
#ifdef SHAPE
1327
 
    if (extensions_shape) {
 
1329
    if (obt_display_extension_shape) {
1328
1330
        gint foo;
1329
1331
        guint ufoo;
1330
1332
        gint s;
1331
1333
 
1332
 
        XShapeSelectInput(ob_display, self->window, ShapeNotifyMask);
 
1334
        XShapeSelectInput(obt_display, self->window, ShapeNotifyMask);
1333
1335
 
1334
 
        XShapeQueryExtents(ob_display, self->window, &s, &foo,
 
1336
        XShapeQueryExtents(obt_display, self->window, &s, &foo,
1335
1337
                           &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
1336
1338
                           &ufoo);
1337
1339
        self->shaped = !!s;
1345
1347
    ObClient *target = NULL;
1346
1348
    gboolean trangroup = FALSE;
1347
1349
 
1348
 
    if (XGetTransientForHint(ob_display, self->window, &t)) {
 
1350
    if (XGetTransientForHint(obt_display, self->window, &t)) {
1349
1351
        if (t != self->window) { /* can't be transient to itself! */
1350
 
            target = g_hash_table_lookup(window_map, &t);
 
1352
            ObWindow *tw = window_find(t);
1351
1353
            /* if this happens then we need to check for it */
1352
 
            g_assert(target != self);
1353
 
            if (target && !WINDOW_IS_CLIENT(target)) {
 
1354
            g_assert(tw != CLIENT_AS_WINDOW(self));
 
1355
            if (tw && WINDOW_IS_CLIENT(tw)) {
1354
1356
                /* watch out for windows with a parent that is something
1355
1357
                   different, like a dockapp for example */
1356
 
                target = NULL;
 
1358
                target = WINDOW_AS_CLIENT(tw);
1357
1359
            }
1358
1360
        }
1359
1361
 
1360
1362
        /* Setting the transient_for to Root is actually illegal, however
1361
1363
           applications from time have done this to specify transient for
1362
1364
           their group */
1363
 
        if (!target && self->group && t == RootWindow(ob_display, ob_screen))
 
1365
        if (!target && self->group && t == obt_root(ob_screen))
1364
1366
            trangroup = TRUE;
1365
1367
    } else if (self->group && self->transient)
1366
1368
        trangroup = TRUE;
1495
1497
 
1496
1498
    self->mwmhints.flags = 0; /* default to none */
1497
1499
 
1498
 
    if (PROP_GETA32(self->window, motif_wm_hints, motif_wm_hints,
1499
 
                    &hints, &num)) {
 
1500
    if (OBT_PROP_GETA32(self->window, MOTIF_WM_HINTS, MOTIF_WM_HINTS,
 
1501
                        &hints, &num)) {
1500
1502
        if (num >= OB_MWM_ELEMENTS) {
1501
1503
            self->mwmhints.flags = hints[0];
1502
1504
            self->mwmhints.functions = hints[1];
1515
1517
    self->type = -1;
1516
1518
    self->transient = FALSE;
1517
1519
 
1518
 
    if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
 
1520
    if (OBT_PROP_GETA32(self->window, NET_WM_WINDOW_TYPE, ATOM, &val, &num)) {
1519
1521
        /* use the first value that we know about in the array */
1520
1522
        for (i = 0; i < num; ++i) {
1521
 
            if (val[i] == prop_atoms.net_wm_window_type_desktop)
 
1523
            if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DESKTOP))
1522
1524
                self->type = OB_CLIENT_TYPE_DESKTOP;
1523
 
            else if (val[i] == prop_atoms.net_wm_window_type_dock)
 
1525
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DOCK))
1524
1526
                self->type = OB_CLIENT_TYPE_DOCK;
1525
 
            else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
 
1527
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_TOOLBAR))
1526
1528
                self->type = OB_CLIENT_TYPE_TOOLBAR;
1527
 
            else if (val[i] == prop_atoms.net_wm_window_type_menu)
 
1529
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_MENU))
1528
1530
                self->type = OB_CLIENT_TYPE_MENU;
1529
 
            else if (val[i] == prop_atoms.net_wm_window_type_utility)
 
1531
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_UTILITY))
1530
1532
                self->type = OB_CLIENT_TYPE_UTILITY;
1531
 
            else if (val[i] == prop_atoms.net_wm_window_type_splash)
 
1533
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_SPLASH))
1532
1534
                self->type = OB_CLIENT_TYPE_SPLASH;
1533
 
            else if (val[i] == prop_atoms.net_wm_window_type_dialog)
 
1535
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG))
1534
1536
                self->type = OB_CLIENT_TYPE_DIALOG;
1535
 
            else if (val[i] == prop_atoms.net_wm_window_type_normal)
 
1537
            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_NORMAL))
1536
1538
                self->type = OB_CLIENT_TYPE_NORMAL;
1537
 
            else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
 
1539
            else if (val[i] == OBT_PROP_ATOM(KDE_NET_WM_WINDOW_TYPE_OVERRIDE))
 
1540
            {
1538
1541
                /* prevent this window from getting any decor or
1539
1542
                   functionality */
1540
1543
                self->mwmhints.flags &= (OB_MWM_FLAG_FUNCTIONS |
1548
1551
        g_free(val);
1549
1552
    }
1550
1553
 
1551
 
    if (XGetTransientForHint(ob_display, self->window, &t))
 
1554
    if (XGetTransientForHint(obt_display, self->window, &t))
1552
1555
        self->transient = TRUE;
1553
1556
 
1554
1557
    if (self->type == (ObClientType) -1) {
1574
1577
void client_update_protocols(ObClient *self)
1575
1578
{
1576
1579
    guint32 *proto;
1577
 
    guint num_return, i;
 
1580
    guint num_ret, i;
1578
1581
 
1579
1582
    self->focus_notify = FALSE;
1580
1583
    self->delete_window = FALSE;
1581
1584
 
1582
 
    if (PROP_GETA32(self->window, wm_protocols, atom, &proto, &num_return)) {
1583
 
        for (i = 0; i < num_return; ++i) {
1584
 
            if (proto[i] == prop_atoms.wm_delete_window)
 
1585
    if (OBT_PROP_GETA32(self->window, WM_PROTOCOLS, ATOM, &proto, &num_ret)) {
 
1586
        for (i = 0; i < num_ret; ++i) {
 
1587
            if (proto[i] == OBT_PROP_ATOM(WM_DELETE_WINDOW))
1585
1588
                /* this means we can request the window to close */
1586
1589
                self->delete_window = TRUE;
1587
 
            else if (proto[i] == prop_atoms.wm_take_focus)
 
1590
            else if (proto[i] == OBT_PROP_ATOM(WM_TAKE_FOCUS))
1588
1591
                /* if this protocol is requested, then the window will be
1589
1592
                   notified whenever we want it to receive focus */
1590
1593
                self->focus_notify = TRUE;
1591
 
            else if (proto[i] == prop_atoms.net_wm_ping)
 
1594
            else if (proto[i] == OBT_PROP_ATOM(NET_WM_PING))
1592
1595
                /* if this protocol is requested, then the window will allow
1593
1596
                   pings to determine if it is still alive */
1594
1597
                self->ping = TRUE;
1595
1598
#ifdef SYNC
1596
 
            else if (proto[i] == prop_atoms.net_wm_sync_request)
 
1599
            else if (proto[i] == OBT_PROP_ATOM(NET_WM_SYNC_REQUEST))
1597
1600
                /* if this protocol is requested, then resizing the
1598
1601
                   window will be synchronized between the frame and the
1599
1602
                   client */
1609
1612
{
1610
1613
    guint32 i;
1611
1614
 
1612
 
    if (PROP_GET32(self->window, net_wm_sync_request_counter, cardinal, &i)) {
 
1615
    if (OBT_PROP_GET32(self->window, NET_WM_SYNC_REQUEST_COUNTER, CARDINAL,&i))
 
1616
    {
 
1617
        XSyncValue val;
 
1618
 
1613
1619
        self->sync_counter = i;
 
1620
 
 
1621
        /* this must be set when managing a new window according to EWMH */
 
1622
        XSyncIntToValue(&val, 0);
 
1623
        XSyncSetCounter(obt_display, self->sync_counter, val);
1614
1624
    } else
1615
1625
        self->sync_counter = None;
1616
1626
}
1620
1630
{
1621
1631
    XWindowAttributes wa;
1622
1632
 
1623
 
    if (XGetWindowAttributes(ob_display, self->window, &wa))
 
1633
    if (XGetWindowAttributes(obt_display, self->window, &wa))
1624
1634
        client_update_colormap(self, wa.colormap);
1625
1635
}
1626
1636
 
1628
1638
{
1629
1639
    if (colormap == self->colormap) return;
1630
1640
 
1631
 
    ob_debug("Setting client %s colormap: 0x%x\n", self->title, colormap);
 
1641
    ob_debug("Setting client %s colormap: 0x%x", self->title, colormap);
1632
1642
 
1633
1643
    if (client_focused(self)) {
1634
1644
        screen_install_colormap(self, FALSE); /* uninstall old one */
1652
1662
    SIZE_SET(self->max_size, G_MAXINT, G_MAXINT);
1653
1663
 
1654
1664
    /* get the hints from the window */
1655
 
    if (XGetWMNormalHints(ob_display, self->window, &size, &ret)) {
 
1665
    if (XGetWMNormalHints(obt_display, self->window, &size, &ret)) {
1656
1666
        /* normal windows can't request placement! har har
1657
1667
        if (!client_normal(self))
1658
1668
        */
1683
1693
        if (size.flags & PResizeInc && size.width_inc && size.height_inc)
1684
1694
            SIZE_SET(self->size_inc, size.width_inc, size.height_inc);
1685
1695
 
1686
 
        ob_debug("Normal hints: min size (%d %d) max size (%d %d)\n   "
1687
 
                 "size inc (%d %d) base size (%d %d)\n",
 
1696
        ob_debug("Normal hints: min size (%d %d) max size (%d %d)",
1688
1697
                 self->min_size.width, self->min_size.height,
1689
 
                 self->max_size.width, self->max_size.height,
 
1698
                 self->max_size.width, self->max_size.height);
 
1699
        ob_debug("size inc (%d %d) base size (%d %d)",
1690
1700
                 self->size_inc.width, self->size_inc.height,
1691
1701
                 self->base_size.width, self->base_size.height);
1692
1702
    }
1693
1703
    else
1694
 
        ob_debug("Normal hints: not set\n");
 
1704
        ob_debug("Normal hints: not set");
1695
1705
}
1696
1706
 
1697
1707
void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
1770
1780
        break;
1771
1781
    }
1772
1782
 
 
1783
    /* If the client has no decor from its type (which never changes) then
 
1784
       don't allow the user to "undecorate" the window.  Otherwise, allow them
 
1785
       to, even if there are motif hints removing the decor, because those
 
1786
       may change these days (e.g. chromium) */
 
1787
    if (self->decorations == 0)
 
1788
        self->functions &= ~OB_CLIENT_FUNC_UNDECORATE;
 
1789
 
1773
1790
    /* Mwm Hints are applied subtractively to what has already been chosen for
1774
1791
       decor and functionality */
1775
1792
    if (self->mwmhints.flags & OB_MWM_FLAG_DECORATIONS) {
1822
1839
    }
1823
1840
 
1824
1841
    if (self->max_horz && self->max_vert) {
1825
 
        /* you can't resize fully maximized windows */
1826
 
        self->functions &= ~OB_CLIENT_FUNC_RESIZE;
1827
 
        /* kill the handle on fully maxed windows */
 
1842
        /* once upon a time you couldn't resize maximized windows, that is not
 
1843
           the case any more though !
 
1844
 
 
1845
           but do kill the handle on fully maxed windows */
1828
1846
        self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
1829
1847
    }
1830
1848
 
1831
 
    /* If there are no decorations to remove, don't allow the user to try
1832
 
       toggle the state */
1833
 
    if (self->decorations == 0)
1834
 
        self->functions &= ~OB_CLIENT_FUNC_UNDECORATE;
1835
 
 
1836
1849
    /* finally, the user can have requested no decorations, which overrides
1837
1850
       everything (but doesnt give it a border if it doesnt have one) */
1838
1851
    if (self->undecorated)
1854
1867
    client_change_allowed_actions(self);
1855
1868
 
1856
1869
    if (reconfig)
1857
 
        /* force reconfigure to make sure decorations are updated */
1858
 
        client_reconfigure(self, TRUE);
 
1870
        /* reconfigure to make sure decorations are updated */
 
1871
        client_reconfigure(self, FALSE);
1859
1872
}
1860
1873
 
1861
1874
static void client_change_allowed_actions(ObClient *self)
1865
1878
 
1866
1879
    /* desktop windows are kept on all desktops */
1867
1880
    if (self->type != OB_CLIENT_TYPE_DESKTOP)
1868
 
        actions[num++] = prop_atoms.net_wm_action_change_desktop;
 
1881
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_CHANGE_DESKTOP);
1869
1882
 
1870
1883
    if (self->functions & OB_CLIENT_FUNC_SHADE)
1871
 
        actions[num++] = prop_atoms.net_wm_action_shade;
 
1884
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_SHADE);
1872
1885
    if (self->functions & OB_CLIENT_FUNC_CLOSE)
1873
 
        actions[num++] = prop_atoms.net_wm_action_close;
 
1886
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_CLOSE);
1874
1887
    if (self->functions & OB_CLIENT_FUNC_MOVE)
1875
 
        actions[num++] = prop_atoms.net_wm_action_move;
 
1888
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
1876
1889
    if (self->functions & OB_CLIENT_FUNC_ICONIFY)
1877
 
        actions[num++] = prop_atoms.net_wm_action_minimize;
 
1890
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
1878
1891
    if (self->functions & OB_CLIENT_FUNC_RESIZE)
1879
 
        actions[num++] = prop_atoms.net_wm_action_resize;
 
1892
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
1880
1893
    if (self->functions & OB_CLIENT_FUNC_FULLSCREEN)
1881
 
        actions[num++] = prop_atoms.net_wm_action_fullscreen;
 
1894
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_FULLSCREEN);
1882
1895
    if (self->functions & OB_CLIENT_FUNC_MAXIMIZE) {
1883
 
        actions[num++] = prop_atoms.net_wm_action_maximize_horz;
1884
 
        actions[num++] = prop_atoms.net_wm_action_maximize_vert;
 
1896
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_HORZ);
 
1897
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_VERT);
1885
1898
    }
1886
1899
    if (self->functions & OB_CLIENT_FUNC_ABOVE)
1887
 
        actions[num++] = prop_atoms.net_wm_action_above;
 
1900
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_ABOVE);
1888
1901
    if (self->functions & OB_CLIENT_FUNC_BELOW)
1889
 
        actions[num++] = prop_atoms.net_wm_action_below;
 
1902
        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_BELOW);
1890
1903
    if (self->functions & OB_CLIENT_FUNC_UNDECORATE)
1891
 
        actions[num++] = prop_atoms.ob_wm_action_undecorate;
1892
 
 
1893
 
    PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
1894
 
 
1895
 
   /* make sure the window isn't breaking any rules now
1896
 
 
1897
 
   don't check ICONIFY here.  just cuz a window can't iconify doesnt mean
1898
 
   it can't be iconified with its parent
1899
 
   */
 
1904
        actions[num++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
 
1905
 
 
1906
    OBT_PROP_SETA32(self->window, NET_WM_ALLOWED_ACTIONS, ATOM, actions, num);
 
1907
 
 
1908
    /* make sure the window isn't breaking any rules now
 
1909
 
 
1910
       don't check ICONIFY here.  just cuz a window can't iconify doesnt mean
 
1911
       it can't be iconified with its parent
 
1912
    */
1900
1913
 
1901
1914
    if (!(self->functions & OB_CLIENT_FUNC_SHADE) && self->shaded) {
1902
1915
        if (self->frame) client_shade(self, FALSE);
1920
1933
    /* assume a window takes input if it doesn't specify */
1921
1934
    self->can_focus = TRUE;
1922
1935
 
1923
 
    if ((hints = XGetWMHints(ob_display, self->window)) != NULL) {
 
1936
    if ((hints = XGetWMHints(obt_display, self->window)) != NULL) {
1924
1937
        gboolean ur;
1925
1938
 
1926
1939
        if (hints->flags & InputHint)
2011
2024
    g_free(self->original_title);
2012
2025
 
2013
2026
    /* try netwm */
2014
 
    if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) {
 
2027
    if (!OBT_PROP_GETS_UTF8(self->window, NET_WM_NAME, &data)) {
2015
2028
        /* try old x stuff */
2016
 
        if (!(PROP_GETS(self->window, wm_name, locale, &data)
2017
 
              || PROP_GETS(self->window, wm_name, utf8, &data))) {
 
2029
        if (!OBT_PROP_GETS(self->window, WM_NAME, &data)) {
2018
2030
            if (self->transient) {
2019
 
    /*
2020
 
    GNOME alert windows are not given titles:
2021
 
    http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html
2022
 
    */
 
2031
   /*
 
2032
   GNOME alert windows are not given titles:
 
2033
   http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html
 
2034
   */
2023
2035
                data = g_strdup("");
2024
2036
            } else
2025
2037
                data = g_strdup(_("Unnamed Window"));
2042
2054
        g_free(data);
2043
2055
    }
2044
2056
 
2045
 
    PROP_SETS(self->window, net_wm_visible_name, visible);
 
2057
    OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, visible);
2046
2058
    self->title = visible;
2047
2059
 
2048
2060
    if (self->frame)
2053
2065
    g_free(self->icon_title);
2054
2066
 
2055
2067
    /* try netwm */
2056
 
    if (!PROP_GETS(self->window, net_wm_icon_name, utf8, &data))
 
2068
    if (!OBT_PROP_GETS_UTF8(self->window, NET_WM_ICON_NAME, &data))
2057
2069
        /* try old x stuff */
2058
 
        if (!(PROP_GETS(self->window, wm_icon_name, locale, &data) ||
2059
 
              PROP_GETS(self->window, wm_icon_name, utf8, &data)))
 
2070
        if (!OBT_PROP_GETS(self->window, WM_ICON_NAME, &data))
2060
2071
            data = g_strdup(self->title);
2061
2072
 
2062
2073
    if (self->client_machine) {
2074
2085
        g_free(data);
2075
2086
    }
2076
2087
 
2077
 
    PROP_SETS(self->window, net_wm_visible_icon_name, visible);
 
2088
    OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, visible);
2078
2089
    self->icon_title = visible;
2079
2090
}
2080
2091
 
2085
2096
    gboolean got = FALSE;
2086
2097
    StrutPartial strut;
2087
2098
 
2088
 
    if (PROP_GETA32(self->window, net_wm_strut_partial, cardinal,
2089
 
                    &data, &num)) {
 
2099
    if (OBT_PROP_GETA32(self->window, NET_WM_STRUT_PARTIAL, CARDINAL,
 
2100
                        &data, &num))
 
2101
    {
2090
2102
        if (num == 12) {
2091
2103
            got = TRUE;
2092
2104
            STRUT_PARTIAL_SET(strut,
2098
2110
    }
2099
2111
 
2100
2112
    if (!got &&
2101
 
        PROP_GETA32(self->window, net_wm_strut, cardinal, &data, &num)) {
 
2113
        OBT_PROP_GETA32(self->window, NET_WM_STRUT, CARDINAL, &data, &num)) {
2102
2114
        if (num == 4) {
2103
 
            Rect *a;
 
2115
            const Rect *a;
2104
2116
 
2105
2117
            got = TRUE;
2106
2118
 
2113
2125
                              a->x, a->x + a->width - 1,
2114
2126
                              a->y, a->y + a->height - 1,
2115
2127
                              a->x, a->x + a->width - 1);
2116
 
            g_free(a);
2117
2128
        }
2118
2129
        g_free(data);
2119
2130
    }
2137
2148
    guint num;
2138
2149
    guint32 *data;
2139
2150
    guint w, h, i, j;
2140
 
    guint num_seen;  /* number of icons present */
2141
2151
    RrImage *img;
2142
2152
 
2143
2153
    img = NULL;
2147
2157
       icon */
2148
2158
    grab_server(TRUE);
2149
2159
 
2150
 
    if (PROP_GETA32(self->window, net_wm_icon, cardinal, &data, &num)) {
 
2160
    if (OBT_PROP_GETA32(self->window, NET_WM_ICON, CARDINAL, &data, &num)) {
2151
2161
        /* figure out how many valid icons are in here */
2152
2162
        i = 0;
2153
 
        num_seen = 0;
2154
2163
        while (i + 2 < num) { /* +2 is to make sure there is a w and h */
2155
2164
            w = data[i++];
2156
2165
            h = data[i++];
2157
2166
            /* watch for the data being too small for the specified size,
2158
2167
               or for zero sized icons. */
2159
 
            if (i + w*h > num || w == 0 || h == 0) break;
 
2168
            if (i + w*h > num || w == 0 || h == 0) {
 
2169
                i += w*h;
 
2170
                continue;
 
2171
            }
2160
2172
 
2161
2173
            /* convert it to the right bit order for ObRender */
2162
2174
            for (j = 0; j < w*h; ++j)
2166
2178
                    (((data[i+j] >>  8) & 0xff) << RrDefaultGreenOffset) +
2167
2179
                    (((data[i+j] >>  0) & 0xff) << RrDefaultBlueOffset);
2168
2180
 
2169
 
            /* is it in the cache? */
2170
 
            img = RrImageCacheFind(ob_rr_icons, &data[i], w, h);
2171
 
            if (img) RrImageRef(img); /* own it */
 
2181
            /* add it to the image cache as an original */
 
2182
            if (!img)
 
2183
                img = RrImageNewFromData(ob_rr_icons, &data[i], w, h);
 
2184
            else
 
2185
                RrImageAddFromData(img, &data[i], w, h);
2172
2186
 
2173
2187
            i += w*h;
2174
 
            ++num_seen;
2175
 
 
2176
 
            /* don't bother looping anymore if we already found it in the cache
2177
 
               since we'll just use that! */
2178
 
            if (img) break;
2179
 
        }
2180
 
 
2181
 
        /* if it's not in the cache yet, then add it to the cache now.
2182
 
           we have already converted it to the correct bit order above */
2183
 
        if (!img && num_seen > 0) {
2184
 
            img = RrImageNew(ob_rr_icons);
2185
 
            i = 0;
2186
 
            for (j = 0; j < num_seen; ++j) {
2187
 
                w = data[i++];
2188
 
                h = data[i++];
2189
 
                RrImageAddPicture(img, &data[i], w, h);
2190
 
                i += w*h;
2191
 
            }
2192
2188
        }
2193
2189
 
2194
2190
        g_free(data);
2199
2195
    if (!img) {
2200
2196
        XWMHints *hints;
2201
2197
 
2202
 
        if ((hints = XGetWMHints(ob_display, self->window))) {
 
2198
        if ((hints = XGetWMHints(obt_display, self->window))) {
2203
2199
            if (hints->flags & IconPixmapHint) {
2204
2200
                gboolean xicon;
2205
 
                xerror_set_ignore(TRUE);
 
2201
                obt_display_ignore_errors(TRUE);
2206
2202
                xicon = RrPixmapToRGBA(ob_rr_inst,
2207
2203
                                       hints->icon_pixmap,
2208
2204
                                       (hints->flags & IconMaskHint ?
2209
2205
                                        hints->icon_mask : None),
2210
2206
                                       (gint*)&w, (gint*)&h, &data);
2211
 
                xerror_set_ignore(FALSE);
 
2207
                obt_display_ignore_errors(FALSE);
2212
2208
 
2213
2209
                if (xicon) {
2214
2210
                    if (w > 0 && h > 0) {
2215
 
                        /* is this icon in the cache yet? */
2216
 
                        img = RrImageCacheFind(ob_rr_icons, data, w, h);
2217
 
                        if (img) RrImageRef(img); /* own it */
2218
 
 
2219
 
                        /* if not, then add it */
2220
 
                        if (!img) {
2221
 
                            img = RrImageNew(ob_rr_icons);
2222
 
                            RrImageAddPicture(img, data, w, h);
2223
 
                        }
 
2211
                        if (!img)
 
2212
                            img = RrImageNewFromData(ob_rr_icons, data, w, h);
 
2213
                        else
 
2214
                            RrImageAddFromData(img, data, w, h);
2224
2215
                    }
2225
2216
 
2226
2217
                    g_free(data);
2239
2230
    */
2240
2231
    if (!self->icon_set && !self->parents) {
2241
2232
        RrPixel32 *icon = ob_rr_theme->def_win_icon;
2242
 
        gulong *ldata; /* use a long here to satisfy PROP_SETA32 */
 
2233
        gulong *ldata; /* use a long here to satisfy OBT_PROP_SETA32 */
2243
2234
 
2244
2235
        w = ob_rr_theme->def_win_icon_w;
2245
2236
        h = ob_rr_theme->def_win_icon_h;
2251
2242
                (((icon[i] >> RrDefaultRedOffset) & 0xff) << 16) +
2252
2243
                (((icon[i] >> RrDefaultGreenOffset) & 0xff) << 8) +
2253
2244
                (((icon[i] >> RrDefaultBlueOffset) & 0xff) << 0);
2254
 
        PROP_SETA32(self->window, net_wm_icon, cardinal, ldata, w*h+2);
 
2245
        OBT_PROP_SETA32(self->window, NET_WM_ICON, CARDINAL, ldata, w*h+2);
2255
2246
        g_free(ldata);
2256
2247
    } else if (self->frame)
2257
2248
        /* don't draw the icon empty if we're just setting one now anyways,
2268
2259
 
2269
2260
    RECT_SET(self->icon_geometry, 0, 0, 0, 0);
2270
2261
 
2271
 
    if (PROP_GETA32(self->window, net_wm_icon_geometry, cardinal, &data, &num))
 
2262
    if (OBT_PROP_GETA32(self->window, NET_WM_ICON_GEOMETRY, CARDINAL,
 
2263
                        &data, &num))
2272
2264
    {
2273
2265
        if (num == 4)
2274
2266
            /* don't let them set it with an area < 0 */
2285
2277
    gchar *s;
2286
2278
    gchar **ss;
2287
2279
 
2288
 
    if (!PROP_GET32(self->window, wm_client_leader, window, &leader))
 
2280
    if (!OBT_PROP_GET32(self->window, WM_CLIENT_LEADER, WINDOW, &leader))
2289
2281
        leader = None;
2290
2282
 
2291
2283
    /* get the SM_CLIENT_ID */
2292
 
    got = FALSE;
2293
 
    if (leader)
2294
 
        got = PROP_GETS(leader, sm_client_id, locale, &self->sm_client_id);
2295
 
    if (!got)
2296
 
        PROP_GETS(self->window, sm_client_id, locale, &self->sm_client_id);
 
2284
    if (leader && leader != self->window)
 
2285
        OBT_PROP_GETS_XPCS(leader, SM_CLIENT_ID, &self->sm_client_id);
 
2286
    else
 
2287
        OBT_PROP_GETS_XPCS(self->window, SM_CLIENT_ID, &self->sm_client_id);
2297
2288
 
2298
2289
    /* get the WM_CLASS (name and class). make them "" if they are not
2299
2290
       provided */
2300
 
    got = FALSE;
2301
 
    if (leader)
2302
 
        got = PROP_GETSS(leader, wm_class, locale, &ss);
2303
 
    if (!got)
2304
 
        got = PROP_GETSS(self->window, wm_class, locale, &ss);
 
2291
    got = OBT_PROP_GETSS_TYPE(self->window, WM_CLASS, STRING_NO_CC, &ss);
2305
2292
 
2306
2293
    if (got) {
2307
2294
        if (ss[0]) {
2316
2303
    if (self->class == NULL) self->class = g_strdup("");
2317
2304
 
2318
2305
    /* get the WM_WINDOW_ROLE. make it "" if it is not provided */
2319
 
    got = FALSE;
2320
 
    if (leader)
2321
 
        got = PROP_GETS(leader, wm_window_role, locale, &s);
2322
 
    if (!got)
2323
 
        got = PROP_GETS(self->window, wm_window_role, locale, &s);
 
2306
    got = OBT_PROP_GETS_XPCS(self->window, WM_WINDOW_ROLE, &s);
2324
2307
 
2325
2308
    if (got)
2326
2309
        self->role = s;
2331
2314
    got = FALSE;
2332
2315
 
2333
2316
    if (leader)
2334
 
        got = PROP_GETSS(leader, wm_command, locale, &ss);
 
2317
        got = OBT_PROP_GETSS(leader, WM_COMMAND, &ss);
2335
2318
    if (!got)
2336
 
        got = PROP_GETSS(self->window, wm_command, locale, &ss);
 
2319
        got = OBT_PROP_GETSS(self->window, WM_COMMAND, &ss);
2337
2320
 
2338
2321
    if (got) {
2339
2322
        /* merge/mash them all together */
2356
2339
    /* get the WM_CLIENT_MACHINE */
2357
2340
    got = FALSE;
2358
2341
    if (leader)
2359
 
        got = PROP_GETS(leader, wm_client_machine, locale, &s);
 
2342
        got = OBT_PROP_GETS(leader, WM_CLIENT_MACHINE, &s);
2360
2343
    if (!got)
2361
 
        got = PROP_GETS(self->window, wm_client_machine, locale, &s);
 
2344
        got = OBT_PROP_GETS(self->window, WM_CLIENT_MACHINE, &s);
2362
2345
 
2363
2346
    if (got) {
2364
2347
        gchar localhost[128];
2373
2356
 
2374
2357
        /* see if it has the PID set too (the PID requires that the
2375
2358
           WM_CLIENT_MACHINE be set) */
2376
 
        if (PROP_GET32(self->window, net_wm_pid, cardinal, &pid))
 
2359
        if (OBT_PROP_GET32(self->window, NET_WM_PID, CARDINAL, &pid))
2377
2360
            self->pid = pid;
2378
2361
    }
2379
2362
}
2385
2368
{
2386
2369
    const gchar *type;
2387
2370
 
2388
 
    PROP_SETS(self->window, ob_app_role, self->role);
2389
 
    PROP_SETS(self->window, ob_app_name, self->name);
2390
 
    PROP_SETS(self->window, ob_app_class, self->class);
 
2371
    OBT_PROP_SETS(self->window, OB_APP_ROLE, self->role);
 
2372
    OBT_PROP_SETS(self->window, OB_APP_NAME, self->name);
 
2373
    OBT_PROP_SETS(self->window, OB_APP_CLASS, self->class);
 
2374
    OBT_PROP_SETS(self->window, OB_APP_TITLE, self->original_title);
2391
2375
 
2392
2376
    switch (self->type) {
2393
2377
    case OB_CLIENT_TYPE_NORMAL:
2407
2391
    case OB_CLIENT_TYPE_DOCK:
2408
2392
        type = "dock"; break;
2409
2393
    }
2410
 
    PROP_SETS(self->window, ob_app_type, type);
 
2394
    OBT_PROP_SETS(self->window, OB_APP_TYPE, type);
2411
2395
}
2412
2396
 
2413
2397
static void client_change_wm_state(ObClient *self)
2425
2409
        self->wmstate = NormalState;
2426
2410
 
2427
2411
    if (old != self->wmstate) {
2428
 
        PROP_MSG(self->window, kde_wm_change_state,
2429
 
                 self->wmstate, 1, 0, 0);
 
2412
        OBT_PROP_MSG(ob_screen, self->window, KDE_WM_CHANGE_STATE,
 
2413
                     self->wmstate, 1, 0, 0, 0);
2430
2414
 
2431
2415
        state[0] = self->wmstate;
2432
2416
        state[1] = None;
2433
 
        PROP_SETA32(self->window, wm_state, wm_state, state, 2);
 
2417
        OBT_PROP_SETA32(self->window, WM_STATE, WM_STATE, state, 2);
2434
2418
    }
2435
2419
}
2436
2420
 
2441
2425
 
2442
2426
    num = 0;
2443
2427
    if (self->modal)
2444
 
        netstate[num++] = prop_atoms.net_wm_state_modal;
 
2428
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
2445
2429
    if (self->shaded)
2446
 
        netstate[num++] = prop_atoms.net_wm_state_shaded;
 
2430
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SHADED);
2447
2431
    if (self->iconic)
2448
 
        netstate[num++] = prop_atoms.net_wm_state_hidden;
 
2432
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_HIDDEN);
2449
2433
    if (self->skip_taskbar)
2450
 
        netstate[num++] = prop_atoms.net_wm_state_skip_taskbar;
 
2434
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR);
2451
2435
    if (self->skip_pager)
2452
 
        netstate[num++] = prop_atoms.net_wm_state_skip_pager;
 
2436
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER);
2453
2437
    if (self->fullscreen)
2454
 
        netstate[num++] = prop_atoms.net_wm_state_fullscreen;
 
2438
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN);
2455
2439
    if (self->max_vert)
2456
 
        netstate[num++] = prop_atoms.net_wm_state_maximized_vert;
 
2440
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT);
2457
2441
    if (self->max_horz)
2458
 
        netstate[num++] = prop_atoms.net_wm_state_maximized_horz;
 
2442
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ);
2459
2443
    if (self->above)
2460
 
        netstate[num++] = prop_atoms.net_wm_state_above;
 
2444
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_ABOVE);
2461
2445
    if (self->below)
2462
 
        netstate[num++] = prop_atoms.net_wm_state_below;
 
2446
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_BELOW);
2463
2447
    if (self->demands_attention)
2464
 
        netstate[num++] = prop_atoms.net_wm_state_demands_attention;
 
2448
        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
2465
2449
    if (self->undecorated)
2466
 
        netstate[num++] = prop_atoms.ob_wm_state_undecorated;
2467
 
    PROP_SETA32(self->window, net_wm_state, atom, netstate, num);
 
2450
        netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
 
2451
    OBT_PROP_SETA32(self->window, NET_WM_STATE, ATOM, netstate, num);
2468
2452
 
2469
2453
    if (self->frame)
2470
2454
        frame_adjust_state(self->frame);
2524
2508
    return self->parents != NULL;
2525
2509
}
2526
2510
 
 
2511
gboolean client_has_children(ObClient *self)
 
2512
{
 
2513
    return self->transients != NULL;
 
2514
}
 
2515
 
 
2516
gboolean client_is_oldfullscreen(const ObClient *self,
 
2517
                                 const Rect *area)
 
2518
{
 
2519
    const Rect *monitor, *allmonitors;
 
2520
 
 
2521
    /* No decorations and fills the monitor = oldskool fullscreen.
 
2522
       But not for maximized windows.
 
2523
    */
 
2524
 
 
2525
    if (self->decorations || self->max_horz || self->max_vert) return FALSE;
 
2526
 
 
2527
    monitor = screen_physical_area_monitor(screen_find_monitor(area));
 
2528
    allmonitors = screen_physical_area_all_monitors();
 
2529
 
 
2530
    return (RECT_EQUAL(*area, *monitor) ||
 
2531
            RECT_EQUAL(*area, *allmonitors));
 
2532
}
 
2533
 
2527
2534
static ObStackingLayer calc_layer(ObClient *self)
2528
2535
{
2529
2536
    ObStackingLayer l;
2530
 
    Rect *monitor;
2531
 
 
2532
 
    monitor = screen_physical_area_monitor(client_monitor(self));
2533
2537
 
2534
2538
    if (self->type == OB_CLIENT_TYPE_DESKTOP)
2535
2539
        l = OB_STACKING_LAYER_DESKTOP;
2538
2542
        else l = OB_STACKING_LAYER_ABOVE;
2539
2543
    }
2540
2544
    else if ((self->fullscreen ||
2541
 
              /* No decorations and fills the monitor = oldskool fullscreen.
2542
 
                 But not for maximized windows.
2543
 
              */
2544
 
              (self->decorations == 0 &&
2545
 
               !(self->max_horz && self->max_vert) &&
2546
 
               RECT_EQUAL(self->area, *monitor))) &&
 
2545
              client_is_oldfullscreen(self, &self->area)) &&
2547
2546
             /* you are fullscreen while you or your children are focused.. */
2548
2547
             (client_focused(self) || client_search_focus_tree(self) ||
2549
2548
              /* you can be fullscreen if you're on another desktop */
2558
2557
    else if (self->below) l = OB_STACKING_LAYER_BELOW;
2559
2558
    else l = OB_STACKING_LAYER_NORMAL;
2560
2559
 
2561
 
    g_free(monitor);
2562
 
 
2563
2560
    return l;
2564
2561
}
2565
2562
 
2758
2755
       pre-max/pre-fullscreen values
2759
2756
    */
2760
2757
    client_try_configure(self, &x, &y, &w, &h, &l, &l, FALSE);
2761
 
    ob_debug("placed window 0x%x at %d, %d with size %d x %d\n",
 
2758
    ob_debug("placed window 0x%x at %d, %d with size %d x %d",
2762
2759
             self->window, x, y, w, h);
2763
2760
    /* save the area, and make it where it should be for the premax stuff */
2764
2761
    oldarea = self->area;
2768
2765
 
2769
2766
    if (iconic)
2770
2767
        client_iconify(self, TRUE, FALSE, TRUE);
2771
 
    if (fullscreen)
2772
 
        client_fullscreen(self, TRUE);
2773
2768
    if (undecorated)
2774
2769
        client_set_undecorated(self, TRUE);
2775
2770
    if (shaded)
2784
2779
    else if (max_horz)
2785
2780
        client_maximize(self, TRUE, 1);
2786
2781
 
 
2782
    /* fullscreen removes the ability to apply other states */
 
2783
    if (fullscreen)
 
2784
        client_fullscreen(self, TRUE);
 
2785
 
2787
2786
    /* if the window hasn't been configured yet, then do so now, in fact the
2788
2787
       x,y,w,h may _not_ be the same as the area rect, which can end up
2789
2788
       meaning that the client isn't properly moved/resized by the fullscreen
2797
2796
    self->area = oldarea;
2798
2797
    client_configure(self, x, y, w, h, FALSE, TRUE, FALSE);
2799
2798
 
2800
 
    /* set the desktop hint, to make sure that it always exists */
2801
 
    PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
2802
 
 
2803
2799
    /* nothing to do for the other states:
2804
2800
       skip_taskbar
2805
2801
       skip_pager
2879
2875
       the updated frame dimensions. */
2880
2876
    frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
2881
2877
 
 
2878
    /* cap any X windows at the size of an unsigned short */
 
2879
    *w = MIN(*w,
 
2880
             G_MAXUSHORT - self->frame->size.left - self->frame->size.right);
 
2881
    *h = MIN(*h,
 
2882
             G_MAXUSHORT - self->frame->size.top - self->frame->size.bottom);
 
2883
 
 
2884
 
2882
2885
    /* gets the frame's position */
2883
2886
    frame_client_gravity(self->frame, x, y);
2884
2887
 
2886
2889
 
2887
2890
    /* set the size and position if fullscreen */
2888
2891
    if (self->fullscreen) {
2889
 
        Rect *a;
 
2892
        const Rect *a;
2890
2893
        guint i;
2891
2894
 
2892
2895
        i = screen_find_monitor(&desired);
2899
2902
 
2900
2903
        user = FALSE; /* ignore if the client can't be moved/resized when it
2901
2904
                         is fullscreening */
2902
 
 
2903
 
        g_free(a);
2904
2905
    } else if (self->max_horz || self->max_vert) {
2905
2906
        Rect *a;
2906
2907
        guint i;
2923
2924
        user = FALSE; /* ignore if the client can't be moved/resized when it
2924
2925
                         is maximizing */
2925
2926
 
2926
 
        g_free(a);
 
2927
        g_slice_free(Rect, a);
2927
2928
    }
2928
2929
 
2929
2930
    /* gets the client's position */
2934
2935
       through this code */
2935
2936
    {
2936
2937
        gint basew, baseh, minw, minh;
2937
 
        gint incw, inch;
 
2938
        gint incw, inch, maxw, maxh;
2938
2939
        gfloat minratio, maxratio;
2939
2940
 
2940
 
        incw = self->fullscreen || self->max_horz ? 1 : self->size_inc.width;
2941
 
        inch = self->fullscreen || self->max_vert ? 1 : self->size_inc.height;
 
2941
        incw = self->size_inc.width;
 
2942
        inch = self->size_inc.height;
2942
2943
        minratio = self->fullscreen || (self->max_horz && self->max_vert) ?
2943
2944
            0 : self->min_ratio;
2944
2945
        maxratio = self->fullscreen || (self->max_horz && self->max_vert) ?
2974
2975
        *w -= basew;
2975
2976
        *h -= baseh;
2976
2977
 
 
2978
        /* the sizes to used for maximized */
 
2979
        maxw = *w;
 
2980
        maxh = *h;
 
2981
 
2977
2982
        /* keep to the increments */
2978
2983
        *w /= incw;
2979
2984
        *h /= inch;
2989
2994
        *w *= incw;
2990
2995
        *h *= inch;
2991
2996
 
 
2997
        /* if maximized/fs then don't use the size increments */
 
2998
        if (self->fullscreen || self->max_horz) *w = maxw;
 
2999
        if (self->fullscreen || self->max_vert) *h = maxh;
 
3000
 
2992
3001
        *w += basew;
2993
3002
        *h += baseh;
2994
3003
 
3041
3050
void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
3042
3051
                      gboolean user, gboolean final, gboolean force_reply)
3043
3052
{
3044
 
    Rect oldframe;
3045
 
    gint oldw, oldh;
 
3053
    Rect oldframe, oldclient;
3046
3054
    gboolean send_resize_client;
3047
3055
    gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE;
3048
3056
    gboolean fmoved, fresized;
3062
3070
    moved = (x != self->area.x || y != self->area.y);
3063
3071
    resized = (w != self->area.width || h != self->area.height);
3064
3072
 
3065
 
    oldw = self->area.width;
3066
 
    oldh = self->area.height;
3067
3073
    oldframe = self->frame->area;
 
3074
    oldclient = self->area;
3068
3075
    RECT_SET(self->area, x, y, w, h);
3069
3076
 
3070
3077
    /* for app-requested resizes, always resize if 'resized' is true.
3075
3082
                                    (resized && config_resize_redraw))));
3076
3083
 
3077
3084
    /* if the client is enlarging, then resize the client before the frame */
3078
 
    if (send_resize_client && (w > oldw || h > oldh)) {
3079
 
        XMoveResizeWindow(ob_display, self->window,
 
3085
    if (send_resize_client && (w > oldclient.width || h > oldclient.height)) {
 
3086
        XMoveResizeWindow(obt_display, self->window,
3080
3087
                          self->frame->size.left, self->frame->size.top,
3081
 
                          MAX(w, oldw), MAX(h, oldh));
 
3088
                          MAX(w, oldclient.width), MAX(h, oldclient.height));
3082
3089
        frame_adjust_client_area(self->frame);
3083
3090
    }
3084
3091
 
3128
3135
       When user = FALSE, then the request is coming from the application
3129
3136
       itself, and we are more strict about when to send a synthetic
3130
3137
       ConfigureNotify.  We strictly follow the rules of the ICCCM sec 4.1.5
3131
 
       in this case (if force_reply is true)
 
3138
       in this case (or send one if force_reply is true)
3132
3139
 
3133
3140
       When user = TRUE, then the request is coming from "us", like when we
3134
3141
       maximize a window or something.  In this case we are more lenient.  We
3135
3142
       used to follow the same rules as above, but _Java_ Swing can't handle
3136
3143
       this. So just to appease Swing, when user = TRUE, we always send
3137
3144
       a synthetic ConfigureNotify to give the window its root coordinates.
 
3145
       Lastly, if force_reply is TRUE, we always send a
 
3146
       ConfigureNotify, which is needed during a resize with XSYNCronization.
3138
3147
    */
3139
3148
    if ((!user && !resized && (rootmoved || force_reply)) ||
3140
 
        (user && final && rootmoved))
 
3149
        (user && ((!resized && force_reply) || (final && rootmoved))))
3141
3150
    {
3142
3151
        XEvent event;
3143
3152
 
3144
3153
        event.type = ConfigureNotify;
3145
 
        event.xconfigure.display = ob_display;
 
3154
        event.xconfigure.display = obt_display;
3146
3155
        event.xconfigure.event = self->window;
3147
3156
        event.xconfigure.window = self->window;
3148
3157
 
3149
 
        ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d\n",
 
3158
        ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d",
3150
3159
                 self->title, self->root_pos.x, self->root_pos.y, w, h);
3151
3160
 
3152
3161
        /* root window real coords */
3166
3175
       both of these resize sections may run, because the top one only resizes
3167
3176
       in the direction that is growing
3168
3177
     */
3169
 
    if (send_resize_client && (w <= oldw || h <= oldh)) {
 
3178
    if (send_resize_client && (w <= oldclient.width || h <= oldclient.height))
 
3179
    {
3170
3180
        frame_adjust_client_area(self->frame);
3171
 
        XMoveResizeWindow(ob_display, self->window,
 
3181
        XMoveResizeWindow(obt_display, self->window,
3172
3182
                          self->frame->size.left, self->frame->size.top, w, h);
3173
3183
    }
3174
3184
 
3175
 
    XFlush(ob_display);
 
3185
    XFlush(obt_display);
3176
3186
 
3177
3187
    /* if it moved between monitors, then this can affect the stacking
3178
 
       layer of this window or others - for fullscreen windows */
 
3188
       layer of this window or others - for fullscreen windows.
 
3189
       also if it changed to/from oldschool fullscreen then its layer may
 
3190
       change
 
3191
 
 
3192
       watch out tho, don't try change stacking stuff if the window is no
 
3193
       longer being managed !
 
3194
    */
3179
3195
    if (self->managed &&
3180
 
        screen_find_monitor(&self->frame->area) !=
3181
 
        screen_find_monitor(&oldframe))
 
3196
        (screen_find_monitor(&self->frame->area) !=
 
3197
         screen_find_monitor(&oldframe) ||
 
3198
         (final && (client_is_oldfullscreen(self, &oldclient) !=
 
3199
                    client_is_oldfullscreen(self, &self->area)))))
3182
3200
    {
3183
3201
        client_calc_layer(self);
3184
3202
    }
3238
3256
        RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
3239
3257
    }
3240
3258
 
3241
 
    ob_debug("Window %s going fullscreen (%d)\n",
 
3259
    ob_debug("Window %s going fullscreen (%d)",
3242
3260
             self->title, self->fullscreen);
3243
3261
 
 
3262
    if (fs) {
 
3263
        /* make sure the window is on some monitor */
 
3264
        client_find_onscreen(self, &x, &y, w, h, FALSE);
 
3265
    }
 
3266
 
3244
3267
    client_setup_decor_and_functions(self, FALSE);
3245
3268
    client_move_resize(self, x, y, w, h);
3246
3269
 
3263
3286
    gboolean changed = FALSE;
3264
3287
 
3265
3288
    if (self->iconic != iconic) {
3266
 
        ob_debug("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"),
 
3289
        ob_debug("%sconifying window: 0x%lx", (iconic ? "I" : "Uni"),
3267
3290
                 self->window);
3268
3291
 
3269
3292
        if (iconic) {
3383
3406
    if (dir == 0 || dir == 2) /* vert */
3384
3407
        self->max_vert = max;
3385
3408
 
 
3409
    if (max) {
 
3410
        /* make sure the window is on some monitor */
 
3411
        client_find_onscreen(self, &x, &y, w, h, FALSE);
 
3412
    }
 
3413
 
3386
3414
    client_change_state(self); /* change the state hints on the client */
3387
3415
 
3388
3416
    client_setup_decor_and_functions(self, FALSE);
3439
3467
    if (!self->delete_window)
3440
3468
        /* don't use client_kill(), we should only kill based on PID in
3441
3469
           response to a lack of PING replies */
3442
 
        XKillClient(ob_display, self->window);
 
3470
        XKillClient(obt_display, self->window);
3443
3471
    else {
3444
3472
        /* request the client to close with WM_DELETE_WINDOW */
3445
 
        PROP_MSG_TO(self->window, self->window, wm_protocols,
3446
 
                    prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
3447
 
                    NoEventMask);
 
3473
        OBT_PROP_MSG_TO(self->window, self->window, WM_PROTOCOLS,
 
3474
                        OBT_PROP_ATOM(WM_DELETE_WINDOW), event_time(),
 
3475
                        0, 0, 0, NoEventMask);
3448
3476
 
3449
3477
        /* we're trying to close the window, so see if it is responding. if it
3450
3478
           is not, then we will let them kill the window */
3552
3580
            client_update_title(self);
3553
3581
        }
3554
3582
        else {
3555
 
            ob_debug("killing window 0x%x with pid %lu, with SIGKILL\n",
 
3583
            ob_debug("killing window 0x%x with pid %lu, with SIGKILL",
3556
3584
                     self->window, self->pid);
3557
3585
            kill(self->pid, SIGKILL); /* kill -9 */
3558
3586
        }
3559
3587
    }
3560
3588
    else {
3561
3589
        /* running on a remote host */
3562
 
        XKillClient(ob_display, self->window);
 
3590
        XKillClient(obt_display, self->window);
3563
3591
    }
3564
3592
}
3565
3593
 
3599
3627
 
3600
3628
    if (target != self->desktop && self->type != OB_CLIENT_TYPE_DESKTOP) {
3601
3629
 
3602
 
        ob_debug("Setting desktop %u\n", target+1);
 
3630
        ob_debug("Setting desktop %u", target+1);
3603
3631
 
3604
3632
        g_assert(target < screen_num_desktops || target == DESKTOP_ALL);
3605
3633
 
3606
3634
        old = self->desktop;
3607
3635
        self->desktop = target;
3608
 
        PROP_SET32(self->window, net_wm_desktop, cardinal, target);
 
3636
        OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, target);
3609
3637
        /* the frame can display the current desktop state */
3610
3638
        frame_adjust_state(self->frame);
3611
3639
        /* 'move' the window to the new desktop */
3661
3689
    return NULL;
3662
3690
}
3663
3691
 
3664
 
static gboolean client_validate_unmap(ObClient *self, int n)
 
3692
struct ObClientFindDestroyUnmap {
 
3693
    Window window;
 
3694
    gint ignore_unmaps;
 
3695
};
 
3696
 
 
3697
static gboolean find_destroy_unmap(XEvent *e, gpointer data)
3665
3698
{
3666
 
    XEvent e;
3667
 
    gboolean ret = TRUE;
3668
 
 
3669
 
    if (XCheckTypedWindowEvent(ob_display, self->window, UnmapNotify, &e)) {
3670
 
        if (n < self->ignore_unmaps) // ignore this one, but look for more
3671
 
            ret = client_validate_unmap(self, n+1);
3672
 
        else
3673
 
            ret = FALSE; // the window is going to become unmanaged
3674
 
 
3675
 
        /* put them back on the event stack so they end up in the same order */
3676
 
        XPutBackEvent(ob_display, &e);
3677
 
    }
3678
 
 
3679
 
    return ret;
 
3699
    struct ObClientFindDestroyUnmap *find = data;
 
3700
    if (e->type == DestroyNotify)
 
3701
        return e->xdestroywindow.window == find->window;
 
3702
    if (e->type == UnmapNotify && e->xunmap.window == find->window)
 
3703
        /* ignore the first $find->ignore_unmaps$ many unmap events */
 
3704
        return --find->ignore_unmaps < 0;
 
3705
    return FALSE;
3680
3706
}
3681
3707
 
3682
3708
gboolean client_validate(ObClient *self)
3683
3709
{
3684
 
    XEvent e;
3685
 
 
3686
 
    XSync(ob_display, FALSE); /* get all events on the server */
3687
 
 
3688
 
    if (XCheckTypedWindowEvent(ob_display, self->window, DestroyNotify, &e)) {
3689
 
        XPutBackEvent(ob_display, &e);
3690
 
        return FALSE;
3691
 
    }
3692
 
 
3693
 
    if (!client_validate_unmap(self, 0))
 
3710
    struct ObClientFindDestroyUnmap find;
 
3711
 
 
3712
    XSync(obt_display, FALSE); /* get all events on the server */
 
3713
 
 
3714
    find.window = self->window;
 
3715
    find.ignore_unmaps = self->ignore_unmaps;
 
3716
    if (xqueue_exists_local(find_destroy_unmap, &find))
3694
3717
        return FALSE;
3695
3718
 
3696
3719
    return TRUE;
3723
3746
    gboolean above = self->above;
3724
3747
    gboolean below = self->below;
3725
3748
    gint i;
 
3749
    gboolean value;
3726
3750
 
3727
 
    if (!(action == prop_atoms.net_wm_state_add ||
3728
 
          action == prop_atoms.net_wm_state_remove ||
3729
 
          action == prop_atoms.net_wm_state_toggle))
 
3751
    if (!(action == OBT_PROP_ATOM(NET_WM_STATE_ADD) ||
 
3752
          action == OBT_PROP_ATOM(NET_WM_STATE_REMOVE) ||
 
3753
          action == OBT_PROP_ATOM(NET_WM_STATE_TOGGLE)))
3730
3754
        /* an invalid action was passed to the client message, ignore it */
3731
3755
        return;
3732
3756
 
3736
3760
        if (!state) continue;
3737
3761
 
3738
3762
        /* if toggling, then pick whether we're adding or removing */
3739
 
        if (action == prop_atoms.net_wm_state_toggle) {
3740
 
            if (state == prop_atoms.net_wm_state_modal)
3741
 
                action = modal ? prop_atoms.net_wm_state_remove :
3742
 
                    prop_atoms.net_wm_state_add;
3743
 
            else if (state == prop_atoms.net_wm_state_maximized_vert)
3744
 
                action = self->max_vert ? prop_atoms.net_wm_state_remove :
3745
 
                    prop_atoms.net_wm_state_add;
3746
 
            else if (state == prop_atoms.net_wm_state_maximized_horz)
3747
 
                action = self->max_horz ? prop_atoms.net_wm_state_remove :
3748
 
                    prop_atoms.net_wm_state_add;
3749
 
            else if (state == prop_atoms.net_wm_state_shaded)
3750
 
                action = shaded ? prop_atoms.net_wm_state_remove :
3751
 
                    prop_atoms.net_wm_state_add;
3752
 
            else if (state == prop_atoms.net_wm_state_skip_taskbar)
3753
 
                action = self->skip_taskbar ?
3754
 
                    prop_atoms.net_wm_state_remove :
3755
 
                    prop_atoms.net_wm_state_add;
3756
 
            else if (state == prop_atoms.net_wm_state_skip_pager)
3757
 
                action = self->skip_pager ?
3758
 
                    prop_atoms.net_wm_state_remove :
3759
 
                    prop_atoms.net_wm_state_add;
3760
 
            else if (state == prop_atoms.net_wm_state_hidden)
3761
 
                action = self->iconic ?
3762
 
                    prop_atoms.net_wm_state_remove :
3763
 
                    prop_atoms.net_wm_state_add;
3764
 
            else if (state == prop_atoms.net_wm_state_fullscreen)
3765
 
                action = fullscreen ?
3766
 
                    prop_atoms.net_wm_state_remove :
3767
 
                    prop_atoms.net_wm_state_add;
3768
 
            else if (state == prop_atoms.net_wm_state_above)
3769
 
                action = self->above ? prop_atoms.net_wm_state_remove :
3770
 
                    prop_atoms.net_wm_state_add;
3771
 
            else if (state == prop_atoms.net_wm_state_below)
3772
 
                action = self->below ? prop_atoms.net_wm_state_remove :
3773
 
                    prop_atoms.net_wm_state_add;
3774
 
            else if (state == prop_atoms.net_wm_state_demands_attention)
3775
 
                action = self->demands_attention ?
3776
 
                    prop_atoms.net_wm_state_remove :
3777
 
                    prop_atoms.net_wm_state_add;
3778
 
            else if (state == prop_atoms.ob_wm_state_undecorated)
3779
 
                action = undecorated ? prop_atoms.net_wm_state_remove :
3780
 
                    prop_atoms.net_wm_state_add;
 
3763
        if (action == OBT_PROP_ATOM(NET_WM_STATE_TOGGLE)) {
 
3764
            if (state == OBT_PROP_ATOM(NET_WM_STATE_MODAL))
 
3765
                value = modal;
 
3766
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT))
 
3767
                value = self->max_vert;
 
3768
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ))
 
3769
                value = self->max_horz;
 
3770
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_SHADED))
 
3771
                value = shaded;
 
3772
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR))
 
3773
                value = self->skip_taskbar;
 
3774
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER))
 
3775
                value = self->skip_pager;
 
3776
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_HIDDEN))
 
3777
                value = self->iconic;
 
3778
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN))
 
3779
                value = fullscreen;
 
3780
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_ABOVE))
 
3781
                value = self->above;
 
3782
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_BELOW))
 
3783
                value = self->below;
 
3784
            else if (state == OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION))
 
3785
                value = self->demands_attention;
 
3786
            else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
 
3787
                value = undecorated;
 
3788
            else
 
3789
                g_assert_not_reached();
 
3790
            action = value ? OBT_PROP_ATOM(NET_WM_STATE_REMOVE) :
 
3791
                             OBT_PROP_ATOM(NET_WM_STATE_ADD);
3781
3792
        }
3782
3793
 
3783
 
        if (action == prop_atoms.net_wm_state_add) {
3784
 
            if (state == prop_atoms.net_wm_state_modal) {
3785
 
                modal = TRUE;
3786
 
            } else if (state == prop_atoms.net_wm_state_maximized_vert) {
3787
 
                max_vert = TRUE;
3788
 
            } else if (state == prop_atoms.net_wm_state_maximized_horz) {
3789
 
                max_horz = TRUE;
3790
 
            } else if (state == prop_atoms.net_wm_state_shaded) {
3791
 
                shaded = TRUE;
3792
 
            } else if (state == prop_atoms.net_wm_state_skip_taskbar) {
3793
 
                self->skip_taskbar = TRUE;
3794
 
            } else if (state == prop_atoms.net_wm_state_skip_pager) {
3795
 
                self->skip_pager = TRUE;
3796
 
            } else if (state == prop_atoms.net_wm_state_hidden) {
3797
 
                iconic = TRUE;
3798
 
            } else if (state == prop_atoms.net_wm_state_fullscreen) {
3799
 
                fullscreen = TRUE;
3800
 
            } else if (state == prop_atoms.net_wm_state_above) {
3801
 
                above = TRUE;
3802
 
                below = FALSE;
3803
 
            } else if (state == prop_atoms.net_wm_state_below) {
3804
 
                above = FALSE;
3805
 
                below = TRUE;
3806
 
            } else if (state == prop_atoms.net_wm_state_demands_attention) {
3807
 
                demands_attention = TRUE;
3808
 
            } else if (state == prop_atoms.ob_wm_state_undecorated) {
3809
 
                undecorated = TRUE;
3810
 
            }
3811
 
 
3812
 
        } else { /* action == prop_atoms.net_wm_state_remove */
3813
 
            if (state == prop_atoms.net_wm_state_modal) {
3814
 
                modal = FALSE;
3815
 
            } else if (state == prop_atoms.net_wm_state_maximized_vert) {
3816
 
                max_vert = FALSE;
3817
 
            } else if (state == prop_atoms.net_wm_state_maximized_horz) {
3818
 
                max_horz = FALSE;
3819
 
            } else if (state == prop_atoms.net_wm_state_shaded) {
3820
 
                shaded = FALSE;
3821
 
            } else if (state == prop_atoms.net_wm_state_skip_taskbar) {
3822
 
                self->skip_taskbar = FALSE;
3823
 
            } else if (state == prop_atoms.net_wm_state_skip_pager) {
3824
 
                self->skip_pager = FALSE;
3825
 
            } else if (state == prop_atoms.net_wm_state_hidden) {
3826
 
                iconic = FALSE;
3827
 
            } else if (state == prop_atoms.net_wm_state_fullscreen) {
3828
 
                fullscreen = FALSE;
3829
 
            } else if (state == prop_atoms.net_wm_state_above) {
3830
 
                above = FALSE;
3831
 
            } else if (state == prop_atoms.net_wm_state_below) {
3832
 
                below = FALSE;
3833
 
            } else if (state == prop_atoms.net_wm_state_demands_attention) {
3834
 
                demands_attention = FALSE;
3835
 
            } else if (state == prop_atoms.ob_wm_state_undecorated) {
3836
 
                undecorated = FALSE;
3837
 
            }
 
3794
        value = action == OBT_PROP_ATOM(NET_WM_STATE_ADD);
 
3795
        if (state == OBT_PROP_ATOM(NET_WM_STATE_MODAL)) {
 
3796
            modal = value;
 
3797
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT)) {
 
3798
            max_vert = value;
 
3799
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ)) {
 
3800
            max_horz = value;
 
3801
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_SHADED)) {
 
3802
            shaded = value;
 
3803
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR)) {
 
3804
            self->skip_taskbar = value;
 
3805
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER)) {
 
3806
            self->skip_pager = value;
 
3807
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_HIDDEN)) {
 
3808
            iconic = value;
 
3809
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN)) {
 
3810
            fullscreen = value;
 
3811
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_ABOVE)) {
 
3812
            above = value;
 
3813
            /* only unset below when setting above, otherwise you can't get to
 
3814
               the normal layer */
 
3815
            if (value)
 
3816
                below = FALSE;
 
3817
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_BELOW)) {
 
3818
            /* and vice versa */
 
3819
            if (value)
 
3820
                above = FALSE;
 
3821
            below = value;
 
3822
        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION)){
 
3823
            demands_attention = value;
 
3824
        } else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED)) {
 
3825
            undecorated = value;
3838
3826
        }
3839
3827
    }
3840
3828
 
3917
3905
 
3918
3906
gboolean client_focus(ObClient *self)
3919
3907
{
 
3908
    if (!client_validate(self)) return FALSE;
 
3909
 
3920
3910
    /* we might not focus this window, so if we have modal children which would
3921
3911
       be focused instead, bring them to this desktop */
3922
3912
    client_bring_modal_windows(self);
3926
3916
 
3927
3917
    if (!client_can_focus(self)) {
3928
3918
        ob_debug_type(OB_DEBUG_FOCUS,
3929
 
                      "Client %s can't be focused\n", self->title);
 
3919
                      "Client %s can't be focused", self->title);
3930
3920
        return FALSE;
3931
3921
    }
3932
3922
 
3933
3923
    ob_debug_type(OB_DEBUG_FOCUS,
3934
 
                  "Focusing client \"%s\" (0x%x) at time %u\n",
3935
 
                  self->title, self->window, event_curtime);
 
3924
                  "Focusing client \"%s\" (0x%x) at time %u",
 
3925
                  self->title, self->window, event_time());
3936
3926
 
3937
3927
    /* if using focus_delay, stop the timer now so that focus doesn't
3938
3928
       go moving on us */
3939
3929
    event_halt_focus_delay();
3940
3930
 
3941
 
    xerror_set_ignore(TRUE);
3942
 
    xerror_occured = FALSE;
 
3931
    obt_display_ignore_errors(TRUE);
3943
3932
 
3944
3933
    if (self->can_focus) {
3945
3934
        /* This can cause a BadMatch error with CurrentTime, or if an app
3946
3935
           passed in a bad time for _NET_WM_ACTIVE_WINDOW. */
3947
 
        XSetInputFocus(ob_display, self->window, RevertToPointerRoot,
3948
 
                       event_curtime);
 
3936
        XSetInputFocus(obt_display, self->window, RevertToPointerRoot,
 
3937
                       event_time());
3949
3938
    }
3950
3939
 
3951
3940
    if (self->focus_notify) {
3952
3941
        XEvent ce;
3953
3942
        ce.xclient.type = ClientMessage;
3954
 
        ce.xclient.message_type = prop_atoms.wm_protocols;
3955
 
        ce.xclient.display = ob_display;
 
3943
        ce.xclient.message_type = OBT_PROP_ATOM(WM_PROTOCOLS);
 
3944
        ce.xclient.display = obt_display;
3956
3945
        ce.xclient.window = self->window;
3957
3946
        ce.xclient.format = 32;
3958
 
        ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
3959
 
        ce.xclient.data.l[1] = event_curtime;
 
3947
        ce.xclient.data.l[0] = OBT_PROP_ATOM(WM_TAKE_FOCUS);
 
3948
        ce.xclient.data.l[1] = event_time();
3960
3949
        ce.xclient.data.l[2] = 0l;
3961
3950
        ce.xclient.data.l[3] = 0l;
3962
3951
        ce.xclient.data.l[4] = 0l;
3963
 
        XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
 
3952
        XSendEvent(obt_display, self->window, FALSE, NoEventMask, &ce);
3964
3953
    }
3965
3954
 
3966
 
    xerror_set_ignore(FALSE);
 
3955
    obt_display_ignore_errors(FALSE);
3967
3956
 
3968
 
    ob_debug_type(OB_DEBUG_FOCUS, "Error focusing? %d\n", xerror_occured);
3969
 
    return !xerror_occured;
 
3957
    ob_debug_type(OB_DEBUG_FOCUS, "Error focusing? %d",
 
3958
                  obt_display_error_occured);
 
3959
    return !obt_display_error_occured;
3970
3960
}
3971
3961
 
3972
3962
static void client_present(ObClient *self, gboolean here, gboolean raise,
4000
3990
                     gboolean here, gboolean raise,
4001
3991
                     gboolean unshade, gboolean user)
4002
3992
{
4003
 
    if ((user && (desktop ||
4004
 
                  self->desktop == DESKTOP_ALL ||
4005
 
                  self->desktop == screen_desktop)) ||
4006
 
        client_can_steal_focus(self, event_curtime, CurrentTime))
4007
 
    {
 
3993
    self = client_focus_target(self);
 
3994
 
 
3995
    if (client_can_steal_focus(self, desktop, user, event_time(), CurrentTime))
4008
3996
        client_present(self, here, raise, unshade);
4009
 
    }
4010
3997
    else
4011
3998
        client_hilite(self, TRUE);
4012
3999
}
4282
4269
            g_assert_not_reached();
4283
4270
    }
4284
4271
 
4285
 
    ob_debug("my head %d size %d\n", my_head, my_size);
4286
 
    ob_debug("head %d tail %d dest %d\n", head, tail, *dest);
 
4272
    ob_debug("my head %d size %d", my_head, my_size);
 
4273
    ob_debug("head %d tail %d dest %d", head, tail, *dest);
4287
4274
    if (!skip_head) {
4288
 
        ob_debug("using near edge %d\n", head);
 
4275
        ob_debug("using near edge %d", head);
4289
4276
        *dest = head;
4290
4277
        *near_edge = TRUE;
4291
4278
    }
4292
4279
    else if (!skip_tail) {
4293
 
        ob_debug("using far edge %d\n", tail);
 
4280
        ob_debug("using far edge %d", tail);
4294
4281
        *dest = tail;
4295
4282
        *near_edge = FALSE;
4296
4283
    }
4335
4322
        Rect *area = screen_area(self->desktop, i, NULL);
4336
4323
        detect_edge(*area, dir, my_head, my_size, my_edge_start,
4337
4324
                    my_edge_size, dest, near_edge);
4338
 
        g_free(area);
 
4325
        g_slice_free(Rect, area);
4339
4326
    }
4340
4327
 
4341
4328
    /* search for edges of clients */
4351
4338
            cur->desktop != screen_desktop)
4352
4339
            continue;
4353
4340
 
4354
 
        ob_debug("trying window %s\n", cur->title);
 
4341
        ob_debug("trying window %s", cur->title);
4355
4342
 
4356
4343
        detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start,
4357
4344
                    my_edge_size, dest, near_edge);
4359
4346
    dock_get_area(&dock_area);
4360
4347
    detect_edge(dock_area, dir, my_head, my_size, my_edge_start,
4361
4348
                my_edge_size, dest, near_edge);
4362
 
    g_free(a);
 
4349
 
 
4350
    g_slice_free(Rect, a);
4363
4351
}
4364
4352
 
4365
4353
void client_find_move_directional(ObClient *self, ObDirection dir,
4471
4459
        g_assert_not_reached();
4472
4460
    }
4473
4461
 
4474
 
    ob_debug("head %d dir %d\n", head, dir);
 
4462
    ob_debug("head %d dir %d", head, dir);
4475
4463
    client_find_edge_directional(self, dir, head, 1,
4476
4464
                                 e_start, e_size, &e, &near);
4477
 
    ob_debug("edge %d\n", e);
 
4465
    ob_debug("edge %d", e);
4478
4466
    *x = self->frame->area.x;
4479
4467
    *y = self->frame->area.y;
4480
4468
    *w = self->frame->area.width;
4544
4532
    return self->group && self->group->members->next;
4545
4533
}
4546
4534
 
 
4535
gboolean client_has_relative(ObClient *self)
 
4536
{
 
4537
    return client_has_parent(self) ||
 
4538
        client_has_group_siblings(self) ||
 
4539
        client_has_children(self);
 
4540
}
 
4541
 
4547
4542
/*! Returns TRUE if the client is running on the same machine as Openbox */
4548
4543
gboolean client_on_localhost(ObClient *self)
4549
4544
{