~ubuntu-branches/ubuntu/warty/fluxbox/warty

« back to all changes in this revision

Viewing changes to src/Window.cc

  • Committer: Bazaar Package Importer
  • Author(s): Matt Hope
  • Date: 2002-04-12 22:08:52 UTC
  • Revision ID: james.westby@ubuntu.com-20020412220852-0gbqxr57mgu63qdh
Tags: upstream-0.1.7
ImportĀ upstreamĀ versionĀ 0.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Window.cc for Fluxbox Window Manager
 
2
// Copyright (c) 2001 - 2002    Henrik Kinnunen (fluxgen@linuxmail.org)
 
3
//
 
4
// Window.cc for Blackbox - an X11 Window manager
 
5
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
 
6
//
 
7
// Permission is hereby granted, free of charge, to any person obtaining a
 
8
// copy of this software and associated documentation files (the "Software"),
 
9
// to deal in the Software without restriction, including without limitation
 
10
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
11
// and/or sell copies of the Software, and to permit persons to whom the
 
12
// Software is furnished to do so, subject to the following conditions:
 
13
//
 
14
// The above copyright notice and this permission notice shall be included in
 
15
// all copies or substantial portions of the Software.
 
16
//
 
17
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.        IN NO EVENT SHALL
 
20
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
21
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
23
// DEALINGS IN THE SOFTWARE.
 
24
 
 
25
// $Id: Window.cc,v 1.31 2002/02/27 22:04:01 fluxgen Exp $
 
26
 
 
27
//use GNU extensions
 
28
#ifndef  _GNU_SOURCE
 
29
#define  _GNU_SOURCE
 
30
#endif // _GNU_SOURCE
 
31
 
 
32
#ifdef          HAVE_CONFIG_H
 
33
#       include "../config.h"
 
34
#endif // HAVE_CONFIG_H
 
35
 
 
36
#include "i18n.hh"
 
37
#include "fluxbox.hh"
 
38
#include "Icon.hh"
 
39
#include "Screen.hh"
 
40
#include "Toolbar.hh"
 
41
#include "Window.hh"
 
42
#include "Windowmenu.hh"
 
43
#include "StringUtil.hh"
 
44
 
 
45
#ifdef          SLIT
 
46
#       include "Slit.hh"
 
47
#endif // SLIT
 
48
 
 
49
#include <X11/Xatom.h>
 
50
#include <X11/keysym.h>
 
51
 
 
52
#ifdef          STDC_HEADERS
 
53
#       include <string.h>
 
54
#endif // STDC_HEADERS
 
55
 
 
56
#ifdef          DEBUG
 
57
#       ifdef           HAVE_STDIO_H
 
58
#               include <stdio.h>
 
59
#       endif // HAVE_STDIO_H
 
60
#endif // DEBUG
 
61
 
 
62
 
 
63
#include <iostream>
 
64
using namespace std;
 
65
 
 
66
FluxboxWindow::FluxboxWindow(Window w, BScreen *s):
 
67
image_ctrl(0),
 
68
moving(false), resizing(false), shaded(false), maximized(false),
 
69
visible(false), iconic(false), transient(false), focused(false),
 
70
stuck(false), modal(false), send_focus_message(false), managed(false),
 
71
screen(0),
 
72
timer(0),
 
73
display(0),
 
74
lastButtonPressTime(0),
 
75
windowmenu(0),
 
76
m_layer(LAYER_NORMAL),
 
77
tab(0)
 
78
#ifdef GNOME
 
79
,gnome_hints(0)
 
80
#endif
 
81
{
 
82
 
 
83
        #ifdef DEBUG
 
84
        fprintf(stderr,
 
85
                I18n::instance()->
 
86
                getMessage(
 
87
        #ifdef NLS
 
88
                        WindowSet, WindowCreating,
 
89
        #else // !NLS
 
90
                        0, 0,
 
91
        #endif // NLS
 
92
                        "FluxboxWindow::FluxboxWindow(): creating 0x%lx\n"),
 
93
                w);
 
94
        #endif // DEBUG
 
95
 
 
96
        Fluxbox *fluxbox = Fluxbox::instance();
 
97
        display = fluxbox->getXDisplay();
 
98
        BaseDisplay::GrabGuard gg(*fluxbox);
 
99
        
 
100
        blackbox_attrib.workspace = workspace_number = window_number = -1;
 
101
 
 
102
        blackbox_attrib.flags = blackbox_attrib.attrib = blackbox_attrib.stack = 0l;
 
103
        blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
 
104
        blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
 
105
        //use tab as default
 
106
        decorations.tab = true;
 
107
        client.window = w;
 
108
        frame.window = frame.plate = frame.title = frame.handle = None;
 
109
        frame.right_grip = frame.left_grip = None;
 
110
 
 
111
        frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None;
 
112
        frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None;
 
113
        frame.pbutton = frame.ugrip = frame.fgrip = None;
 
114
        
 
115
        //get decorations
 
116
        vector<Fluxbox::Titlebar> dir = fluxbox->getTitlebarLeft();
 
117
        for (char c=0; c<2; c++) {
 
118
                for (unsigned int i=0; i<dir.size(); i++) {
 
119
                        switch (dir[i]) {
 
120
                                case Fluxbox::SHADE:
 
121
                                        decorations.shade = true;
 
122
                                break;
 
123
                                case Fluxbox::MAXIMIZE:
 
124
                                        decorations.maximize = true;    
 
125
                                break;
 
126
                                case Fluxbox::MINIMIZE:
 
127
                                        decorations.iconify = true;                     
 
128
                                break;
 
129
                                case Fluxbox::STICK:
 
130
                                        decorations.sticky = true;
 
131
                                break;
 
132
                                case Fluxbox::CLOSE:
 
133
                                        decorations.close = true;
 
134
                                break;
 
135
                                case Fluxbox::MENU:
 
136
                                        decorations.menu = true;
 
137
                                break;
 
138
                                default:
 
139
                                break;
 
140
                        }
 
141
                }
 
142
                //next right
 
143
                dir = fluxbox->getTitlebarRight();
 
144
        }
 
145
        
 
146
        decorations.menu = true;        //override menu option
 
147
        
 
148
        decorations.titlebar = decorations.border = decorations.handle = true;
 
149
        functions.resize = functions.move = functions.iconify = functions.maximize = true;
 
150
        functions.close = decorations.close = false;
 
151
 
 
152
        client.wm_hint_flags = client.normal_hint_flags = 0;
 
153
        client.transient_for = client.transient = 0;
 
154
        client.title = 0;
 
155
        client.title_len = 0;
 
156
        client.icon_title = 0;
 
157
        client.mwm_hint = (MwmHints *) 0;
 
158
        client.blackbox_hint = 0;
 
159
 
 
160
        fluxbox->grab();
 
161
        if (! validateClient())
 
162
                return;
 
163
 
 
164
        // fetch client size and placement
 
165
        XWindowAttributes wattrib;
 
166
        if ((! XGetWindowAttributes(display, client.window, &wattrib)) ||
 
167
                        (! wattrib.screen) || wattrib.override_redirect) {
 
168
                return;
 
169
        }
 
170
 
 
171
        if (s)
 
172
                screen = s;
 
173
        else
 
174
                screen = fluxbox->searchScreen(RootWindowOfScreen(wattrib.screen));
 
175
 
 
176
        if (!screen)
 
177
                return;
 
178
 
 
179
        image_ctrl = screen->getImageControl();
 
180
 
 
181
        client.x = wattrib.x;
 
182
        client.y = wattrib.y;
 
183
        client.width = wattrib.width;
 
184
        client.height = wattrib.height;
 
185
        client.old_bw = wattrib.border_width;
 
186
 
 
187
        timer = new BTimer(fluxbox, this);
 
188
        timer->setTimeout(fluxbox->getAutoRaiseDelay());
 
189
        timer->fireOnce(true);
 
190
 
 
191
        getBlackboxHints();
 
192
        if (! client.blackbox_hint)
 
193
                getMWMHints();
 
194
 
 
195
        // get size, aspect, minimum/maximum size and other hints set by the
 
196
        // client
 
197
        getWMProtocols();
 
198
        getWMHints();
 
199
        getWMNormalHints();
 
200
 
 
201
        #ifdef SLIT
 
202
 
 
203
        if (client.initial_state == WithdrawnState) {
 
204
                screen->getSlit()->addClient(client.window);
 
205
                return;
 
206
        }
 
207
        #endif // SLIT
 
208
 
 
209
        managed = true; //mark for usage
 
210
 
 
211
        fluxbox->saveWindowSearch(client.window, this);
 
212
 
 
213
        // determine if this is a transient window
 
214
        Window win;
 
215
        if (XGetTransientForHint(display, client.window, &win)) {       
 
216
                if (win && (win != client.window)) {
 
217
                        FluxboxWindow *tr;
 
218
                        if ((tr = fluxbox->searchWindow(win))) {
 
219
                                
 
220
                                while (tr->client.transient) 
 
221
                                        tr = tr->client.transient;
 
222
                                
 
223
                                client.transient_for = tr;
 
224
                                tr->client.transient = this;
 
225
                                stuck = client.transient_for->stuck;
 
226
                                transient = true;
 
227
                        } else if (win == client.window_group) {
 
228
                                if ((tr = fluxbox->searchGroup(win, this))) {
 
229
                                        
 
230
                                        while (tr->client.transient) 
 
231
                                                tr = tr->client.transient;
 
232
                                        
 
233
                                        client.transient_for = tr;
 
234
                                        tr->client.transient = this;
 
235
                                        stuck = client.transient_for->stuck;
 
236
                                        transient = true;
 
237
                                }
 
238
                        }
 
239
                }
 
240
 
 
241
                if (win == screen->getRootWindow())
 
242
                        modal = true;
 
243
        }
 
244
 
 
245
        // adjust the window decorations based on transience and window sizes
 
246
        if (transient) {
 
247
                decorations.maximize = decorations.handle =
 
248
                        decorations.border = functions.maximize = false;
 
249
        }       
 
250
        
 
251
        if ((client.normal_hint_flags & PMinSize) &&
 
252
                        (client.normal_hint_flags & PMaxSize) &&
 
253
                        client.max_width <= client.min_width &&
 
254
                        client.max_height <= client.min_height) {
 
255
                decorations.maximize = decorations.handle =
 
256
                        functions.resize = functions.maximize = false;
 
257
                        decorations.tab = false; //no tab for this window
 
258
        }
 
259
 
 
260
        upsize();
 
261
 
 
262
        bool place_window = true;
 
263
        if (fluxbox->isStartup() || transient ||
 
264
                        client.normal_hint_flags & (PPosition|USPosition)) {
 
265
                setGravityOffsets();
 
266
 
 
267
                if (! fluxbox->isStartup()) { // is going to be used when position
 
268
                        if (decorations.tab) {                  // window is cleanly fixed 
 
269
                                int real_x = frame.x;
 
270
                                int real_y = frame.y;
 
271
 
 
272
                                if (screen->getTabPlacement() == Tab::PTOP)
 
273
                                        real_y -= screen->getTabHeight();
 
274
 
 
275
                                else if (screen->getTabPlacement() == Tab::PLEFT) {
 
276
                                        if (screen->isTabRotateVertical())
 
277
                                                real_x -= screen->getTabHeight();
 
278
                                        else
 
279
                                                real_x -= screen->getTabWidth();
 
280
                                }
 
281
 
 
282
                                if (real_x >= 0 && 
 
283
                                                real_y + frame.y_border >= 0 &&
 
284
                                                real_x <= (signed) screen->getWidth() &&
 
285
                                                real_y <= (signed) screen->getHeight())
 
286
                                        place_window = false;
 
287
 
 
288
                        } else if (frame.x >= 0 && // non tab
 
289
                                        (signed) (frame.y + frame.y_border) >= 0 &&
 
290
                                        frame.x <= (signed) screen->getWidth() &&
 
291
                                        frame.y <= (signed) screen->getHeight())
 
292
                                place_window = false;
 
293
                } else
 
294
                        place_window = false;
 
295
 
 
296
/*              if ((fluxbox->isStartup()) ||
 
297
                                (frame.x >= 0 &&
 
298
                                (signed) (frame.y + frame.y_border) >= 0 &&
 
299
                                frame.x <= (signed) screen->getWidth() &&
 
300
                                frame.y <= (signed) screen->getHeight()))
 
301
                        place_window = false; */
 
302
                        
 
303
        }
 
304
 
 
305
        frame.window = createToplevelWindow(frame.x, frame.y, frame.width,
 
306
                frame.height,
 
307
                screen->getBorderWidth());      //create frame window
 
308
        
 
309
        fluxbox->saveWindowSearch(frame.window, this);  //save frame window
 
310
 
 
311
        frame.plate = createChildWindow(frame.window); //Create plate window
 
312
        fluxbox->saveWindowSearch(frame.plate, this);   //save plate window
 
313
        
 
314
        frame.title = createChildWindow(frame.window); //create titlebar win
 
315
        if (decorations.titlebar) {     //have titlebar decorations?            
 
316
                fluxbox->saveWindowSearch(frame.title, this);   //save titlebar win
 
317
                frame.label = createChildWindow(frame.title); //create label win in titlebar
 
318
                fluxbox->saveWindowSearch(frame.label, this);   //save label win
 
319
        }
 
320
 
 
321
        if (decorations.handle) {       //have handle decorations ?
 
322
                frame.handle = createChildWindow(frame.window); //create handle win
 
323
                fluxbox->saveWindowSearch(frame.handle, this);  //save handle win
 
324
 
 
325
                frame.left_grip = // create left handle
 
326
                        createChildWindow(frame.handle, fluxbox->getLowerLeftAngleCursor());
 
327
                fluxbox->saveWindowSearch(frame.left_grip, this); //save left handle
 
328
 
 
329
                frame.right_grip = // create right handle
 
330
                        createChildWindow(frame.handle, fluxbox->getLowerRightAngleCursor());
 
331
                fluxbox->saveWindowSearch(frame.right_grip, this); //save right handle
 
332
        }
 
333
        
 
334
        
 
335
        associateClientWindow();
 
336
 
 
337
        grabButtons();
 
338
                                
 
339
        positionWindows();
 
340
 
 
341
        //use tab? delayed this so that tabs wont "flicker" when creating windows
 
342
        if (decorations.tab && fluxbox->useTabs())
 
343
                tab = new Tab(this, 0, 0);
 
344
        decorate();
 
345
        
 
346
        XRaiseWindow(display, frame.plate);
 
347
        XMapSubwindows(display, frame.plate);
 
348
        if (decorations.titlebar)
 
349
                XMapSubwindows(display, frame.title);
 
350
        
 
351
        XMapSubwindows(display, frame.window);
 
352
 
 
353
        if (decorations.menu)
 
354
                windowmenu = new Windowmenu(this);
 
355
 
 
356
        if (workspace_number < 0 || workspace_number >= screen->getCount())
 
357
                screen->getCurrentWorkspace()->addWindow(this, place_window);
 
358
        else
 
359
                screen->getWorkspace(workspace_number)->addWindow(this, place_window);
 
360
 
 
361
        configure(frame.x, frame.y, frame.width, frame.height);
 
362
 
 
363
        if (shaded) {
 
364
                shaded = false;
 
365
                shade();
 
366
        }
 
367
 
 
368
        if (maximized && functions.maximize) {
 
369
                int m = maximized;
 
370
                maximized = false;
 
371
 
 
372
                maximize(m);
 
373
        }
 
374
 
 
375
        setFocusFlag(false);
 
376
 
 
377
        #ifdef GNOME
 
378
        updateGnomeAtoms();
 
379
        #endif
 
380
 
 
381
        #ifdef DEBUG
 
382
        fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this);
 
383
        #endif
 
384
 
 
385
 
 
386
}
 
387
 
 
388
 
 
389
FluxboxWindow::~FluxboxWindow(void) {
 
390
        if (screen==0) //the window wasn't created 
 
391
                return;
 
392
 
 
393
        Fluxbox *fluxbox = Fluxbox::instance();
 
394
        
 
395
        
 
396
        if (moving || resizing) {
 
397
                screen->hideGeometry();
 
398
                XUngrabPointer(display, CurrentTime);
 
399
        }
 
400
        
 
401
        if (workspace_number != -1 && window_number != -1)
 
402
                screen->getWorkspace(workspace_number)->removeWindow(this);
 
403
        else if (iconic)
 
404
                screen->removeIcon(this);
 
405
        
 
406
        if (timer) {
 
407
                if (timer->isTiming()) timer->stop();
 
408
                delete timer;
 
409
                timer = 0;
 
410
        }
 
411
 
 
412
        if (windowmenu)
 
413
                delete windowmenu;
 
414
 
 
415
        if (client.title)
 
416
                delete [] client.title;
 
417
 
 
418
        if (client.icon_title)
 
419
                delete [] client.icon_title;
 
420
 
 
421
        if (tab!=0)
 
422
                delete tab;     
 
423
        tab = 0;
 
424
        
 
425
        if (client.mwm_hint!=0)
 
426
                XFree(client.mwm_hint);
 
427
 
 
428
        if (client.blackbox_hint!=0)
 
429
                XFree(client.blackbox_hint);            
 
430
 
 
431
        //TODO: Move this to Workspace::removeWindow
 
432
        if (client.transient_for!=0)    
 
433
                fluxbox->setFocusedWindow(client.transient_for);        
 
434
        
 
435
        if (client.window_group)
 
436
                fluxbox->removeGroupSearch(client.window_group);
 
437
 
 
438
        if (transient && client.transient_for)
 
439
                client.transient_for->client.transient = client.transient;
 
440
        if (client.transient)
 
441
                client.transient->client.transient_for = client.transient_for;
 
442
        
 
443
        while ( !buttonlist.empty()) {  //destroy all buttons on titlebar
 
444
                fluxbox->removeWindowSearch(buttonlist.back().win);     
 
445
                XDestroyWindow(display, buttonlist.back().win);
 
446
                buttonlist.pop_back();
 
447
        }
 
448
 
 
449
        if (frame.title) {
 
450
                if (frame.ftitle)
 
451
                        image_ctrl->removeImage(frame.ftitle);
 
452
 
 
453
                if (frame.utitle)
 
454
                        image_ctrl->removeImage(frame.utitle);
 
455
 
 
456
                if (frame.flabel)
 
457
                        image_ctrl->removeImage(frame.flabel);
 
458
 
 
459
                if( frame.ulabel)
 
460
                        image_ctrl->removeImage(frame.ulabel);
 
461
 
 
462
                fluxbox->removeWindowSearch(frame.label);
 
463
                fluxbox->removeWindowSearch(frame.title);
 
464
                XDestroyWindow(display, frame.label);
 
465
                XDestroyWindow(display, frame.title);
 
466
        }
 
467
 
 
468
        if (frame.handle) {
 
469
                if (frame.fhandle)
 
470
                        image_ctrl->removeImage(frame.fhandle);
 
471
 
 
472
                if (frame.uhandle)
 
473
                        image_ctrl->removeImage(frame.uhandle);
 
474
 
 
475
                if (frame.fgrip)
 
476
                        image_ctrl->removeImage(frame.fgrip);
 
477
 
 
478
                if (frame.ugrip)
 
479
                        image_ctrl->removeImage(frame.ugrip);
 
480
 
 
481
                fluxbox->removeWindowSearch(frame.right_grip);
 
482
                fluxbox->removeWindowSearch(frame.left_grip);
 
483
                fluxbox->removeWindowSearch(frame.handle);
 
484
                
 
485
                XDestroyWindow(display, frame.right_grip);
 
486
                XDestroyWindow(display, frame.left_grip);
 
487
                XDestroyWindow(display, frame.handle);
 
488
        }
 
489
 
 
490
        if (frame.fbutton)
 
491
                image_ctrl->removeImage(frame.fbutton);
 
492
 
 
493
        if (frame.ubutton)
 
494
                image_ctrl->removeImage(frame.ubutton);
 
495
 
 
496
        if (frame.pbutton)
 
497
                image_ctrl->removeImage(frame.pbutton);
 
498
 
 
499
        
 
500
        if (frame.plate) {              //NOTE 
 
501
                fluxbox->removeWindowSearch(frame.plate);
 
502
                XDestroyWindow(display, frame.plate);
 
503
        }
 
504
 
 
505
        if (frame.window) {
 
506
                fluxbox->removeWindowSearch(frame.window);
 
507
                XDestroyWindow(display, frame.window);
 
508
        }
 
509
 
 
510
        if (managed) {
 
511
                fluxbox->removeWindowSearch(client.window);
 
512
                screen->removeNetizen(client.window);
 
513
        }
 
514
 
 
515
 
 
516
        #ifdef DEBUG
 
517
        cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow(this="<<this<<") done"<<endl;
 
518
        #endif
 
519
}
 
520
 
 
521
void FluxboxWindow::showError(FluxboxWindow::Error error) {
 
522
 
 
523
#ifdef          DEBUG
 
524
        switch (error) {                
 
525
        case NOERROR:
 
526
                break;
 
527
        case XGETWINDOWATTRIB:  
 
528
                fprintf(stderr,
 
529
                        I18n::instance()->
 
530
                        getMessage(
 
531
                        #ifdef NLS
 
532
                                WindowSet, WindowXGetWindowAttributesFail,
 
533
                        #else // !NLS
 
534
                                0, 0,
 
535
                        #endif // NLS
 
536
                                "FluxboxWindow::FluxboxWindow(): XGetWindowAttributes "
 
537
                                "failed\n")
 
538
                        );      
 
539
                break;
 
540
        case CANTFINDSCREEN:
 
541
                fprintf(stderr,
 
542
                        I18n::instance()->
 
543
                        getMessage(
 
544
                        #ifdef NLS
 
545
                                WindowSet, WindowCannotFindScreen,
 
546
                        #else // !NLS
 
547
                                0, 0,
 
548
                        #endif // NLS
 
549
                                "FluxboxWindow::FluxboxWindow(): can't find screen\n"
 
550
                                "       for root window"));
 
551
                break;
 
552
        };
 
553
#endif // DEBUG 
 
554
}
 
555
 
 
556
Window FluxboxWindow::createToplevelWindow(
 
557
        int x, int y, unsigned int width,
 
558
        unsigned int height,
 
559
        unsigned int borderwidth)
 
560
{
 
561
        XSetWindowAttributes attrib_create;
 
562
        unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap |
 
563
                CWOverrideRedirect | CWEventMask;
 
564
 
 
565
        attrib_create.background_pixmap = None;
 
566
        attrib_create.colormap = screen->getColormap();
 
567
        attrib_create.override_redirect = True;
 
568
        attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
 
569
                ButtonMotionMask | EnterWindowMask;
 
570
 
 
571
        return (XCreateWindow(display, screen->getRootWindow(), x, y, width, height,
 
572
                borderwidth, screen->getDepth(), InputOutput,
 
573
                screen->getVisual(), create_mask,
 
574
                &attrib_create));
 
575
}
 
576
 
 
577
 
 
578
Window FluxboxWindow::createChildWindow(Window parent, Cursor cursor) {
 
579
        XSetWindowAttributes attrib_create;
 
580
        unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
 
581
 
 
582
        attrib_create.background_pixmap = None;
 
583
        attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
 
584
                ButtonMotionMask | ExposureMask |
 
585
                EnterWindowMask | LeaveWindowMask;
 
586
 
 
587
        if (cursor) {
 
588
                create_mask |= CWCursor;
 
589
                attrib_create.cursor = cursor;
 
590
        }
 
591
 
 
592
        return (XCreateWindow(display, parent, 0, 0, 1, 1, 0,
 
593
                screen->getDepth(), InputOutput, screen->getVisual(),
 
594
                create_mask, &attrib_create));
 
595
}
 
596
 
 
597
 
 
598
void FluxboxWindow::associateClientWindow(void) {
 
599
        XSetWindowBorderWidth(display, client.window, 0);
 
600
        getWMName();
 
601
        getWMIconName();
 
602
 
 
603
        XChangeSaveSet(display, client.window, SetModeInsert);
 
604
        XSetWindowAttributes attrib_set;
 
605
 
 
606
        XSelectInput(display, frame.plate, NoEventMask);
 
607
        XReparentWindow(display, client.window, frame.plate, 0, 0);
 
608
        XSelectInput(display, frame.plate, SubstructureRedirectMask);
 
609
 
 
610
        XFlush(display);
 
611
 
 
612
        attrib_set.event_mask = 
 
613
                PropertyChangeMask | StructureNotifyMask | FocusChangeMask;
 
614
        attrib_set.do_not_propagate_mask = 
 
615
                ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
 
616
 
 
617
        XChangeWindowAttributes(display, client.window, CWEventMask|CWDontPropagate,
 
618
                &attrib_set);
 
619
 
 
620
#ifdef          SHAPE
 
621
        if (Fluxbox::instance()->hasShapeExtensions()) {
 
622
                XShapeSelectInput(display, client.window, ShapeNotifyMask);
 
623
 
 
624
                int foo;
 
625
                unsigned int ufoo;
 
626
 
 
627
                XShapeQueryExtents(display, client.window, &frame.shaped, &foo, &foo,
 
628
                        &ufoo, &ufoo, &foo, &foo, &foo, &ufoo, &ufoo);
 
629
 
 
630
                if (frame.shaped) {
 
631
                        XShapeCombineShape(display, frame.window, ShapeBounding,
 
632
                                frame.mwm_border_w, frame.y_border +
 
633
                                frame.mwm_border_w, client.window,
 
634
                                ShapeBounding, ShapeSet);
 
635
 
 
636
                        int num = 1;
 
637
                        XRectangle xrect[2];
 
638
                        xrect[0].x = xrect[0].y = 0;
 
639
                        xrect[0].width = frame.width;
 
640
                        xrect[0].height = frame.y_border;
 
641
 
 
642
                        if (decorations.handle) {
 
643
                                xrect[1].x = 0;
 
644
                                xrect[1].y = frame.y_handle;
 
645
                                xrect[1].width = frame.width;
 
646
                                xrect[1].height = frame.handle_h + screen->getBorderWidth();
 
647
                                num++;
 
648
                        }
 
649
 
 
650
                        XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
 
651
                                xrect, num, ShapeUnion, Unsorted);
 
652
                }
 
653
        }
 
654
#endif // SHAPE
 
655
        //create the buttons
 
656
        if (decorations.iconify) 
 
657
                createButton(Fluxbox::MINIMIZE, FluxboxWindow::iconifyPressed_cb, 
 
658
                        FluxboxWindow::iconifyButton_cb, FluxboxWindow::iconifyDraw_cb);
 
659
        if (decorations.maximize)
 
660
                createButton(Fluxbox::MAXIMIZE, FluxboxWindow::maximizePressed_cb, 
 
661
                        FluxboxWindow::maximizeButton_cb, FluxboxWindow::maximizeDraw_cb);
 
662
        if (decorations.close) 
 
663
                createButton(Fluxbox::CLOSE, FluxboxWindow::closePressed_cb, 
 
664
                        FluxboxWindow::closeButton_cb, FluxboxWindow::closeDraw_cb);            
 
665
        if (decorations.sticky)
 
666
                createButton(Fluxbox::STICK, FluxboxWindow::stickyPressed_cb, 
 
667
                        FluxboxWindow::stickyButton_cb, FluxboxWindow::stickyDraw_cb);
 
668
 
 
669
        if (decorations.menu)//TODO
 
670
                createButton(Fluxbox::MENU, 0, 0, 0);
 
671
 
 
672
        if (decorations.shade)
 
673
                createButton(Fluxbox::SHADE, 0, FluxboxWindow::shadeButton_cb, FluxboxWindow::shadeDraw_cb);
 
674
 
 
675
        if (frame.ubutton) {
 
676
                for (unsigned int i=0; i<buttonlist.size(); i++)
 
677
                        XSetWindowBackgroundPixmap(display, buttonlist[i].win, frame.ubutton);   
 
678
        
 
679
        } else {
 
680
                for (unsigned int i=0; i<buttonlist.size(); i++)
 
681
                        XSetWindowBackground(display, buttonlist[i].win, frame.ubutton_pixel);   
 
682
        }
 
683
}
 
684
 
 
685
 
 
686
void FluxboxWindow::decorate(void) {
 
687
                
 
688
        if (tab)
 
689
                tab->decorate();
 
690
 
 
691
        Pixmap tmp = frame.fbutton;
 
692
        BTexture *texture = &(screen->getWindowStyle()->b_focus);
 
693
        if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
694
                frame.fbutton = None;
 
695
                frame.fbutton_pixel = texture->getColor()->getPixel();
 
696
        } else
 
697
                frame.fbutton =
 
698
                        image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
 
699
        if (tmp) image_ctrl->removeImage(tmp);
 
700
 
 
701
        tmp = frame.ubutton;
 
702
        texture = &(screen->getWindowStyle()->b_unfocus);
 
703
        if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
704
                frame.ubutton = None;
 
705
                frame.ubutton_pixel = texture->getColor()->getPixel();
 
706
        } else
 
707
                frame.ubutton =
 
708
                        image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
 
709
        if (tmp) image_ctrl->removeImage(tmp);
 
710
 
 
711
        tmp = frame.pbutton;
 
712
        texture = &(screen->getWindowStyle()->b_pressed);
 
713
        if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
714
                frame.pbutton = None;
 
715
                frame.pbutton_pixel = texture->getColor()->getPixel();
 
716
        } else
 
717
                frame.pbutton =
 
718
                        image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
 
719
        if (tmp) image_ctrl->removeImage(tmp);
 
720
 
 
721
        if (decorations.titlebar) {
 
722
                tmp = frame.ftitle;
 
723
                texture = &(screen->getWindowStyle()->t_focus);
 
724
                if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
725
                        frame.ftitle = None;
 
726
                        frame.ftitle_pixel = texture->getColor()->getPixel();
 
727
                } else
 
728
                        frame.ftitle =
 
729
                                image_ctrl->renderImage(frame.width, frame.title_h, texture);
 
730
                
 
731
                if (tmp) 
 
732
                        image_ctrl->removeImage(tmp);
 
733
 
 
734
                tmp = frame.utitle;
 
735
                texture = &(screen->getWindowStyle()->t_unfocus);
 
736
                if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
737
                        frame.utitle = None;
 
738
                        frame.utitle_pixel = texture->getColor()->getPixel();
 
739
                } else
 
740
                        frame.utitle =
 
741
                                image_ctrl->renderImage(frame.width, frame.title_h, texture);
 
742
                if (tmp) image_ctrl->removeImage(tmp);
 
743
 
 
744
                XSetWindowBorder(display, frame.title,
 
745
                         screen->getBorderColor()->getPixel());
 
746
 
 
747
                decorateLabel();
 
748
                
 
749
        }
 
750
 
 
751
        if (decorations.border) {
 
752
                frame.fborder_pixel = screen->getWindowStyle()->f_focus.getPixel();
 
753
                frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.getPixel();
 
754
        }
 
755
 
 
756
        if (decorations.handle) {
 
757
                tmp = frame.fhandle;
 
758
                texture = &(screen->getWindowStyle()->h_focus);
 
759
                if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
760
                        frame.fhandle = None;
 
761
                        frame.fhandle_pixel = texture->getColor()->getPixel();
 
762
                } else
 
763
                        frame.fhandle =
 
764
                                image_ctrl->renderImage(frame.width, frame.handle_h, texture);
 
765
                if (tmp) image_ctrl->removeImage(tmp);
 
766
 
 
767
                tmp = frame.uhandle;
 
768
                texture = &(screen->getWindowStyle()->h_unfocus);
 
769
                if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
770
                        frame.uhandle = None;
 
771
                        frame.uhandle_pixel = texture->getColor()->getPixel();
 
772
                } else
 
773
                        frame.uhandle =
 
774
                                image_ctrl->renderImage(frame.width, frame.handle_h, texture);
 
775
                if (tmp)
 
776
                        image_ctrl->removeImage(tmp);
 
777
 
 
778
                tmp = frame.fgrip;
 
779
                texture = &(screen->getWindowStyle()->g_focus);
 
780
                if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
781
                        frame.fgrip = None;
 
782
                        frame.fgrip_pixel = texture->getColor()->getPixel();
 
783
                } else
 
784
                        frame.fgrip =
 
785
                                image_ctrl->renderImage(frame.grip_w, frame.grip_h, texture);
 
786
                if (tmp)
 
787
                        image_ctrl->removeImage(tmp);
 
788
 
 
789
                tmp = frame.ugrip;
 
790
                texture = &(screen->getWindowStyle()->g_unfocus);
 
791
                if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
792
                        frame.ugrip = None;
 
793
                        frame.ugrip_pixel = texture->getColor()->getPixel();
 
794
                } else
 
795
                        frame.ugrip =
 
796
                                image_ctrl->renderImage(frame.grip_w, frame.grip_h, texture);
 
797
                if (tmp) image_ctrl->removeImage(tmp);
 
798
 
 
799
                XSetWindowBorder(display, frame.handle,
 
800
                        screen->getBorderColor()->getPixel());
 
801
                XSetWindowBorder(display, frame.left_grip,
 
802
                        screen->getBorderColor()->getPixel());
 
803
                XSetWindowBorder(display, frame.right_grip,
 
804
                        screen->getBorderColor()->getPixel());
 
805
        }
 
806
                
 
807
        XSetWindowBorder(display, frame.window,
 
808
                screen->getBorderColor()->getPixel());
 
809
}
 
810
 
 
811
 
 
812
void FluxboxWindow::decorateLabel(void) {
 
813
        Pixmap tmp = frame.flabel;
 
814
        BTexture *texture = &(screen->getWindowStyle()->l_focus);
 
815
        if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
816
                frame.flabel = None;
 
817
                frame.flabel_pixel = texture->getColor()->getPixel();           
 
818
        } else
 
819
                frame.flabel = image_ctrl->renderImage(frame.label_w, frame.label_h, texture);
 
820
                        
 
821
        if (tmp) image_ctrl->removeImage(tmp);
 
822
 
 
823
        tmp = frame.ulabel;
 
824
        texture = &(screen->getWindowStyle()->l_unfocus);
 
825
        if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
826
                frame.ulabel = None;
 
827
                frame.ulabel_pixel = texture->getColor()->getPixel();
 
828
        } else
 
829
                frame.ulabel = image_ctrl->renderImage(frame.label_w, frame.label_h, texture);
 
830
                
 
831
        if (tmp) image_ctrl->removeImage(tmp);
 
832
}
 
833
 
 
834
void FluxboxWindow::grabButtons() {
 
835
        Fluxbox *fluxbox = Fluxbox::instance();
 
836
 
 
837
        XGrabButton(display, Button1, AnyModifier, 
 
838
                frame.plate, True, ButtonPressMask,
 
839
                GrabModeSync, GrabModeSync, None, None);                
 
840
        XUngrabButton(display, Button1, Mod1Mask|Mod2Mask|Mod3Mask, frame.plate);
 
841
                
 
842
 
 
843
        XGrabButton(display, Button1, Mod1Mask, frame.window, True,
 
844
                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
845
                GrabModeAsync, None, fluxbox->getMoveCursor());
 
846
 
 
847
        //----grab with "all" modifiers
 
848
        grabButton(display, Button1, frame.window, fluxbox->getMoveCursor());
 
849
        
 
850
        XGrabButton(display, Button2, Mod1Mask, frame.window, True,
 
851
                ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None);   
 
852
                
 
853
        XGrabButton(display, Button3, Mod1Mask, frame.window, True,
 
854
                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
855
                GrabModeAsync, None, fluxbox->getLowerRightAngleCursor());
 
856
        
 
857
        //---grab with "all" modifiers
 
858
        grabButton(display, Button3, frame.window, fluxbox->getLowerRightAngleCursor());
 
859
}
 
860
 
 
861
void FluxboxWindow::createButton(int type, ButtonEventProc pressed, ButtonEventProc released, ButtonDrawProc draw) {
 
862
        Button b;
 
863
        b.win = createChildWindow(frame.title);
 
864
        Fluxbox::instance()->saveWindowSearch(b.win, this);
 
865
        b.type = type;
 
866
        b.used = true;
 
867
        b.draw = draw;
 
868
        b.pressed = pressed;
 
869
        b.released = released;
 
870
        buttonlist.push_back(b);
 
871
}
 
872
 
 
873
#ifdef GNOME
 
874
//TODO
 
875
void FluxboxWindow::updateGnomeAtoms() {
 
876
        updateGnomeWorkspaceAtom();
 
877
        updateGnomeStateAtom();
 
878
        updateGnomeLayerAtom();
 
879
        updateGnomeWorkspaceAtom();
 
880
}
 
881
 
 
882
void FluxboxWindow::updateGnomeStateAtom() {
 
883
        BaseDisplay *bd = screen->getBaseDisplay();
 
884
        int val = getGnomeWindowState();
 
885
        XChangeProperty(display, client.window, bd->getGnomeStateAtom(),
 
886
                XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&val, 1);    
 
887
}
 
888
 
 
889
void FluxboxWindow::updateGnomeLayerAtom() {
 
890
        BaseDisplay *bd = screen->getBaseDisplay();
 
891
        int val = getGnomeLayer();
 
892
        XChangeProperty(display, client.window, bd->getGnomeLayerAtom(),
 
893
                XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&val, 1);    
 
894
}
 
895
 
 
896
void FluxboxWindow::updateGnomeWorkspaceAtom() {
 
897
        BaseDisplay *bd = screen->getBaseDisplay();
 
898
        int val = workspace_number; 
 
899
        XChangeProperty(display, client.window, bd->getGnomeWorkspaceAtom(), 
 
900
                XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&val, 1);    
 
901
}
 
902
 
 
903
//TODO
 
904
int FluxboxWindow::getGnomeWindowState() {
 
905
        int state=0;
 
906
        if (isStuck())
 
907
                state |= WIN_STATE_STICKY;
 
908
        if (isIconic())
 
909
                state |= WIN_STATE_MINIMIZED;
 
910
        if (isShaded())
 
911
                state |= WIN_STATE_SHADED;
 
912
        /*TODO: states:
 
913
                WIN_STATE_MAXIMIZED_VERT   // window in maximized V state
 
914
                WIN_STATE_MAXIMIZED_HORIZ // window in maximized H state
 
915
                WIN_STATE_HIDDEN          // not on taskbar but window visible          
 
916
                WIN_STATE_HID_WORKSPACE   // not on current desktop
 
917
                WIN_STATE_HID_TRANSIENT   // owner of transient is hidden
 
918
                WIN_STATE_FIXED_POSITION  // window is fixed in position even
 
919
                WIN_STATE_ARRANGE_IGNORE  // ignore for auto arranging
 
920
        */
 
921
        return state;
 
922
}
 
923
 
 
924
//TODO
 
925
int FluxboxWindow::getGnomeLayer() {
 
926
        switch (m_layer) {
 
927
                case LAYER_NORMAL:
 
928
                        return WIN_LAYER_NORMAL;
 
929
                case LAYER_BOTTOM:
 
930
                        return WIN_LAYER_BELOW;
 
931
                case LAYER_TOP:
 
932
                        return WIN_LAYER_ONTOP;
 
933
                case LAYER_BELOW:
 
934
                        return WIN_LAYER_BELOW;
 
935
                default:
 
936
                break;
 
937
        }
 
938
        return WIN_LAYER_NORMAL;        
 
939
}
 
940
 
 
941
bool FluxboxWindow::handleGnomePropertyNotify(Atom atom) {
 
942
        BaseDisplay *bd = screen->getBaseDisplay();
 
943
        
 
944
        if (atom == bd->getGnomeStateAtom()) {
 
945
                #ifdef DEBUG
 
946
                cerr<<__FILE__<<"("<<__LINE__<<"): gnome state"<<endl;
 
947
                #endif
 
948
                loadGnomeStateAtom();
 
949
        } else  if (atom == bd->getGnomeWorkspaceAtom()) {
 
950
                #ifdef DEBUG
 
951
                cerr<<__FILE__<<"("<<__LINE__<<"): gnome workspace"<<endl;
 
952
                #endif          
 
953
        } else if (atom == bd->getGnomeHintsAtom()) {
 
954
                #ifdef DEBUG
 
955
                cerr<<__FILE__<<"("<<__LINE__<<"): gnome hints"<<endl;
 
956
                #endif
 
957
                loadGnomeHintsAtom();
 
958
        } else if (atom == bd->getGnomeLayerAtom()){
 
959
                #ifdef DEBUG
 
960
                cerr<<__FILE__<<"("<<__LINE__<<"): gnome layer"<<endl;
 
961
                #endif
 
962
                loadGnomeLayerAtom();
 
963
        } else
 
964
                return false;
 
965
 
 
966
        return true;
 
967
}
 
968
 
 
969
//TODO
 
970
void FluxboxWindow::setGnomeState(int state) {
 
971
        #ifdef DEBUG
 
972
        cerr<<"state=0x"<<hex<<state<<dec<<endl;
 
973
        #endif
 
974
 
 
975
        if ( state & WIN_STATE_STICKY) {
 
976
                cerr<<"Sticky"<<endl;
 
977
                if (!isStuck())
 
978
                        stick();
 
979
        } else if (isStuck())
 
980
                stick();
 
981
                        
 
982
        if (state & WIN_STATE_MINIMIZED) {
 
983
                cerr<<"Minimized"<<endl;
 
984
                if (isIconic())
 
985
                        iconify();
 
986
        } else if (isIconic())
 
987
                deiconify(true, true);
 
988
        /* TODO 
 
989
        if (state & WIN_STATE_MAXIMIZED_VERT)
 
990
                cerr<<"Maximize Vert"<<endl;
 
991
        if (state & WIN_STATE_MAXIMIZED_HORIZ)
 
992
                cerr<<"Maximize Horiz"<<endl;
 
993
        if (state & WIN_STATE_HIDDEN)
 
994
                cerr<<"Hidden"<<endl;
 
995
        if (state & WIN_STATE_SHADED) {
 
996
                cerr<<"Shaded"<<endl;
 
997
                if (!isShaded()) shade();
 
998
        } else if (isShaded())
 
999
                shade();
 
1000
 
 
1001
        if (state & WIN_STATE_HID_WORKSPACE)
 
1002
                cerr<<"HID Workspace"<<endl;
 
1003
        if (state & WIN_STATE_HID_TRANSIENT)
 
1004
                cerr<<"HID Transient"<<endl;
 
1005
        if (state & WIN_STATE_FIXED_POSITION)
 
1006
                cerr<<"Fixed Position"<<endl;
 
1007
        if (state & WIN_STATE_ARRANGE_IGNORE)
 
1008
                cerr<<"Arrange Ignore"<<endl;                   
 
1009
        */
 
1010
}
 
1011
 
 
1012
void FluxboxWindow::setGnomeLayer(int layer) {
 
1013
        switch (layer) {
 
1014
                case WIN_LAYER_DESKTOP:
 
1015
                        m_layer = LAYER_BOTTOM;
 
1016
                break;
 
1017
                case WIN_LAYER_BELOW:
 
1018
                        m_layer = LAYER_BELOW;
 
1019
                break;
 
1020
                case WIN_LAYER_NORMAL:
 
1021
                        m_layer = LAYER_NORMAL;
 
1022
                break;          
 
1023
                case WIN_LAYER_ONTOP:
 
1024
                case WIN_LAYER_DOCK:
 
1025
                case WIN_LAYER_ABOVE_DOCK:
 
1026
                case WIN_LAYER_MENU:
 
1027
                        m_layer = LAYER_TOP;
 
1028
                break;
 
1029
                default:
 
1030
                        m_layer = LAYER_NORMAL;
 
1031
                break;
 
1032
        }
 
1033
}
 
1034
//------------ loadGnomeAtoms ------------
 
1035
// Loads the values from the atoms
 
1036
//----------------------------------------
 
1037
void FluxboxWindow::loadGnomeAtoms() {
 
1038
        loadGnomeStateAtom();
 
1039
        loadGnomeHintsAtom();
 
1040
        loadGnomeLayerAtom();
 
1041
}
 
1042
//----------- loadGnomeStateAtom -------
 
1043
// Gets gnome state from the atom
 
1044
//----------------------------------------
 
1045
void FluxboxWindow::loadGnomeStateAtom() {
 
1046
        Atom ret_type;
 
1047
        int fmt;
 
1048
        unsigned long nitems, bytes_after;
 
1049
        long flags, *data = 0;
 
1050
        BaseDisplay *bd = screen->getBaseDisplay();
 
1051
        if (XGetWindowProperty (bd->getXDisplay(), getClientWindow(), 
 
1052
                        bd->getGnomeStateAtom(), 0, 1, False, XA_CARDINAL, 
 
1053
                        &ret_type, &fmt, &nitems, &bytes_after, 
 
1054
                        (unsigned char **) &data) ==  Success && data) {
 
1055
                flags = *data;
 
1056
                setGnomeState(flags);
 
1057
                XFree (data);
 
1058
        }
 
1059
}
 
1060
 
 
1061
//--------- loadGnomeHintsAtom ---------
 
1062
// Gets the gnome hint from the atom
 
1063
//----------------------------------------
 
1064
void FluxboxWindow::loadGnomeHintsAtom() {
 
1065
        Atom ret_type;
 
1066
        int fmt;
 
1067
        unsigned long nitems, bytes_after;
 
1068
        long *data = 0;
 
1069
        BaseDisplay *bd = screen->getBaseDisplay();
 
1070
        if (XGetWindowProperty (bd->getXDisplay(), getClientWindow(), 
 
1071
                        bd->getGnomeHintsAtom(), 0, 1, False, XA_CARDINAL, 
 
1072
                        &ret_type, &fmt, &nitems, &bytes_after, 
 
1073
                        (unsigned char **) &data) ==  Success && data) {
 
1074
                gnome_hints = static_cast<int>(*data);
 
1075
                #ifdef DEBUG
 
1076
                cerr<<__FILE__<<"("<<__LINE__<<"): gnome hints:0x"<<hex<<gnome_hints<<dec<<endl;
 
1077
                #endif
 
1078
                XFree (data);
 
1079
        }
 
1080
}
 
1081
//---------- loadGnomeLayerAtom ------------
 
1082
// Gets the gnome layer from the atom
 
1083
//------------------------------------------
 
1084
void FluxboxWindow::loadGnomeLayerAtom() {
 
1085
        Atom ret_type;
 
1086
        int fmt;
 
1087
        unsigned long nitems, bytes_after;
 
1088
        long *data = 0;
 
1089
        BaseDisplay *bd = screen->getBaseDisplay();
 
1090
        if (XGetWindowProperty (bd->getXDisplay(), getClientWindow(), 
 
1091
                        bd->getGnomeLayerAtom(), 0, 1, False, XA_CARDINAL, 
 
1092
                        &ret_type, &fmt, &nitems, &bytes_after, 
 
1093
                        (unsigned char **) &data) ==  Success && data) {
 
1094
                setGnomeLayer(static_cast<int>(*data));
 
1095
                #ifdef DEBUG
 
1096
                cerr<<__FILE__<<"("<<__LINE__<<"): gnome hints:0x"<<hex<<*data<<dec<<endl;
 
1097
                #endif
 
1098
                XFree (data);
 
1099
        }
 
1100
}
 
1101
#endif //!GNOME
 
1102
 
 
1103
#ifdef NEWWMSPEC
 
1104
//TODO!! 
 
1105
 
 
1106
void FluxboxWindow::updateNETWMAtoms() {
 
1107
 
 
1108
}
 
1109
 
 
1110
int FluxboxWindow::getNETWMWindowState() {
 
1111
 
 
1112
}
 
1113
 
 
1114
void FluxboxWindow::loadNETWMWorkspaceAtom() {
 
1115
 
 
1116
}
 
1117
 
 
1118
#endif //!NEWWMSPEC
 
1119
 
 
1120
Window FluxboxWindow::findTitleButton(int type) {
 
1121
        for (unsigned int i=0; i<buttonlist.size(); i++) {
 
1122
                if (buttonlist[i].type == type)
 
1123
                        return buttonlist[i].win;
 
1124
        }
 
1125
        return 0;
 
1126
}
 
1127
void FluxboxWindow::stickyButton_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1128
        t->stick();
 
1129
        FluxboxWindow::stickyDraw_cb(t, be->window, false);
 
1130
}
 
1131
 
 
1132
void FluxboxWindow::stickyPressed_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1133
        FluxboxWindow::stickyDraw_cb(t, be->window, true);
 
1134
}
 
1135
 
 
1136
void FluxboxWindow::iconifyButton_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1137
        t->iconify();
 
1138
        FluxboxWindow::iconifyDraw_cb(t, be->window, false);
 
1139
}
 
1140
 
 
1141
void FluxboxWindow::iconifyPressed_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1142
        t->screen->getWorkspace(t->workspace_number)->lowerWindow(t);
 
1143
        FluxboxWindow::iconifyDraw_cb(t, be->window, true);
 
1144
}
 
1145
 
 
1146
void FluxboxWindow::maximizeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1147
 FluxboxWindow::maximizeDraw_cb(t, be->window, false);
 
1148
 t->maximize(be->button); 
 
1149
}
 
1150
 
 
1151
void FluxboxWindow::maximizePressed_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1152
 FluxboxWindow::maximizeDraw_cb(t, be->window, true); 
 
1153
}
 
1154
 
 
1155
void FluxboxWindow::closeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1156
        t->close();
 
1157
        FluxboxWindow::closeDraw_cb(t, be->window, false);
 
1158
}
 
1159
 
 
1160
void FluxboxWindow::closePressed_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1161
        FluxboxWindow::closeDraw_cb(t, be->window, true);
 
1162
}
 
1163
 
 
1164
void FluxboxWindow::shadeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
 
1165
        FluxboxWindow::shadeDraw_cb(t, be->window, false);
 
1166
        t->shade();
 
1167
        if (t->tab)
 
1168
                t->tab->shade();
 
1169
}
 
1170
 
 
1171
void FluxboxWindow::stickyDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
 
1172
        t->drawButtonBase(w, pressed);
 
1173
        if (t->stuck) {
 
1174
                XFillRectangle(t->display, w, 
 
1175
                        ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1176
                        t->screen->getWindowStyle()->b_pic_unfocus_gc),
 
1177
                        t->frame.button_w/2-t->frame.button_w/4, t->frame.button_h/2-t->frame.button_h/4,
 
1178
                        t->frame.button_w/2, t->frame.button_h/2);
 
1179
        } else {
 
1180
                XFillRectangle(t->display, w, 
 
1181
                        ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1182
                        t->screen->getWindowStyle()->b_pic_unfocus_gc),
 
1183
                        t->frame.button_w/2, t->frame.button_h/2,
 
1184
                        t->frame.button_w/5, t->frame.button_h/5);
 
1185
        }
 
1186
}
 
1187
 
 
1188
void FluxboxWindow::iconifyDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
 
1189
        t->drawButtonBase(w, pressed);
 
1190
        XDrawRectangle(t->display, w,
 
1191
                ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1192
                t->screen->getWindowStyle()->b_pic_unfocus_gc),
 
1193
                2, t->frame.button_h - 5, t->frame.button_w - 5, 2);
 
1194
}
 
1195
 
 
1196
void FluxboxWindow::maximizeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
 
1197
        t->drawButtonBase(w, pressed);
 
1198
        XDrawRectangle(t->display, w,
 
1199
                ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1200
                        t->screen->getWindowStyle()->b_pic_unfocus_gc),
 
1201
                        2, 2, t->frame.button_w - 5, t->frame.button_h - 5);
 
1202
        XDrawLine(t->display, w,
 
1203
                        ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1204
                                t->screen->getWindowStyle()->b_pic_unfocus_gc),
 
1205
                        2, 3, t->frame.button_w - 3, 3);
 
1206
}
 
1207
 
 
1208
void FluxboxWindow::closeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
 
1209
        t->drawButtonBase(w, pressed);
 
1210
        XDrawLine(t->display, w,
 
1211
                        ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1212
                                t->screen->getWindowStyle()->b_pic_unfocus_gc), 2, 2,
 
1213
                                t->frame.button_w - 3, t->frame.button_h - 3);
 
1214
        XDrawLine(t->display, w,
 
1215
                        ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
 
1216
                                t->screen->getWindowStyle()->b_pic_unfocus_gc), 2,
 
1217
                                t->frame.button_h - 3,
 
1218
                                t->frame.button_w - 3, 2);
 
1219
}
 
1220
 
 
1221
void FluxboxWindow::shadeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
 
1222
        t->drawButtonBase(w, pressed);
 
1223
}
 
1224
 
 
1225
void FluxboxWindow::grabButton(Display *display, unsigned int button, 
 
1226
                                Window window, Cursor cursor) {
 
1227
 
 
1228
        //numlock
 
1229
        XGrabButton(display, button, Mod1Mask|Mod2Mask, window, True,
 
1230
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1231
                                GrabModeAsync, None, cursor);
 
1232
        //scrolllock
 
1233
        XGrabButton(display, button, Mod1Mask|Mod5Mask, window, True,
 
1234
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1235
                                GrabModeAsync, None, cursor);
 
1236
        
 
1237
        //capslock
 
1238
        XGrabButton(display, button, Mod1Mask|LockMask, window, True,
 
1239
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1240
                                GrabModeAsync, None, cursor);
 
1241
 
 
1242
        //capslock+numlock
 
1243
        XGrabButton(display, Button1, Mod1Mask|LockMask|Mod2Mask, window, True,
 
1244
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1245
                                GrabModeAsync, None, cursor);
 
1246
 
 
1247
        //capslock+scrolllock
 
1248
        XGrabButton(display, button, Mod1Mask|LockMask|Mod5Mask, window, True,
 
1249
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1250
                                GrabModeAsync, None, cursor);
 
1251
        
 
1252
        //capslock+numlock+scrolllock
 
1253
        XGrabButton(display, button, Mod1Mask|LockMask|Mod2Mask|Mod5Mask, window, True,
 
1254
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1255
                                GrabModeAsync, None, cursor);
 
1256
 
 
1257
        //numlock+scrollLock
 
1258
        XGrabButton(display, button, Mod1Mask|Mod2Mask|Mod5Mask, window, True,
 
1259
                                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 
1260
                                GrabModeAsync, None, cursor);
 
1261
        
 
1262
}
 
1263
 
 
1264
void FluxboxWindow::drawButtonBase(Window w, bool pressed) {
 
1265
        if (! pressed) {
 
1266
                if (focused) {
 
1267
                        if (frame.fbutton)
 
1268
                                XSetWindowBackgroundPixmap(display, w, frame.fbutton);
 
1269
                        else
 
1270
                                XSetWindowBackground(display, w, frame.fbutton_pixel);
 
1271
                } else {
 
1272
                        if (frame.ubutton)
 
1273
                                XSetWindowBackgroundPixmap(display, w, frame.ubutton);
 
1274
                        else
 
1275
                                XSetWindowBackground(display, w, frame.ubutton_pixel);
 
1276
                }
 
1277
        } else {
 
1278
                if (frame.pbutton)
 
1279
                        XSetWindowBackgroundPixmap(display, w, frame.pbutton);
 
1280
                else
 
1281
                        XSetWindowBackground(display, w, frame.pbutton_pixel);
 
1282
        }
 
1283
        XClearWindow(display, w);
 
1284
 
 
1285
}
 
1286
 
 
1287
void FluxboxWindow::positionButtons(bool redecorate_label) {
 
1288
        unsigned int bw = frame.button_w + frame.bevel_w + 1,
 
1289
                by = frame.bevel_w + 1, lx = by, lw = frame.width - by; 
 
1290
        Fluxbox *fluxbox = Fluxbox::instance();
 
1291
        vector<Fluxbox::Titlebar> left = fluxbox->getTitlebarLeft();
 
1292
        vector<Fluxbox::Titlebar> right = fluxbox->getTitlebarRight();
 
1293
 
 
1294
        //left side buttons
 
1295
        for (unsigned int i=0; i<left.size(); i++) {
 
1296
                Window w = findTitleButton(left[i]);    //get Window of button
 
1297
                if (w) {
 
1298
                        XMoveResizeWindow(display, w, lx, by,
 
1299
                                        frame.button_w, frame.button_h);
 
1300
                        XMapWindow(display, w);
 
1301
                        XClearWindow(display, w);
 
1302
                        lx += bw;
 
1303
                        lw -= bw;
 
1304
                }               
 
1305
        }
 
1306
        
 
1307
        int bx = frame.width - bw;
 
1308
 
 
1309
        //right side buttons
 
1310
        for (int i=right.size()-1; i>=0; i--) {
 
1311
                Window w = findTitleButton(right[i]);   //get window of button
 
1312
                if (w) {
 
1313
                        XMoveResizeWindow(display, w, bx, by,
 
1314
                                        frame.button_w, frame.button_h);
 
1315
                        XMapWindow(display, w);
 
1316
                        XClearWindow(display, w);
 
1317
                        bx -= bw;
 
1318
                        lw -= bw;
 
1319
                }
 
1320
        }
 
1321
        
 
1322
        //Draw the label
 
1323
        frame.label_w = lw - by;
 
1324
        XMoveResizeWindow(display, frame.label, lx, frame.bevel_w,
 
1325
                frame.label_w, frame.label_h);
 
1326
        if (redecorate_label) 
 
1327
                decorateLabel();
 
1328
        if (tab) {
 
1329
                tab->setPosition();
 
1330
                tab->draw(false);
 
1331
        }
 
1332
        redrawLabel();
 
1333
        redrawAllButtons();
 
1334
}
 
1335
 
 
1336
 
 
1337
void FluxboxWindow::reconfigure(void) {
 
1338
        upsize();
 
1339
        
 
1340
        if (Fluxbox::instance()->useTabs()) {
 
1341
                //no tab and we allowed to use tab? then create it 
 
1342
                if (!tab && decorations.tab) {                  
 
1343
                        tab = new Tab(this, 0, 0);              
 
1344
                        if (current_state == IconicState)
 
1345
                                tab->iconify();
 
1346
                        else if (current_state == WithdrawnState)
 
1347
                                tab->withdraw();
 
1348
                }
 
1349
        }       else {          
 
1350
                if (tab) { //got a tab? then destroy it
 
1351
                        delete tab;
 
1352
                        tab=0;
 
1353
                }
 
1354
        }
 
1355
        
 
1356
        client.x = frame.x + frame.mwm_border_w + screen->getBorderWidth();
 
1357
        client.y = frame.y + frame.y_border + frame.mwm_border_w +
 
1358
                         screen->getBorderWidth();
 
1359
 
 
1360
        if (client.title) {
 
1361
                if (I18n::instance()->multibyte()) {
 
1362
                        XRectangle ink, logical;
 
1363
                        XmbTextExtents(screen->getWindowStyle()->font.set,
 
1364
                                        client.title, client.title_len, &ink, &logical);
 
1365
                        client.title_text_w = logical.width;
 
1366
                } else {
 
1367
                        client.title_text_w = XTextWidth(screen->getWindowStyle()->font.fontstruct,
 
1368
                                        client.title, client.title_len);
 
1369
                }
 
1370
 
 
1371
                client.title_text_w += (frame.bevel_w * 4);
 
1372
        }
 
1373
 
 
1374
                
 
1375
        positionWindows();
 
1376
        decorate();
 
1377
 
 
1378
                                
 
1379
        XClearWindow(display, frame.window);
 
1380
        setFocusFlag(focused);
 
1381
 
 
1382
        configure(frame.x, frame.y, frame.width, frame.height);
 
1383
 
 
1384
        if (! (screen->isSloppyFocus() || screen->isSemiSloppyFocus())) {
 
1385
                XGrabButton(display, Button1, AnyModifier, frame.plate, True, ButtonPressMask,
 
1386
                                GrabModeSync, GrabModeSync, None, None);
 
1387
                XUngrabButton(display, Button1, Mod1Mask|Mod2Mask|Mod3Mask, frame.plate);
 
1388
        } else          
 
1389
                XUngrabButton(display, Button1, AnyModifier, frame.plate);
 
1390
 
 
1391
        if (windowmenu) {
 
1392
                windowmenu->move(windowmenu->getX(), frame.y + frame.title_h);
 
1393
                windowmenu->reconfigure();
 
1394
        }
 
1395
                
 
1396
        
 
1397
}
 
1398
 
 
1399
 
 
1400
void FluxboxWindow::positionWindows(void) {
 
1401
        XResizeWindow(display, frame.window, frame.width,
 
1402
                                                        ((shaded) ? frame.title_h : frame.height));
 
1403
        XSetWindowBorderWidth(display, frame.window, screen->getBorderWidth());
 
1404
        XSetWindowBorderWidth(display, frame.plate, screen->getFrameWidth() *
 
1405
                        decorations.border);
 
1406
        XMoveResizeWindow(display, frame.plate, 0, frame.y_border,
 
1407
                                                                client.width, client.height);
 
1408
        XMoveResizeWindow(display, client.window, 0, 0, client.width, client.height);
 
1409
 
 
1410
        if (decorations.titlebar) {
 
1411
                XSetWindowBorderWidth(display, frame.title, screen->getBorderWidth());
 
1412
                XMoveResizeWindow(display, frame.title, -screen->getBorderWidth(),
 
1413
                                        -screen->getBorderWidth(), frame.width, frame.title_h);
 
1414
 
 
1415
                positionButtons();
 
1416
        } else if (frame.title)
 
1417
                XUnmapWindow(display, frame.title);
 
1418
 
 
1419
        if (decorations.handle) {
 
1420
                XSetWindowBorderWidth(display, frame.handle, screen->getBorderWidth());
 
1421
                XSetWindowBorderWidth(display, frame.left_grip, screen->getBorderWidth());
 
1422
                XSetWindowBorderWidth(display, frame.right_grip, screen->getBorderWidth());
 
1423
 
 
1424
                XMoveResizeWindow(display, frame.handle, -screen->getBorderWidth(),
 
1425
                        frame.y_handle - screen->getBorderWidth(),
 
1426
                        frame.width, frame.handle_h);
 
1427
                XMoveResizeWindow(display, frame.left_grip, -screen->getBorderWidth(),
 
1428
                        -screen->getBorderWidth(), frame.grip_w, frame.grip_h);
 
1429
                XMoveResizeWindow(display, frame.right_grip,
 
1430
                        frame.width - frame.grip_w - screen->getBorderWidth(),
 
1431
                        -screen->getBorderWidth(), frame.grip_w, frame.grip_h);
 
1432
                XMapSubwindows(display, frame.handle);
 
1433
        } else if (frame.handle)
 
1434
                XUnmapWindow(display, frame.handle);
 
1435
        if (tab)
 
1436
                tab->setPosition();
 
1437
}
 
1438
 
 
1439
 
 
1440
void FluxboxWindow::getWMName(void) {
 
1441
        if (client.title) {
 
1442
                delete [] client.title;
 
1443
                client.title = 0;
 
1444
        }
 
1445
 
 
1446
        XTextProperty text_prop;
 
1447
        char **list;
 
1448
        int num;
 
1449
        I18n *i18n = I18n::instance();
 
1450
        
 
1451
        if (XGetWMName(display, client.window, &text_prop)) {
 
1452
                if (text_prop.value && text_prop.nitems > 0) {
 
1453
                        if (text_prop.encoding != XA_STRING) {
 
1454
                                
 
1455
                                text_prop.nitems = strlen((char *) text_prop.value);
 
1456
                                
 
1457
                                if ((XmbTextPropertyToTextList(display, &text_prop,
 
1458
                                                        &list, &num) == Success) &&
 
1459
                                                (num > 0) && *list) {
 
1460
                                        client.title = StringUtil::strdup(*list);
 
1461
                                        XFreeStringList(list);
 
1462
                                } else
 
1463
                                        client.title = StringUtil::strdup((char *) text_prop.value);
 
1464
                                        
 
1465
                        } else
 
1466
                                client.title = StringUtil::strdup((char *) text_prop.value);
 
1467
 
 
1468
                        XFree((char *) text_prop.value);
 
1469
                } else
 
1470
                        client.title = StringUtil::strdup(i18n->getMessage(
 
1471
#ifdef          NLS
 
1472
                                                                        WindowSet, WindowUnnamed,
 
1473
#else // !NLS
 
1474
                                                                        0, 0,
 
1475
#endif //
 
1476
                                                                        "Unnamed"));
 
1477
        } else {
 
1478
                client.title = StringUtil::strdup(i18n->getMessage(
 
1479
#ifdef          NLS
 
1480
                                                        WindowSet, WindowUnnamed,
 
1481
#else // !NLS
 
1482
                                                        0, 0,
 
1483
#endif //
 
1484
                                                        "Unnamed"));
 
1485
        }
 
1486
        
 
1487
        client.title_len = strlen(client.title);
 
1488
 
 
1489
        if (i18n->multibyte()) {
 
1490
                XRectangle ink, logical;
 
1491
                XmbTextExtents(screen->getWindowStyle()->font.set,
 
1492
                                client.title, client.title_len, &ink, &logical);
 
1493
                client.title_text_w = logical.width;
 
1494
        } else {
 
1495
                client.title_len = strlen(client.title);
 
1496
                client.title_text_w = XTextWidth(screen->getWindowStyle()->font.fontstruct,
 
1497
                                                        client.title, client.title_len);
 
1498
        }
 
1499
 
 
1500
        client.title_text_w += (frame.bevel_w * 4);
 
1501
}
 
1502
 
 
1503
 
 
1504
void FluxboxWindow::getWMIconName(void) {
 
1505
        if (client.icon_title) {
 
1506
                delete [] client.icon_title;
 
1507
                client.icon_title = (char *) 0;
 
1508
        }
 
1509
 
 
1510
        XTextProperty text_prop;
 
1511
        char **list;
 
1512
        int num;
 
1513
 
 
1514
        if (XGetWMIconName(display, client.window, &text_prop)) {
 
1515
                if (text_prop.value && text_prop.nitems > 0) {
 
1516
                        if (text_prop.encoding != XA_STRING) {
 
1517
                                text_prop.nitems = strlen((char *) text_prop.value);
 
1518
 
 
1519
                                if ((XmbTextPropertyToTextList(display, &text_prop,
 
1520
                                                &list, &num) == Success) &&
 
1521
                                                (num > 0) && *list) {
 
1522
                                        client.icon_title = StringUtil::strdup(*list);
 
1523
                                        XFreeStringList(list);
 
1524
                                } else
 
1525
                                        client.icon_title = StringUtil::strdup((char *) text_prop.value);
 
1526
                        } else
 
1527
                                client.icon_title = StringUtil::strdup((char *) text_prop.value);
 
1528
 
 
1529
                        XFree((char *) text_prop.value);
 
1530
                } else
 
1531
                                client.icon_title = StringUtil::strdup(client.title);
 
1532
        } else
 
1533
                client.icon_title = StringUtil::strdup(client.title);
 
1534
}
 
1535
 
 
1536
 
 
1537
void FluxboxWindow::getWMProtocols(void) {
 
1538
        Atom *proto;
 
1539
        int num_return = 0;
 
1540
        Fluxbox *fluxbox = Fluxbox::instance();
 
1541
        
 
1542
        if (XGetWMProtocols(display, client.window, &proto, &num_return)) {
 
1543
                for (int i = 0; i < num_return; ++i) {
 
1544
                        if (proto[i] == fluxbox->getWMDeleteAtom())
 
1545
                                functions.close = decorations.close = true;
 
1546
                        else if (proto[i] == fluxbox->getWMTakeFocusAtom())
 
1547
                                send_focus_message = true;
 
1548
                        else if (proto[i] == fluxbox->getFluxboxStructureMessagesAtom())
 
1549
                                screen->addNetizen(new Netizen(screen, client.window));
 
1550
                }
 
1551
 
 
1552
                XFree(proto);
 
1553
        }
 
1554
}
 
1555
 
 
1556
 
 
1557
void FluxboxWindow::getWMHints(void) {
 
1558
        XWMHints *wmhint = XGetWMHints(display, client.window);
 
1559
        if (! wmhint) {
 
1560
                visible = true;
 
1561
                iconic = false;
 
1562
                focus_mode = F_PASSIVE;
 
1563
                client.window_group = None;
 
1564
                client.initial_state = NormalState;
 
1565
        } else {
 
1566
                client.wm_hint_flags = wmhint->flags;
 
1567
                if (wmhint->flags & InputHint) {
 
1568
                        if (wmhint->input == true) {
 
1569
                                if (send_focus_message)
 
1570
                                        focus_mode = F_LOCALLYACTIVE;
 
1571
                                else
 
1572
                                        focus_mode = F_PASSIVE;
 
1573
                        } else {
 
1574
                                if (send_focus_message)
 
1575
                                        focus_mode = F_GLOBALLYACTIVE;
 
1576
                                else
 
1577
                                        focus_mode = F_NOINPUT;
 
1578
                        }
 
1579
                } else
 
1580
                        focus_mode = F_PASSIVE;
 
1581
 
 
1582
                if (wmhint->flags & StateHint)
 
1583
                        client.initial_state = wmhint->initial_state;
 
1584
                else
 
1585
                        client.initial_state = NormalState;
 
1586
 
 
1587
                if (wmhint->flags & WindowGroupHint) {
 
1588
                        if (! client.window_group) {
 
1589
                                client.window_group = wmhint->window_group;
 
1590
                                Fluxbox::instance()->saveGroupSearch(client.window_group, this);
 
1591
                        }
 
1592
                } else
 
1593
                        client.window_group = None;
 
1594
 
 
1595
                XFree(wmhint);
 
1596
        }
 
1597
}
 
1598
 
 
1599
 
 
1600
void FluxboxWindow::getWMNormalHints(void) {
 
1601
        long icccm_mask;
 
1602
        XSizeHints sizehint;
 
1603
        if (! XGetWMNormalHints(display, client.window, &sizehint, &icccm_mask)) {
 
1604
                client.min_width = client.min_height =
 
1605
                        client.base_width = client.base_height =
 
1606
                        client.width_inc = client.height_inc = 1;
 
1607
                client.max_width = screen->getWidth();
 
1608
                client.max_height = screen->getHeight();
 
1609
                client.min_aspect_x = client.min_aspect_y =
 
1610
                        client.max_aspect_x = client.max_aspect_y = 1;
 
1611
                client.win_gravity = NorthWestGravity;
 
1612
        } else {
 
1613
                client.normal_hint_flags = sizehint.flags;
 
1614
 
 
1615
                if (sizehint.flags & PMinSize) {
 
1616
                        client.min_width = sizehint.min_width;
 
1617
                        client.min_height = sizehint.min_height;
 
1618
                } else
 
1619
                        client.min_width = client.min_height = 1;
 
1620
 
 
1621
                if (sizehint.flags & PMaxSize) {
 
1622
                        client.max_width = sizehint.max_width;
 
1623
                        client.max_height = sizehint.max_height;
 
1624
                } else {
 
1625
                        client.max_width = screen->getWidth();
 
1626
                        client.max_height = screen->getHeight();
 
1627
                }
 
1628
 
 
1629
                if (sizehint.flags & PResizeInc) {
 
1630
                        client.width_inc = sizehint.width_inc;
 
1631
                        client.height_inc = sizehint.height_inc;
 
1632
                } else
 
1633
                        client.width_inc = client.height_inc = 1;
 
1634
 
 
1635
                if (sizehint.flags & PAspect) {
 
1636
                        client.min_aspect_x = sizehint.min_aspect.x;
 
1637
                        client.min_aspect_y = sizehint.min_aspect.y;
 
1638
                        client.max_aspect_x = sizehint.max_aspect.x;
 
1639
                        client.max_aspect_y = sizehint.max_aspect.y;
 
1640
                } else
 
1641
                        client.min_aspect_x = client.min_aspect_y =
 
1642
                                client.max_aspect_x = client.max_aspect_y = 1;
 
1643
 
 
1644
                if (sizehint.flags & PBaseSize) {
 
1645
                        client.base_width = sizehint.base_width;
 
1646
                        client.base_height = sizehint.base_height;
 
1647
                } else
 
1648
                        client.base_width = client.base_height = 0;
 
1649
 
 
1650
                if (sizehint.flags & PWinGravity)
 
1651
                        client.win_gravity = sizehint.win_gravity;
 
1652
                else
 
1653
                        client.win_gravity = NorthWestGravity;
 
1654
        }
 
1655
}
 
1656
 
 
1657
 
 
1658
void FluxboxWindow::getMWMHints(void) {
 
1659
        int format;
 
1660
        Atom atom_return;
 
1661
        unsigned long num, len;
 
1662
        Fluxbox *fluxbox = Fluxbox::instance();
 
1663
        if (XGetWindowProperty(display, client.window,
 
1664
                        fluxbox->getMotifWMHintsAtom(), 0,
 
1665
                        PropMwmHintsElements, false,
 
1666
                        fluxbox->getMotifWMHintsAtom(), &atom_return,
 
1667
                         &format, &num, &len,
 
1668
                        (unsigned char **) &client.mwm_hint) == Success &&
 
1669
                        client.mwm_hint)
 
1670
                if (num == PropMwmHintsElements) {
 
1671
                        if (client.mwm_hint->flags & MwmHintsDecorations)
 
1672
                                if (client.mwm_hint->decorations & MwmDecorAll)
 
1673
                                        decorations.titlebar = decorations.handle = decorations.border =
 
1674
                                                decorations.iconify = decorations.maximize =
 
1675
                                                decorations.close = decorations.menu = true;
 
1676
                                else {
 
1677
                                        decorations.titlebar = decorations.handle = decorations.border =
 
1678
                                                decorations.iconify = decorations.maximize =
 
1679
                                                decorations.close = decorations.menu = decorations.tab = false;
 
1680
 
 
1681
                                        if (client.mwm_hint->decorations & MwmDecorBorder)
 
1682
                                                decorations.border = true;
 
1683
                                        if (client.mwm_hint->decorations & MwmDecorHandle)
 
1684
                                                decorations.handle = true;
 
1685
                                        if (client.mwm_hint->decorations & MwmDecorTitle)
 
1686
                                                decorations.titlebar = decorations.tab = true; //only tab on windows with titlebar
 
1687
                                        if (client.mwm_hint->decorations & MwmDecorMenu)
 
1688
                                                decorations.menu = true;
 
1689
                                        if (client.mwm_hint->decorations & MwmDecorIconify)
 
1690
                                                decorations.iconify = true;
 
1691
                                        if (client.mwm_hint->decorations & MwmDecorMaximize)
 
1692
                                                decorations.maximize = true;
 
1693
                                }
 
1694
 
 
1695
                        if (client.mwm_hint->flags & MwmHintsFunctions)
 
1696
                                if (client.mwm_hint->functions & MwmFuncAll) {
 
1697
                                        functions.resize = functions.move = functions.iconify =
 
1698
                                                functions.maximize = functions.close = true;
 
1699
                                } else {
 
1700
                                        functions.resize = functions.move = functions.iconify =
 
1701
                                                functions.maximize = functions.close = false;
 
1702
 
 
1703
                                        if (client.mwm_hint->functions & MwmFuncResize)
 
1704
                                                functions.resize = true;
 
1705
                                        if (client.mwm_hint->functions & MwmFuncMove)
 
1706
                                                functions.move = true;
 
1707
                                        if (client.mwm_hint->functions & MwmFuncIconify)
 
1708
                                                functions.iconify = true;
 
1709
                                        if (client.mwm_hint->functions & MwmFuncMaximize)
 
1710
                                                functions.maximize = true;
 
1711
                                        if (client.mwm_hint->functions & MwmFuncClose)
 
1712
                                                functions.close = true;
 
1713
                                }
 
1714
                }
 
1715
}
 
1716
 
 
1717
 
 
1718
void FluxboxWindow::getBlackboxHints(void) {
 
1719
        int format;
 
1720
        Atom atom_return;
 
1721
        unsigned long num, len;
 
1722
        Fluxbox *fluxbox = Fluxbox::instance();
 
1723
        
 
1724
        if (XGetWindowProperty(display, client.window,
 
1725
                                                                                                 fluxbox->getFluxboxHintsAtom(), 0,
 
1726
                                                                                                 PropBlackboxHintsElements, false,
 
1727
                                                                                                 fluxbox->getFluxboxHintsAtom(), &atom_return,
 
1728
                                                                                                 &format, &num, &len,
 
1729
                                                                                                 (unsigned char **) &client.blackbox_hint) == Success &&
 
1730
                        client.blackbox_hint)
 
1731
                if (num == PropBlackboxHintsElements) {
 
1732
                        if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_SHADED)
 
1733
                                shaded = (client.blackbox_hint->attrib & BaseDisplay::ATTRIB_SHADED);
 
1734
 
 
1735
                        if ((client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ) &&
 
1736
                                        (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT))
 
1737
                                maximized = ((client.blackbox_hint->attrib &
 
1738
                                                                                        (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ? 1 : 0);
 
1739
                        else if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT)
 
1740
                                maximized = ((client.blackbox_hint->attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
 
1741
                        else if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ)
 
1742
                                maximized = ((client.blackbox_hint->attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
 
1743
 
 
1744
                        if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_OMNIPRESENT)
 
1745
                                stuck = (client.blackbox_hint->attrib & BaseDisplay::ATTRIB_OMNIPRESENT);
 
1746
 
 
1747
                        if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_WORKSPACE)
 
1748
                                workspace_number = client.blackbox_hint->workspace;
 
1749
 
 
1750
 
 
1751
                        if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_DECORATION) {
 
1752
                                switch (client.blackbox_hint->decoration) {
 
1753
                                case BaseDisplay::DECOR_NONE:
 
1754
                                        decorations.titlebar = decorations.border = decorations.handle =
 
1755
                                                decorations.iconify = decorations.maximize =
 
1756
                                                decorations.menu = decorations.tab = false; //tab is also a decor
 
1757
                                        functions.resize = functions.move = functions.iconify =
 
1758
                                                functions.maximize = false;
 
1759
 
 
1760
                                        break;
 
1761
 
 
1762
                                default:
 
1763
                                case BaseDisplay::DECOR_NORMAL:
 
1764
                                        decorations.titlebar = decorations.border = decorations.handle =
 
1765
                                                decorations.iconify = decorations.maximize =
 
1766
                                                decorations.menu = true;
 
1767
                                        functions.resize = functions.move = functions.iconify =
 
1768
                                                functions.maximize = true;
 
1769
 
 
1770
                                        break;
 
1771
 
 
1772
                                case BaseDisplay::DECOR_TINY:
 
1773
                                        decorations.titlebar = decorations.iconify = decorations.menu =
 
1774
                                                functions.move = functions.iconify = true;
 
1775
                                        decorations.border = decorations.handle = decorations.maximize =
 
1776
                                                functions.resize = functions.maximize = false;
 
1777
 
 
1778
                                        break;
 
1779
 
 
1780
                                case BaseDisplay::DECOR_TOOL:
 
1781
                                        decorations.titlebar = decorations.menu = functions.move = true;
 
1782
                                        decorations.iconify = decorations.border = decorations.handle =
 
1783
                                                decorations.maximize = functions.resize = functions.maximize =
 
1784
                                                functions.iconify = false;
 
1785
 
 
1786
                                        break;
 
1787
                                }
 
1788
 
 
1789
                                reconfigure();
 
1790
                        }
 
1791
                }
 
1792
}
 
1793
 
 
1794
 
 
1795
void FluxboxWindow::configure(int dx, int dy,
 
1796
                                                         unsigned int dw, unsigned int dh) {
 
1797
        //we don't want negative size
 
1798
        if (dw <0 || dh<0)
 
1799
                return;
 
1800
 
 
1801
        bool send_event = (frame.x != dx || frame.y != dy);
 
1802
 
 
1803
        if ((dw != frame.width) || (dh != frame.height)) {
 
1804
                if ((((signed) frame.width) + dx) < 0) dx = 0;
 
1805
                if ((((signed) frame.height) + dy) < 0) dy = 0;
 
1806
 
 
1807
                frame.x = dx;
 
1808
                frame.y = dy;
 
1809
                frame.width = dw;
 
1810
                frame.height = dh;
 
1811
 
 
1812
                downsize();
 
1813
 
 
1814
#ifdef          SHAPE
 
1815
                if (Fluxbox::instance()->hasShapeExtensions() && frame.shaped) {
 
1816
                        XShapeCombineShape(display, frame.window, ShapeBounding,
 
1817
                                                 frame.mwm_border_w, frame.y_border +
 
1818
                         frame.mwm_border_w, client.window,
 
1819
                         ShapeBounding, ShapeSet);
 
1820
 
 
1821
                        int num = 1;
 
1822
                        XRectangle xrect[2];
 
1823
                        xrect[0].x = xrect[0].y = 0;
 
1824
                        xrect[0].width = frame.width;
 
1825
                        xrect[0].height = frame.y_border;
 
1826
 
 
1827
                        if (decorations.handle) {
 
1828
                                xrect[1].x = 0;
 
1829
                                xrect[1].y = frame.y_handle;
 
1830
                                xrect[1].width = frame.width;
 
1831
                                xrect[1].height = frame.handle_h + screen->getBorderWidth();
 
1832
                                num++;
 
1833
                        }
 
1834
 
 
1835
                        XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
 
1836
                                                xrect, num, ShapeUnion, Unsorted);
 
1837
                }
 
1838
#endif // SHAPE
 
1839
 
 
1840
                XMoveResizeWindow(display, frame.window, frame.x, frame.y,
 
1841
                                                        frame.width, frame.height);
 
1842
                positionWindows();
 
1843
                decorate();
 
1844
                setFocusFlag(focused);
 
1845
                redrawAllButtons();
 
1846
                shaded = false;
 
1847
        } else {
 
1848
                frame.x = dx;
 
1849
                frame.y = dy;
 
1850
 
 
1851
                XMoveWindow(display, frame.window, frame.x, frame.y);
 
1852
                //move the tab and the chain            
 
1853
                if (tab)
 
1854
                        tab->setPosition();
 
1855
                
 
1856
                if (! moving) send_event = true;
 
1857
        }
 
1858
 
 
1859
        if (send_event && ! moving) {
 
1860
                client.x = dx + frame.mwm_border_w + screen->getBorderWidth();
 
1861
                client.y = dy + frame.y_border + frame.mwm_border_w +
 
1862
                        screen->getBorderWidth();
 
1863
 
 
1864
                XEvent event;
 
1865
                event.type = ConfigureNotify;
 
1866
 
 
1867
                event.xconfigure.display = display;
 
1868
                event.xconfigure.event = client.window;
 
1869
                event.xconfigure.window = client.window;
 
1870
                event.xconfigure.x = client.x;
 
1871
                event.xconfigure.y = client.y;
 
1872
                event.xconfigure.width = client.width;
 
1873
                event.xconfigure.height = client.height;
 
1874
                event.xconfigure.border_width = client.old_bw;
 
1875
                event.xconfigure.above = frame.window;
 
1876
                event.xconfigure.override_redirect = false;
 
1877
 
 
1878
                XSendEvent(display, client.window, True, NoEventMask, &event);
 
1879
 
 
1880
                screen->updateNetizenConfigNotify(&event);
 
1881
        }
 
1882
}
 
1883
 
 
1884
 
 
1885
bool FluxboxWindow::setInputFocus(void) {
 
1886
        #ifdef GNOME
 
1887
        if (gnome_hints & WIN_HINTS_SKIP_FOCUS)
 
1888
                return false;
 
1889
        #endif
 
1890
        if (((signed) (frame.x + frame.width)) < 0) {
 
1891
                if (((signed) (frame.y + frame.y_border)) < 0)
 
1892
                        configure(screen->getBorderWidth(), screen->getBorderWidth(),
 
1893
                                                                frame.width, frame.height);
 
1894
                else if (frame.y > (signed) screen->getHeight())
 
1895
                        configure(screen->getBorderWidth(), screen->getHeight() - frame.height,
 
1896
                                                                frame.width, frame.height);
 
1897
                else
 
1898
                        configure(screen->getBorderWidth(), frame.y + screen->getBorderWidth(),
 
1899
                                                                frame.width, frame.height);
 
1900
        } else if (frame.x > (signed) screen->getWidth()) {
 
1901
                if (((signed) (frame.y + frame.y_border)) < 0)
 
1902
                        configure(screen->getWidth() - frame.width, screen->getBorderWidth(),
 
1903
                                                                frame.width, frame.height);
 
1904
                else if (frame.y > (signed) screen->getHeight())
 
1905
                        configure(screen->getWidth() - frame.width,
 
1906
                                        screen->getHeight() - frame.height, frame.width, frame.height);
 
1907
                else
 
1908
                        configure(screen->getWidth() - frame.width,
 
1909
                                                                frame.y + screen->getBorderWidth(), frame.width, frame.height);
 
1910
        }
 
1911
 
 
1912
        Fluxbox *fluxbox = Fluxbox::instance();
 
1913
        BaseDisplay::GrabGuard gg(*fluxbox);
 
1914
        fluxbox->grab();
 
1915
        if (! validateClient()) return false;
 
1916
 
 
1917
        bool ret = false;
 
1918
 
 
1919
        if (client.transient && modal)
 
1920
                ret = client.transient->setInputFocus();
 
1921
        else {
 
1922
                if (! focused) {
 
1923
                        if (focus_mode == F_LOCALLYACTIVE || focus_mode == F_PASSIVE)
 
1924
                                XSetInputFocus(display, client.window,
 
1925
                                                                                        RevertToPointerRoot, CurrentTime);
 
1926
                        else
 
1927
                                XSetInputFocus(display, screen->getRootWindow(),
 
1928
                                                                                        RevertToNone, CurrentTime);
 
1929
 
 
1930
                        fluxbox->setFocusedWindow(this);
 
1931
                        
 
1932
                        if (send_focus_message) {
 
1933
                                XEvent ce;
 
1934
                                ce.xclient.type = ClientMessage;
 
1935
                                ce.xclient.message_type = fluxbox->getWMProtocolsAtom();
 
1936
                                ce.xclient.display = display;
 
1937
                                ce.xclient.window = client.window;
 
1938
                                ce.xclient.format = 32;
 
1939
                                ce.xclient.data.l[0] = fluxbox->getWMTakeFocusAtom();
 
1940
                                ce.xclient.data.l[1] = fluxbox->getLastTime();
 
1941
                                ce.xclient.data.l[2] = 0l;
 
1942
                                ce.xclient.data.l[3] = 0l;
 
1943
                                ce.xclient.data.l[4] = 0l;
 
1944
                                XSendEvent(display, client.window, false, NoEventMask, &ce);
 
1945
                        }
 
1946
 
 
1947
                        if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus())
 
1948
                                        && screen->doAutoRaise())
 
1949
                                timer->start();
 
1950
 
 
1951
                        ret = true;
 
1952
                }
 
1953
        }
 
1954
 
 
1955
        fluxbox->ungrab();
 
1956
 
 
1957
        return ret;
 
1958
}
 
1959
 
 
1960
//------------ setTab --------------
 
1961
// Enables or disables the tab on the window
 
1962
//----------------------------------
 
1963
void FluxboxWindow::setTab(bool flag) {
 
1964
        if (flag) {
 
1965
                if (!tab)
 
1966
                        tab = new Tab(this, 0, 0);
 
1967
                tab->focus(); // draws the tab with correct texture
 
1968
                tab->setPosition(); // set tab windows position
 
1969
 
 
1970
        } else if (tab) {
 
1971
                delete tab;
 
1972
                tab = 0;                
 
1973
        }       
 
1974
        decorations.tab = flag;
 
1975
}
 
1976
 
 
1977
//------------- iconify ----------------
 
1978
// Unmaps the window and removes it from workspace list
 
1979
//--------------------------------------
 
1980
void FluxboxWindow::iconify(void) {
 
1981
 
 
1982
        if (iconic)
 
1983
                return;
 
1984
 
 
1985
        if (windowmenu)
 
1986
                windowmenu->hide();
 
1987
 
 
1988
        setState(IconicState);
 
1989
 
 
1990
        XSelectInput(display, client.window, NoEventMask);
 
1991
        XUnmapWindow(display, client.window);
 
1992
        XSelectInput(display, client.window,
 
1993
                                        PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
 
1994
 
 
1995
        XUnmapWindow(display, frame.window);
 
1996
        visible = false;
 
1997
        iconic = true;
 
1998
        
 
1999
        screen->getWorkspace(workspace_number)->removeWindow(this);
 
2000
 
 
2001
        if (transient && client.transient_for) {
 
2002
                if (! client.transient_for->iconic)
 
2003
                        client.transient_for->iconify();
 
2004
        }
 
2005
        screen->addIcon(this);
 
2006
 
 
2007
        if (tab) //if this window got a tab then iconify it too
 
2008
                tab->iconify();
 
2009
                
 
2010
        if (client.transient) {
 
2011
                if (! client.transient->iconic)
 
2012
                        client.transient->iconify();
 
2013
        }
 
2014
}
 
2015
 
 
2016
 
 
2017
void FluxboxWindow::deiconify(bool reassoc, bool raise) {
 
2018
        if (iconic || reassoc)
 
2019
                screen->reassociateWindow(this, -1, false);
 
2020
        else if (workspace_number != screen->getCurrentWorkspace()->getWorkspaceID())
 
2021
                return;
 
2022
 
 
2023
        setState(NormalState);
 
2024
 
 
2025
        XSelectInput(display, client.window, NoEventMask);
 
2026
        XMapWindow(display, client.window);
 
2027
        XSelectInput(display, client.window,
 
2028
                PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
 
2029
 
 
2030
        XMapSubwindows(display, frame.window);
 
2031
        XMapWindow(display, frame.window);
 
2032
 
 
2033
        if (iconic && screen->doFocusNew()) setInputFocus();
 
2034
 
 
2035
        visible = true;
 
2036
        iconic = false;
 
2037
 
 
2038
        if (reassoc && client.transient) client.transient->deiconify(true, false);
 
2039
        
 
2040
        if (tab)
 
2041
                tab->deiconify();
 
2042
                        
 
2043
        if (raise) {            
 
2044
                screen->getWorkspace(workspace_number)->raiseWindow(this);
 
2045
                if (tab)
 
2046
                        tab->raise();
 
2047
        }
 
2048
}
 
2049
 
 
2050
 
 
2051
void FluxboxWindow::close(void) {
 
2052
        Fluxbox *fluxbox = Fluxbox::instance();
 
2053
        XEvent ce;
 
2054
        ce.xclient.type = ClientMessage;
 
2055
        ce.xclient.message_type = fluxbox->getWMProtocolsAtom();
 
2056
        ce.xclient.display = display;
 
2057
        ce.xclient.window = client.window;
 
2058
        ce.xclient.format = 32;
 
2059
        ce.xclient.data.l[0] = fluxbox->getWMDeleteAtom();
 
2060
        ce.xclient.data.l[1] = CurrentTime;
 
2061
        ce.xclient.data.l[2] = 0l;
 
2062
        ce.xclient.data.l[3] = 0l;
 
2063
        ce.xclient.data.l[4] = 0l;
 
2064
        XSendEvent(display, client.window, false, NoEventMask, &ce);
 
2065
}
 
2066
 
 
2067
 
 
2068
void FluxboxWindow::withdraw(void) {
 
2069
        visible = false;
 
2070
        iconic = false;
 
2071
 
 
2072
        XUnmapWindow(display, frame.window);
 
2073
 
 
2074
        XSelectInput(display, client.window, NoEventMask);
 
2075
        XUnmapWindow(display, client.window);
 
2076
        XSelectInput(display, client.window,
 
2077
                                PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
 
2078
 
 
2079
        if (windowmenu)
 
2080
                windowmenu->hide();
 
2081
        
 
2082
        if (tab)
 
2083
                tab->withdraw();
 
2084
}
 
2085
 
 
2086
 
 
2087
void FluxboxWindow::maximize(unsigned int button) {
 
2088
        if (! maximized) {
 
2089
                int dx, dy;
 
2090
                unsigned int dw, dh, slitModL = 0, slitModR = 0, slitModT = 0, slitModB = 0;
 
2091
#ifdef  SLIT
 
2092
                Slit* mSlt = screen->getSlit();
 
2093
 
 
2094
                if(!screen->doMaxOverSlit() && !screen->doFullMax() && (mSlt->getWidth() > 1))
 
2095
                {
 
2096
                        switch(screen->getSlitDirection())
 
2097
                        {
 
2098
                        case Slit::VERTICAL:
 
2099
                                switch(screen->getSlitPlacement())
 
2100
                                {
 
2101
                                case Slit::TOPRIGHT:
 
2102
                                case Slit::CENTERRIGHT:
 
2103
                                case Slit::BOTTOMRIGHT:
 
2104
                                        slitModR = mSlt->getWidth() + screen->getBevelWidth();
 
2105
                                        break;
 
2106
                                default:
 
2107
                                        slitModL = mSlt->getWidth() + screen->getBevelWidth();
 
2108
                                        break;
 
2109
                                }
 
2110
                        break;
 
2111
                        case Slit::HORIZONTAL:
 
2112
                                switch(screen->getSlitPlacement())
 
2113
                                {
 
2114
                                case Slit::TOPLEFT:
 
2115
                                case Slit::TOPCENTER:
 
2116
                                case Slit::TOPRIGHT:
 
2117
                                        slitModT = mSlt->getHeight() + screen->getBevelWidth();
 
2118
                                        switch (screen->getToolbarPlacement()) {
 
2119
                                                case Toolbar::TOPLEFT:
 
2120
                                                case Toolbar::TOPCENTER:
 
2121
                                                case Toolbar::TOPRIGHT:
 
2122
                                                        slitModT -= screen->getToolbar()->getExposedHeight() + 
 
2123
                                                                screen->getBorderWidth();
 
2124
                                                        break;
 
2125
                                                default:
 
2126
                                                        break;
 
2127
                                        }                               
 
2128
                                        break;
 
2129
                                default:
 
2130
                                        slitModB = mSlt->getHeight() + screen->getBevelWidth();
 
2131
                                        switch (screen->getToolbarPlacement()) {
 
2132
                                                case Toolbar::BOTTOMLEFT:
 
2133
                                                case Toolbar::BOTTOMCENTER:
 
2134
                                                case Toolbar::BOTTOMRIGHT:
 
2135
                                                        slitModB -= screen->getToolbar()->getExposedHeight() + 
 
2136
                                                                screen->getBorderWidth();
 
2137
                                                        break;
 
2138
                                                default:
 
2139
                                                        break;
 
2140
                                        }       
 
2141
                                        break;
 
2142
                                }       
 
2143
                                break;
 
2144
                        }
 
2145
                }               
 
2146
#endif // SLIT
 
2147
        
 
2148
                blackbox_attrib.premax_x = frame.x;
 
2149
                blackbox_attrib.premax_y = frame.y;
 
2150
                blackbox_attrib.premax_w = frame.width;
 
2151
                blackbox_attrib.premax_h = frame.height;
 
2152
 
 
2153
                dw = screen->getWidth() - slitModL - slitModR;
 
2154
                dw -= screen->getBorderWidth2x();
 
2155
                dw -= frame.mwm_border_w * 2;
 
2156
                dw -= client.base_width;
 
2157
 
 
2158
                dh = screen->getHeight() - slitModT - slitModB;
 
2159
                dh -= screen->getBorderWidth2x();
 
2160
                dh -= frame.mwm_border_w * 2;
 
2161
                dh -= ((frame.handle_h + screen->getBorderWidth()) * decorations.handle);
 
2162
                dh -= client.base_height;
 
2163
                dh -= frame.y_border;
 
2164
 
 
2165
                if (! screen->doFullMax())
 
2166
                        dh -= screen->getToolbar()->getExposedHeight() +
 
2167
                                                screen->getBorderWidth2x();
 
2168
 
 
2169
                if (dw < client.min_width) dw = client.min_width;
 
2170
                if (dh < client.min_height) dh = client.min_height;
 
2171
                if (dw > client.max_width) dw = client.max_width;
 
2172
                if (dh > client.max_height) dh = client.max_height;
 
2173
 
 
2174
                dw -= (dw % client.width_inc);
 
2175
                dw += client.base_width;
 
2176
                dh -= (dh % client.height_inc);
 
2177
                dh += client.base_height;
 
2178
 
 
2179
                dw += frame.mwm_border_w * 2;
 
2180
 
 
2181
                dh += frame.y_border;
 
2182
                dh += (frame.handle_h + screen->getBorderWidth());
 
2183
                dh += frame.mwm_border_w * 2;
 
2184
 
 
2185
                dx = ((screen->getWidth()+ slitModL - slitModR - dw) / 2) - screen->getBorderWidth();
 
2186
 
 
2187
                if (screen->doFullMax()) {
 
2188
                        dy = ((screen->getHeight() - dh) / 2) - screen->getBorderWidth();
 
2189
                } else {
 
2190
                        dy = (((screen->getHeight() + slitModT - slitModB - (screen->getToolbar()->getExposedHeight()))
 
2191
                         - dh) / 2) - screen->getBorderWidth2x();
 
2192
 
 
2193
                        switch (screen->getToolbarPlacement()) {
 
2194
                        case Toolbar::TOPLEFT:
 
2195
                        case Toolbar::TOPCENTER:
 
2196
                        case Toolbar::TOPRIGHT:
 
2197
                                dy += screen->getToolbar()->getExposedHeight() +
 
2198
                                                screen->getBorderWidth2x();
 
2199
                                break;
 
2200
                        default:
 
2201
                                break;
 
2202
                        }
 
2203
                }
 
2204
 
 
2205
                if (hasTab()) {
 
2206
                        switch(screen->getTabPlacement()) {                     
 
2207
                        case Tab::PTOP:
 
2208
                                dy += screen->getTabHeight(); 
 
2209
                                dh -= screen->getTabHeight();
 
2210
                                break;
 
2211
                        case Tab::PLEFT:
 
2212
                                if (screen->isTabRotateVertical()) {
 
2213
                                        dx += screen->getTabHeight();
 
2214
                                        dw -= screen->getTabHeight();
 
2215
                                } else {
 
2216
                                        dx += screen->getTabWidth();
 
2217
                                        dw -= screen->getTabWidth();
 
2218
                                }       
 
2219
                                break;
 
2220
                        case Tab::PRIGHT:
 
2221
                                if (screen->isTabRotateVertical())
 
2222
                                        dw -= screen->getTabHeight();
 
2223
                                else
 
2224
                                        dw -= screen->getTabWidth();    
 
2225
                                break;
 
2226
                        case Tab::PBOTTOM:
 
2227
                                dh -= screen->getTabHeight();
 
2228
                                break;
 
2229
                        default:
 
2230
                                dy += screen->getTabHeight();
 
2231
                                dh -= screen->getTabHeight();
 
2232
                                break;
 
2233
                        }
 
2234
                }
 
2235
 
 
2236
                if (button == 2) { //expand max width
 
2237
                        dw = frame.width;
 
2238
                        dx = frame.x;
 
2239
                } else if (button == 3) { //expand max height
 
2240
                        dh = frame.height;
 
2241
                        dy = frame.y;
 
2242
                }
 
2243
 
 
2244
                switch(button) {
 
2245
                case 1:
 
2246
                        blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT;
 
2247
                        blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT;
 
2248
 
 
2249
                        break;
 
2250
 
 
2251
                case 2:
 
2252
                        blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXVERT;
 
2253
                        blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXVERT;
 
2254
 
 
2255
                        break;
 
2256
 
 
2257
                case 3:
 
2258
                        blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXHORIZ;
 
2259
                        blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXHORIZ;
 
2260
 
 
2261
                        break;
 
2262
                }
 
2263
 
 
2264
                if (shaded) {
 
2265
                        blackbox_attrib.flags ^= BaseDisplay::ATTRIB_SHADED;
 
2266
                        blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_SHADED;
 
2267
                        shaded = false;
 
2268
                        if (hasTab())
 
2269
                                getTab()->shade();
 
2270
                }
 
2271
 
 
2272
                maximized = true;
 
2273
 
 
2274
                configure(dx, dy, dw, dh);
 
2275
                if (tab)
 
2276
                        tab->raise();
 
2277
                screen->getWorkspace(workspace_number)->raiseWindow(this);
 
2278
                setState(current_state);
 
2279
 
 
2280
        } else {
 
2281
                maximized = false;
 
2282
 
 
2283
                if (isShaded()) {
 
2284
                        shade();
 
2285
                        if (hasTab())
 
2286
                                getTab()->shade();
 
2287
                }
 
2288
 
 
2289
                blackbox_attrib.flags &= ! (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT);
 
2290
                blackbox_attrib.attrib &= ! (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT);
 
2291
 
 
2292
                configure(blackbox_attrib.premax_x, blackbox_attrib.premax_y,
 
2293
                                blackbox_attrib.premax_w, blackbox_attrib.premax_h);
 
2294
 
 
2295
                blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
 
2296
                blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
 
2297
 
 
2298
                redrawAllButtons();
 
2299
                setState(current_state);
 
2300
        }
 
2301
 
 
2302
        if (tab) //resize all the windows in the tab group
 
2303
                tab->resize();
 
2304
}
 
2305
 
 
2306
 
 
2307
void FluxboxWindow::setWorkspace(int n) {
 
2308
        workspace_number = n;
 
2309
 
 
2310
        blackbox_attrib.flags |= BaseDisplay::ATTRIB_WORKSPACE;
 
2311
        blackbox_attrib.workspace = workspace_number;
 
2312
        #ifdef GNOME
 
2313
        updateGnomeWorkspaceAtom();
 
2314
        #endif
 
2315
}
 
2316
 
 
2317
 
 
2318
void FluxboxWindow::shade(void) {
 
2319
        if (decorations.titlebar) {
 
2320
                if (shaded) {
 
2321
                        XResizeWindow(display, frame.window, frame.width, frame.height);
 
2322
                        shaded = false;
 
2323
                        blackbox_attrib.flags ^= BaseDisplay::ATTRIB_SHADED;
 
2324
                        blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_SHADED;
 
2325
 
 
2326
                        setState(NormalState);
 
2327
                } else {
 
2328
                        XResizeWindow(display, frame.window, frame.width, frame.title_h);
 
2329
                        shaded = true;
 
2330
                        blackbox_attrib.flags |= BaseDisplay::ATTRIB_SHADED;
 
2331
                        blackbox_attrib.attrib |= BaseDisplay::ATTRIB_SHADED;
 
2332
 
 
2333
                        setState(IconicState);
 
2334
                }
 
2335
                #ifdef GNOME
 
2336
                updateGnomeStateAtom();
 
2337
                #endif
 
2338
        }
 
2339
}
 
2340
 
 
2341
 
 
2342
void FluxboxWindow::stick(void) {
 
2343
 
 
2344
        if (tab) //if it got a tab then do tab's stick on all of the objects in the list
 
2345
                tab->stick(); //this window will stick too.
 
2346
        else if (stuck) {
 
2347
                blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT;
 
2348
                blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT;
 
2349
 
 
2350
                stuck = false;
 
2351
 
 
2352
                if (! iconic)
 
2353
                        screen->reassociateWindow(this, -1, true);
 
2354
 
 
2355
                
 
2356
        } else {
 
2357
                stuck = true;
 
2358
 
 
2359
                blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT;
 
2360
                blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT;
 
2361
 
 
2362
        }
 
2363
        //find a STICK button in window
 
2364
        redrawAllButtons();
 
2365
        setState(current_state);
 
2366
        #ifdef GNOME
 
2367
        updateGnomeStateAtom();
 
2368
        #endif
 
2369
}
 
2370
 
 
2371
 
 
2372
void FluxboxWindow::setFocusFlag(bool focus) {
 
2373
        focused = focus;
 
2374
 
 
2375
        if (decorations.titlebar) {
 
2376
                if (focused) {
 
2377
                        if (frame.ftitle)
 
2378
                                XSetWindowBackgroundPixmap(display, frame.title, frame.ftitle);
 
2379
                        else
 
2380
                                XSetWindowBackground(display, frame.title, frame.ftitle_pixel);
 
2381
                } else {
 
2382
                        if (frame.utitle)
 
2383
                                XSetWindowBackgroundPixmap(display, frame.title, frame.utitle);
 
2384
                        else
 
2385
                                XSetWindowBackground(display, frame.title, frame.utitle_pixel);
 
2386
                }
 
2387
                XClearWindow(display, frame.title);
 
2388
                
 
2389
                redrawLabel();
 
2390
                redrawAllButtons();
 
2391
        }
 
2392
 
 
2393
        if (decorations.handle) {
 
2394
                if (focused) {
 
2395
                        if (frame.fhandle)
 
2396
                                XSetWindowBackgroundPixmap(display, frame.handle, frame.fhandle);
 
2397
                        else
 
2398
                                XSetWindowBackground(display, frame.handle, frame.fhandle_pixel);
 
2399
 
 
2400
                        if (frame.fgrip) {
 
2401
                                XSetWindowBackgroundPixmap(display, frame.right_grip, frame.fgrip);
 
2402
                                XSetWindowBackgroundPixmap(display, frame.left_grip, frame.fgrip);
 
2403
                        } else {
 
2404
                                XSetWindowBackground(display, frame.right_grip, frame.fgrip_pixel);
 
2405
                                XSetWindowBackground(display, frame.left_grip, frame.fgrip_pixel);
 
2406
                        }
 
2407
                } else {
 
2408
                        if (frame.uhandle)
 
2409
                                XSetWindowBackgroundPixmap(display, frame.handle, frame.uhandle);
 
2410
                        else
 
2411
                                XSetWindowBackground(display, frame.handle, frame.uhandle_pixel);
 
2412
 
 
2413
                        if (frame.ugrip) {
 
2414
                                XSetWindowBackgroundPixmap(display, frame.right_grip, frame.ugrip);
 
2415
                                XSetWindowBackgroundPixmap(display, frame.left_grip, frame.ugrip);
 
2416
                        } else {
 
2417
                                XSetWindowBackground(display, frame.right_grip, frame.ugrip_pixel);
 
2418
                                XSetWindowBackground(display, frame.left_grip, frame.ugrip_pixel);
 
2419
                        }
 
2420
                }
 
2421
                XClearWindow(display, frame.handle);
 
2422
                XClearWindow(display, frame.right_grip);
 
2423
                XClearWindow(display, frame.left_grip);
 
2424
        }
 
2425
        
 
2426
        if (tab)
 
2427
                tab->focus();
 
2428
        
 
2429
        if (decorations.border) {
 
2430
                if (focused)
 
2431
                        XSetWindowBorder(display, frame.plate, frame.fborder_pixel);
 
2432
                else
 
2433
                        XSetWindowBorder(display, frame.plate, frame.uborder_pixel);
 
2434
        }
 
2435
 
 
2436
        if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) &&
 
2437
                        screen->doAutoRaise() && timer!=0 )
 
2438
                timer->stop();
 
2439
}
 
2440
 
 
2441
 
 
2442
void FluxboxWindow::installColormap(bool install) {
 
2443
        Fluxbox *fluxbox = Fluxbox::instance();
 
2444
        BaseDisplay::GrabGuard gg(*fluxbox);
 
2445
        fluxbox->grab();
 
2446
        if (! validateClient()) return;
 
2447
 
 
2448
        int i = 0, ncmap = 0;
 
2449
        Colormap *cmaps = XListInstalledColormaps(display, client.window, &ncmap);
 
2450
        XWindowAttributes wattrib;
 
2451
        if (cmaps) {
 
2452
                if (XGetWindowAttributes(display, client.window, &wattrib)) {
 
2453
                        if (install) {
 
2454
                                // install the window's colormap
 
2455
                                for (i = 0; i < ncmap; i++) {
 
2456
                                        if (*(cmaps + i) == wattrib.colormap) {
 
2457
                                                // this window is using an installed color map... do not install
 
2458
                                                install = false;
 
2459
                                                break; //end for-loop (we dont need to check more)
 
2460
                                        }
 
2461
                                }
 
2462
                                // otherwise, install the window's colormap
 
2463
                                if (install)
 
2464
                                        XInstallColormap(display, wattrib.colormap);
 
2465
                        } else {                                
 
2466
                                for (i = 0; i < ncmap; i++) // uninstall the window's colormap
 
2467
                                        if (*(cmaps + i) == wattrib.colormap)                                           
 
2468
                                                XUninstallColormap(display, wattrib.colormap); // we found the colormap to uninstall
 
2469
                        }
 
2470
                }
 
2471
 
 
2472
                XFree(cmaps);
 
2473
        }
 
2474
 
 
2475
        fluxbox->ungrab();
 
2476
}
 
2477
 
 
2478
 
 
2479
void FluxboxWindow::setState(unsigned long new_state) {
 
2480
        current_state = new_state;
 
2481
        Fluxbox *fluxbox = Fluxbox::instance();
 
2482
        unsigned long state[2];
 
2483
        state[0] = (unsigned long) current_state;
 
2484
        state[1] = (unsigned long) None;
 
2485
        XChangeProperty(display, client.window, fluxbox->getWMStateAtom(),
 
2486
                        fluxbox->getWMStateAtom(), 32, PropModeReplace,
 
2487
                        (unsigned char *) state, 2);
 
2488
 
 
2489
        XChangeProperty(display, client.window, fluxbox->getFluxboxAttributesAtom(),
 
2490
                                        fluxbox->getFluxboxAttributesAtom(), 32, PropModeReplace,
 
2491
                                        (unsigned char *) &blackbox_attrib, PropBlackboxAttributesElements);
 
2492
}
 
2493
 
 
2494
//TODO: why ungrab in if-statement?
 
2495
bool FluxboxWindow::getState(void) {
 
2496
        current_state = 0;
 
2497
 
 
2498
        Atom atom_return;
 
2499
        bool ret = false;
 
2500
        int foo;
 
2501
        unsigned long *state, ulfoo, nitems;
 
2502
        Fluxbox *fluxbox = Fluxbox::instance();
 
2503
        if ((XGetWindowProperty(display, client.window, fluxbox->getWMStateAtom(),
 
2504
                                0l, 2l, false, fluxbox->getWMStateAtom(),
 
2505
                                &atom_return, &foo, &nitems, &ulfoo,
 
2506
                                (unsigned char **) &state) != Success) ||
 
2507
                        (! state)) {
 
2508
                fluxbox->ungrab();
 
2509
                return false;
 
2510
        }
 
2511
 
 
2512
        if (nitems >= 1) {
 
2513
                current_state = static_cast<unsigned long>(state[0]);
 
2514
                ret = true;
 
2515
        }
 
2516
 
 
2517
        XFree(static_cast<void *>(state));
 
2518
 
 
2519
        return ret;
 
2520
}
 
2521
 
 
2522
 
 
2523
void FluxboxWindow::setGravityOffsets(void) {
 
2524
        // translate x coordinate
 
2525
        switch (client.win_gravity) {
 
2526
                // handle Westward gravity
 
2527
        case NorthWestGravity:
 
2528
        case WestGravity:
 
2529
        case SouthWestGravity:
 
2530
        default:
 
2531
                frame.x = client.x;
 
2532
                        break;
 
2533
 
 
2534
                // handle Eastward gravity
 
2535
        case NorthEastGravity:
 
2536
        case EastGravity:
 
2537
        case SouthEastGravity:
 
2538
                frame.x = (client.x + client.width) - frame.width;
 
2539
                break;
 
2540
 
 
2541
                // no x translation desired - default
 
2542
        case StaticGravity:
 
2543
        case ForgetGravity:
 
2544
        case CenterGravity:
 
2545
                frame.x = client.x - frame.mwm_border_w + screen->getBorderWidth();
 
2546
        }
 
2547
 
 
2548
        // translate y coordinate
 
2549
        switch (client.win_gravity) {
 
2550
                // handle Northbound gravity
 
2551
        case NorthWestGravity:
 
2552
        case NorthGravity:
 
2553
        case NorthEastGravity:
 
2554
        default:
 
2555
                frame.y = client.y;
 
2556
                break;
 
2557
 
 
2558
                // handle Southbound gravity
 
2559
        case SouthWestGravity:
 
2560
        case SouthGravity:
 
2561
        case SouthEastGravity:
 
2562
                frame.y = (client.y + client.height) - frame.height;
 
2563
                break;
 
2564
 
 
2565
                // no y translation desired - default
 
2566
        case StaticGravity:
 
2567
        case ForgetGravity:
 
2568
        case CenterGravity:
 
2569
                frame.y = client.y - frame.y_border - frame.mwm_border_w -
 
2570
                        screen->getBorderWidth();
 
2571
                break;
 
2572
        }
 
2573
}
 
2574
 
 
2575
 
 
2576
void FluxboxWindow::restoreAttributes(void) {
 
2577
        if (!getState())
 
2578
                current_state = NormalState;
 
2579
 
 
2580
        Atom atom_return;
 
2581
        int foo;
 
2582
        unsigned long ulfoo, nitems;
 
2583
        Fluxbox *fluxbox = Fluxbox::instance();
 
2584
        
 
2585
        BaseDisplay::BlackboxAttributes *net;
 
2586
        if (XGetWindowProperty(display, client.window,
 
2587
                         fluxbox->getFluxboxAttributesAtom(), 0l,
 
2588
                         PropBlackboxAttributesElements, false,
 
2589
                         fluxbox->getFluxboxAttributesAtom(), &atom_return, &foo,
 
2590
                         &nitems, &ulfoo, (unsigned char **) &net) ==
 
2591
                        Success && net && nitems == PropBlackboxAttributesElements) {
 
2592
                blackbox_attrib.flags = net->flags;
 
2593
                blackbox_attrib.attrib = net->attrib;
 
2594
                blackbox_attrib.workspace = net->workspace;
 
2595
                blackbox_attrib.stack = net->stack;
 
2596
                blackbox_attrib.premax_x = net->premax_x;
 
2597
                blackbox_attrib.premax_y = net->premax_y;
 
2598
                blackbox_attrib.premax_w = net->premax_w;
 
2599
                blackbox_attrib.premax_h = net->premax_h;
 
2600
 
 
2601
                XFree(static_cast<void *>(net));
 
2602
        } else
 
2603
                return;
 
2604
 
 
2605
        if (blackbox_attrib.flags & BaseDisplay::ATTRIB_SHADED &&
 
2606
                        blackbox_attrib.attrib & BaseDisplay::ATTRIB_SHADED) {
 
2607
                int save_state =
 
2608
                        ((current_state == IconicState) ? NormalState : current_state);
 
2609
 
 
2610
                shaded = false;
 
2611
                shade();
 
2612
                if (tab)
 
2613
                        tab->shade();
 
2614
                        
 
2615
                current_state = save_state;
 
2616
        }
 
2617
 
 
2618
        if (((int) blackbox_attrib.workspace != screen->getCurrentWorkspaceID()) &&
 
2619
                        ((int) blackbox_attrib.workspace < screen->getCount())) {
 
2620
                screen->reassociateWindow(this, blackbox_attrib.workspace, true);
 
2621
 
 
2622
                if (current_state == NormalState) current_state = WithdrawnState;
 
2623
        } else if (current_state == WithdrawnState)
 
2624
                current_state = NormalState;
 
2625
 
 
2626
        if (blackbox_attrib.flags & BaseDisplay::ATTRIB_OMNIPRESENT &&
 
2627
                        blackbox_attrib.attrib & BaseDisplay::ATTRIB_OMNIPRESENT) {
 
2628
                stuck = false;
 
2629
                stick();
 
2630
 
 
2631
                current_state = NormalState;
 
2632
        }
 
2633
 
 
2634
        if ((blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ) ||
 
2635
                        (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT)) {
 
2636
                int x = blackbox_attrib.premax_x, y = blackbox_attrib.premax_y;
 
2637
                unsigned int w = blackbox_attrib.premax_w, h = blackbox_attrib.premax_h;
 
2638
                maximized = false;
 
2639
 
 
2640
                int m;
 
2641
                if ((blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ) &&
 
2642
                                (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT))
 
2643
                        m = ((blackbox_attrib.attrib & (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ?
 
2644
                                         1 : 0);
 
2645
                else if (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT)
 
2646
                        m = ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
 
2647
                else if (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ)
 
2648
                        m = ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
 
2649
                else
 
2650
                        m = 0;
 
2651
 
 
2652
                if (m) maximize(m);
 
2653
 
 
2654
                blackbox_attrib.premax_x = x;
 
2655
                blackbox_attrib.premax_y = y;
 
2656
                blackbox_attrib.premax_w = w;
 
2657
                blackbox_attrib.premax_h = h;
 
2658
        }
 
2659
 
 
2660
        setState(current_state);
 
2661
}
 
2662
 
 
2663
 
 
2664
void FluxboxWindow::restoreGravity(void) {
 
2665
        // restore x coordinate
 
2666
        switch (client.win_gravity) {
 
2667
                // handle Westward gravity
 
2668
        case NorthWestGravity:
 
2669
        case WestGravity:
 
2670
        case SouthWestGravity:
 
2671
        default:
 
2672
                client.x = frame.x;
 
2673
                break;
 
2674
 
 
2675
                // handle Eastward gravity
 
2676
        case NorthEastGravity:
 
2677
        case EastGravity:
 
2678
        case SouthEastGravity:
 
2679
                client.x = (frame.x + frame.width) - client.width;
 
2680
                break;
 
2681
        }
 
2682
 
 
2683
        // restore y coordinate
 
2684
        switch (client.win_gravity) {
 
2685
                // handle Northbound gravity
 
2686
        case NorthWestGravity:
 
2687
        case NorthGravity:
 
2688
        case NorthEastGravity:
 
2689
        default:
 
2690
                client.y = frame.y;
 
2691
                break;
 
2692
 
 
2693
                // handle Southbound gravity
 
2694
        case SouthWestGravity:
 
2695
        case SouthGravity:
 
2696
        case SouthEastGravity:
 
2697
                client.y = (frame.y + frame.height) - client.height;
 
2698
                break;
 
2699
        }
 
2700
}
 
2701
 
 
2702
 
 
2703
void FluxboxWindow::redrawLabel(void) {
 
2704
        if (focused) {
 
2705
                if (frame.flabel)
 
2706
                        XSetWindowBackgroundPixmap(display, frame.label, frame.flabel);
 
2707
                else
 
2708
                        XSetWindowBackground(display, frame.label, frame.flabel_pixel);
 
2709
        } else {
 
2710
                if (frame.ulabel)
 
2711
                        XSetWindowBackgroundPixmap(display, frame.label, frame.ulabel);
 
2712
                else
 
2713
                        XSetWindowBackground(display, frame.label, frame.ulabel_pixel);
 
2714
        }
 
2715
        
 
2716
        GC gc = ((focused) ? screen->getWindowStyle()->l_text_focus_gc :
 
2717
                         screen->getWindowStyle()->l_text_unfocus_gc);
 
2718
 
 
2719
        DrawUtil::DrawString(display, frame.label, gc,
 
2720
                        &screen->getWindowStyle()->font, 
 
2721
                        client.title_text_w, frame.label_w,
 
2722
                        frame.bevel_w, client.title);
 
2723
}
 
2724
 
 
2725
 
 
2726
void FluxboxWindow::redrawAllButtons(void) {
 
2727
        for (unsigned int i=0; i<buttonlist.size(); i++)
 
2728
                if (buttonlist[i].draw)
 
2729
                        buttonlist[i].draw(this, buttonlist[i].win, false);
 
2730
 
 
2731
}
 
2732
 
 
2733
void FluxboxWindow::mapRequestEvent(XMapRequestEvent *re) {
 
2734
        if (re->window == client.window) {
 
2735
#ifdef          DEBUG
 
2736
                fprintf(stderr,
 
2737
                        I18n::instance()->getMessage(
 
2738
#ifdef          NLS
 
2739
                                         WindowSet, WindowMapRequest,
 
2740
#else // !NLS
 
2741
                                         0, 0,
 
2742
#endif // NLS
 
2743
                                         "FluxboxWindow::mapRequestEvent() for 0x%lx\n"),
 
2744
                                                client.window);
 
2745
#endif // DEBUG
 
2746
                Fluxbox *fluxbox = Fluxbox::instance();
 
2747
                BaseDisplay::GrabGuard gg(*fluxbox);
 
2748
                fluxbox->grab();
 
2749
                if (! validateClient())
 
2750
                        return;
 
2751
 
 
2752
                bool get_state_ret = getState();
 
2753
                if (! (get_state_ret && fluxbox->isStartup())) {
 
2754
                        if ((client.wm_hint_flags & StateHint) &&
 
2755
                                        (! (current_state == NormalState || current_state == IconicState)))
 
2756
                                current_state = client.initial_state;
 
2757
                        else
 
2758
                                current_state = NormalState;
 
2759
                } else if (iconic)
 
2760
                        current_state = NormalState;
 
2761
 
 
2762
                switch (current_state) {
 
2763
                case IconicState:
 
2764
                        iconify();
 
2765
 
 
2766
                        break;
 
2767
 
 
2768
                case WithdrawnState:
 
2769
                        withdraw();
 
2770
 
 
2771
                        break;
 
2772
 
 
2773
                case NormalState:
 
2774
                case InactiveState:
 
2775
                case ZoomState:
 
2776
                default:
 
2777
                        deiconify(false);
 
2778
 
 
2779
                        break;
 
2780
                }
 
2781
 
 
2782
                fluxbox->ungrab();
 
2783
        }
 
2784
}
 
2785
 
 
2786
 
 
2787
void FluxboxWindow::mapNotifyEvent(XMapEvent *ne) {
 
2788
        #ifdef GNOME
 
2789
        loadGnomeAtoms();
 
2790
        #endif
 
2791
        if ((ne->window == client.window) && (! ne->override_redirect) && (visible)) {
 
2792
                Fluxbox *fluxbox = Fluxbox::instance();
 
2793
                BaseDisplay::GrabGuard gg(*fluxbox);
 
2794
                fluxbox->grab();
 
2795
                if (! validateClient())
 
2796
                        return;
 
2797
 
 
2798
                if (decorations.titlebar)
 
2799
                        positionButtons();
 
2800
 
 
2801
                setState(NormalState);          
 
2802
                        
 
2803
                redrawAllButtons();
 
2804
 
 
2805
                if (transient || screen->doFocusNew())
 
2806
                        setInputFocus();
 
2807
                else
 
2808
                        setFocusFlag(false);                    
 
2809
                
 
2810
 
 
2811
                visible = true;
 
2812
                iconic = false;
 
2813
 
 
2814
                fluxbox->ungrab();
 
2815
        }
 
2816
}
 
2817
 
 
2818
//------------------- unmapNotify ------------------
 
2819
// Unmaps frame window and client window if 
 
2820
// event.window == client.window
 
2821
// Returns true if *this should die
 
2822
// else false
 
2823
//-------------------------------------------------
 
2824
bool FluxboxWindow::unmapNotifyEvent(XUnmapEvent *ue) {
 
2825
        if (ue->window == client.window) {
 
2826
                #ifdef DEBUG
 
2827
                fprintf(stderr,
 
2828
                        I18n::instance()->getMessage(
 
2829
                #ifdef NLS
 
2830
                         WindowSet, WindowUnmapNotify,
 
2831
                #else // !NLS
 
2832
                         0, 0,
 
2833
                #endif // NLS
 
2834
                         "FluxboxWindow::unmapNotifyEvent() for 0x%lx\n"),
 
2835
                        client.window);
 
2836
                #endif // DEBUG
 
2837
 
 
2838
                Fluxbox *fluxbox = Fluxbox::instance();
 
2839
                BaseDisplay::GrabGuard gg(*fluxbox);
 
2840
                fluxbox->grab();
 
2841
                if (! validateClient())
 
2842
                        return false;
 
2843
 
 
2844
                XChangeSaveSet(display, client.window, SetModeDelete);
 
2845
                XSelectInput(display, client.window, NoEventMask);
 
2846
 
 
2847
                XDeleteProperty(display, client.window, fluxbox->getWMStateAtom());
 
2848
                XDeleteProperty(display, client.window, fluxbox->getFluxboxAttributesAtom());
 
2849
 
 
2850
                XUnmapWindow(display, frame.window);
 
2851
                XUnmapWindow(display, client.window);
 
2852
 
 
2853
                XEvent dummy;
 
2854
                if (! XCheckTypedWindowEvent(display, client.window, ReparentNotify,
 
2855
                                 &dummy)) {
 
2856
                        #ifdef DEBUG
 
2857
                        fprintf(stderr,
 
2858
                                I18n::instance()->getMessage(
 
2859
                        #ifdef NLS
 
2860
                                                 WindowSet, WindowUnmapNotifyReparent,
 
2861
                        #else // !NLS
 
2862
                                                 0, 0,
 
2863
                        #endif // NLS
 
2864
                                                 "FluxboxWindow::unmapNotifyEvent(): reparent 0x%lx to "
 
2865
                                                 "root.\n"), client.window);
 
2866
                        #endif // DEBUG
 
2867
                        restoreGravity();
 
2868
                        XReparentWindow(display, client.window, screen->getRootWindow(),
 
2869
                                client.x, client.y);
 
2870
                }
 
2871
 
 
2872
                XFlush(display);
 
2873
 
 
2874
                fluxbox->ungrab();
 
2875
 
 
2876
                return true;
 
2877
        }
 
2878
 
 
2879
        return false;
 
2880
}
 
2881
 
 
2882
//----------- destroyNotifyEvent -------------
 
2883
// Checks if event is for client.window.
 
2884
// Unmaps frame.window and returns true for destroy
 
2885
// of this FluxboxWindow else returns false.
 
2886
//--------------------------------------------
 
2887
bool FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) {
 
2888
        if (de->window == client.window) {
 
2889
                #ifdef DEBUG
 
2890
                cerr<<__FILE__<<"("<<__LINE__<<":) DestroyNotifyEvent this="<<this<<endl;
 
2891
                #endif
 
2892
                XUnmapWindow(display, frame.window);            
 
2893
                return true;
 
2894
        }
 
2895
        return false;
 
2896
}
 
2897
 
 
2898
 
 
2899
void FluxboxWindow::propertyNotifyEvent(Atom atom) {
 
2900
        Fluxbox *fluxbox = Fluxbox::instance();
 
2901
        BaseDisplay::GrabGuard gg(*fluxbox);
 
2902
        fluxbox->grab();
 
2903
        if (! validateClient()) return;
 
2904
 
 
2905
        switch(atom) {
 
2906
        case XA_WM_CLASS:
 
2907
        case XA_WM_CLIENT_MACHINE:
 
2908
        case XA_WM_COMMAND:
 
2909
                break;
 
2910
 
 
2911
        case XA_WM_TRANSIENT_FOR:
 
2912
                // determine if this is a transient window
 
2913
                Window win;
 
2914
                if (XGetTransientForHint(display, client.window, &win)) {
 
2915
                        if (win && (win != client.window))
 
2916
                                if ((client.transient_for = fluxbox->searchWindow(win))) {
 
2917
                                        client.transient_for->client.transient = this;
 
2918
                                        stuck = client.transient_for->stuck;
 
2919
                                        transient = true;
 
2920
                                } else if (win == client.window_group) {
 
2921
                //jr This doesn't look quite right...
 
2922
                                        if ((client.transient_for = fluxbox->searchGroup(win, this))) {
 
2923
                                                client.transient_for->client.transient = this;
 
2924
                                                stuck = client.transient_for->stuck;
 
2925
                                                transient = true;
 
2926
                                        }
 
2927
                                }
 
2928
 
 
2929
                        if (win == screen->getRootWindow()) modal = true;
 
2930
                }
 
2931
 
 
2932
                // adjust the window decorations based on transience
 
2933
                if (transient)
 
2934
                        decorations.maximize = decorations.handle =
 
2935
                                decorations.border = functions.maximize = false;
 
2936
 
 
2937
                reconfigure();
 
2938
 
 
2939
                break;
 
2940
 
 
2941
        case XA_WM_HINTS:
 
2942
                getWMHints();
 
2943
                break;
 
2944
 
 
2945
        case XA_WM_ICON_NAME:
 
2946
                getWMIconName();
 
2947
                if (iconic) screen->iconUpdate();
 
2948
                break;
 
2949
 
 
2950
        case XA_WM_NAME:
 
2951
                getWMName();
 
2952
 
 
2953
                if (decorations.titlebar)
 
2954
                        redrawLabel();
 
2955
 
 
2956
                if (hasTab()) // update tab
 
2957
                        getTab()->draw(false);
 
2958
 
 
2959
                if (! iconic)
 
2960
                        screen->getWorkspace(workspace_number)->update();
 
2961
                else if (Fluxbox::instance()->useIconBar()) {
 
2962
                        IconBar *iconbar = 0;
 
2963
                        IconBarObj *icon = 0;
 
2964
                        if ((iconbar = screen->getToolbar()->getIconBar()) != 0) {
 
2965
                                if ((icon = iconbar->findIcon(this)) != 0)
 
2966
                                        iconbar->draw(icon, icon->getWidth());
 
2967
#ifdef DEBUG
 
2968
                                else
 
2969
                                        cerr<<__FILE__<<"("<<__LINE__<<"): can't find icon!"<<endl;
 
2970
#endif //DEBUG  
 
2971
                        }
 
2972
#ifdef DEBUG
 
2973
                        else
 
2974
                                cerr<<__FILE__<<"("<<__LINE__<<"): can't find iconbar!"<<endl;
 
2975
#endif //DEBUG
 
2976
                }
 
2977
 
 
2978
                break;
 
2979
 
 
2980
        case XA_WM_NORMAL_HINTS: {
 
2981
                getWMNormalHints();
 
2982
 
 
2983
                if ((client.normal_hint_flags & PMinSize) &&
 
2984
                                (client.normal_hint_flags & PMaxSize)) {
 
2985
                        if (client.max_width <= client.min_width &&
 
2986
                                        client.max_height <= client.min_height)
 
2987
                                decorations.maximize = decorations.handle =
 
2988
                        functions.resize = functions.maximize = false;
 
2989
                        else
 
2990
                                decorations.maximize = decorations.handle =
 
2991
                        functions.resize = functions.maximize = true;
 
2992
                }
 
2993
 
 
2994
                int x = frame.x, y = frame.y;
 
2995
                unsigned int w = frame.width, h = frame.height;
 
2996
 
 
2997
                upsize();
 
2998
 
 
2999
                if ((x != frame.x) || (y != frame.y) ||
 
3000
                                (w != frame.width) || (h != frame.height))
 
3001
                        reconfigure();
 
3002
 
 
3003
                break; 
 
3004
        }
 
3005
 
 
3006
        default:
 
3007
                if (atom == fluxbox->getWMProtocolsAtom()) {
 
3008
                        getWMProtocols();
 
3009
 
 
3010
                        if (decorations.close && !findTitleButton(Fluxbox::CLOSE)) {    
 
3011
                                createButton(Fluxbox::CLOSE, FluxboxWindow::closePressed_cb, 
 
3012
                                        FluxboxWindow::closeButton_cb, FluxboxWindow::closeDraw_cb);
 
3013
 
 
3014
                                if (decorations.titlebar)
 
3015
                                        positionButtons(true);
 
3016
                                if (windowmenu)
 
3017
                                        windowmenu->reconfigure();
 
3018
                        }
 
3019
                } else {
 
3020
                        bool val = false;
 
3021
                        #ifdef GNOME
 
3022
                        val = handleGnomePropertyNotify(atom);
 
3023
                        #endif
 
3024
                        #ifdef NEWWMSPEC
 
3025
                        if (!val)
 
3026
                                handleNETWMPropertyNotify(atom);
 
3027
                        #endif
 
3028
                }
 
3029
                break;
 
3030
        }
 
3031
 
 
3032
        fluxbox->ungrab();
 
3033
}
 
3034
 
 
3035
 
 
3036
void FluxboxWindow::exposeEvent(XExposeEvent *ee) {
 
3037
        if (frame.label == ee->window && decorations.titlebar)
 
3038
                redrawLabel();
 
3039
        else 
 
3040
                redrawAllButtons();
 
3041
 
 
3042
}
 
3043
 
 
3044
 
 
3045
void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) {
 
3046
        if (cr->window == client.window) {
 
3047
                Fluxbox *fluxbox = Fluxbox::instance();
 
3048
                BaseDisplay::GrabGuard gg(*fluxbox);
 
3049
                fluxbox->grab();
 
3050
                if (! validateClient())
 
3051
                        return;
 
3052
 
 
3053
                int cx = frame.x, cy = frame.y;
 
3054
                unsigned int cw = frame.width, ch = frame.height;
 
3055
 
 
3056
                if (cr->value_mask & CWBorderWidth)
 
3057
                        client.old_bw = cr->border_width;
 
3058
 
 
3059
                if (cr->value_mask & CWX)
 
3060
                        cx = cr->x - frame.mwm_border_w - screen->getBorderWidth();
 
3061
 
 
3062
                if (cr->value_mask & CWY)
 
3063
                        cy = cr->y - frame.y_border - frame.mwm_border_w -
 
3064
                                screen->getBorderWidth();
 
3065
 
 
3066
                if (cr->value_mask & CWWidth)
 
3067
                        cw = cr->width + (frame.mwm_border_w * 2);
 
3068
 
 
3069
                if (cr->value_mask & CWHeight)
 
3070
                        ch = cr->height + frame.y_border + (frame.mwm_border_w * 2) +
 
3071
                                (screen->getBorderWidth() * decorations.handle) + frame.handle_h;
 
3072
 
 
3073
                if (frame.x != cx || frame.y != cy ||
 
3074
                        frame.width != cw || frame.height != ch) {
 
3075
                        configure(cx, cy, cw, ch);
 
3076
                        if (tab)
 
3077
                                tab->resize();
 
3078
                }
 
3079
                if (cr->value_mask & CWStackMode) {
 
3080
                        switch (cr->detail) {
 
3081
                        case Above:
 
3082
                        case TopIf:
 
3083
                        default:
 
3084
                                if (iconic)
 
3085
                                        deiconify();
 
3086
//!!TODO check this and the line below..
 
3087
//                              if (tab)
 
3088
//                                      tab->raise();
 
3089
                                screen->getWorkspace(workspace_number)->raiseWindow(this);
 
3090
                                break;
 
3091
 
 
3092
                        case Below:
 
3093
                        case BottomIf:
 
3094
                                if (iconic)
 
3095
                                        deiconify();
 
3096
 
 
3097
//                              if (tab)
 
3098
//                                      tab->raise();
 
3099
                                screen->getWorkspace(workspace_number)->lowerWindow(this);
 
3100
                                break;
 
3101
                        }
 
3102
                }
 
3103
 
 
3104
                fluxbox->ungrab();
 
3105
        }
 
3106
}
 
3107
 
 
3108
 
 
3109
void FluxboxWindow::buttonPressEvent(XButtonEvent *be) {
 
3110
        Fluxbox *fluxbox = Fluxbox::instance();
 
3111
        BaseDisplay::GrabGuard gg(*fluxbox);
 
3112
        fluxbox->grab();
 
3113
        
 
3114
        if (! validateClient()) 
 
3115
                return;
 
3116
        
 
3117
        if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
 
3118
                if ((! focused) && (! screen->isSloppyFocus()))  //check focus
 
3119
                        setInputFocus(); 
 
3120
                
 
3121
                //Redraw buttons
 
3122
                for (unsigned int i=0; i<buttonlist.size(); i++) {
 
3123
                        if (be->window == buttonlist[i].win && buttonlist[i].draw)
 
3124
                                        buttonlist[i].draw(this, be->window, true);
 
3125
                }
 
3126
                
 
3127
                if (frame.plate == be->window) {
 
3128
                        
 
3129
                        if (windowmenu && windowmenu->isVisible()) //hide menu if its visible
 
3130
                                windowmenu->hide();
 
3131
                        //raise tab first, if there is any, so the focus on windows get 
 
3132
                        //right and dont "hide" the tab behind other windows
 
3133
                        if (tab)
 
3134
                                tab->raise();
 
3135
                        
 
3136
                        screen->getWorkspace(workspace_number)->raiseWindow(this);
 
3137
 
 
3138
                        XAllowEvents(display, ReplayPointer, be->time);
 
3139
                        
 
3140
                } else {
 
3141
                
 
3142
                        if (frame.title == be->window || frame.label == be->window) {
 
3143
                                if (((be->time - lastButtonPressTime) <=
 
3144
                                        fluxbox->getDoubleClickInterval()) ||
 
3145
                                                        (be->state & ControlMask)) {
 
3146
                                        lastButtonPressTime = 0;
 
3147
                                        shade();
 
3148
                                        if (tab) //shade windows in the tablist too
 
3149
                                                tab->shade();
 
3150
                                } else
 
3151
                                        lastButtonPressTime = be->time;                 
 
3152
                        }
 
3153
                        
 
3154
                        
 
3155
                        frame.grab_x = be->x_root - frame.x - screen->getBorderWidth();
 
3156
                        frame.grab_y = be->y_root - frame.y - screen->getBorderWidth();
 
3157
 
 
3158
                        if (windowmenu && windowmenu->isVisible())
 
3159
                                windowmenu->hide();
 
3160
                        //raise tab first if there is any
 
3161
                        if (hasTab())
 
3162
                                tab->raise();
 
3163
                
 
3164
                        screen->getWorkspace(workspace_number)->raiseWindow(this);
 
3165
                }
 
3166
        } else if (be->button == 2 && be->window == frame.label) {
 
3167
                screen->getWorkspace(workspace_number)->lowerWindow(this);
 
3168
                if (hasTab())
 
3169
                        getTab()->lower(); //lower the tab AND it's windows
 
3170
 
 
3171
        } else if (windowmenu && be->button == 3 &&
 
3172
                        (frame.title == be->window || frame.label == be->window ||
 
3173
                        frame.handle == be->window)) {
 
3174
 
 
3175
                int mx = 0, my = 0;
 
3176
 
 
3177
                if (frame.title == be->window || frame.label == be->window) {
 
3178
                        mx = be->x_root - (windowmenu->getWidth() / 2);
 
3179
                        my = frame.y + frame.title_h;
 
3180
                } else if (frame.handle == be->window) {
 
3181
                        mx = be->x_root - (windowmenu->getWidth() / 2);
 
3182
                        my = frame.y + frame.y_handle - windowmenu->getHeight();
 
3183
                } else {
 
3184
                        bool buttonproc=false;
 
3185
                        
 
3186
                        if (buttonproc)
 
3187
                                mx = be->x_root - (windowmenu->getWidth() / 2);
 
3188
 
 
3189
                        if (be->y <= (signed) frame.bevel_w)
 
3190
                                my = frame.y + frame.y_border;
 
3191
                        else
 
3192
                                my = be->y_root - (windowmenu->getHeight() / 2);
 
3193
                }
 
3194
 
 
3195
                if (mx > (signed) (frame.x + frame.width - windowmenu->getWidth()))
 
3196
                        mx = frame.x + frame.width - windowmenu->getWidth();
 
3197
                if (mx < frame.x)
 
3198
                        mx = frame.x;
 
3199
 
 
3200
                if (my > (signed) (frame.y + frame.y_handle - windowmenu->getHeight()))
 
3201
                        my = frame.y + frame.y_handle - windowmenu->getHeight();
 
3202
                if (my < (signed) (frame.y + ((decorations.titlebar) ? frame.title_h :
 
3203
                                                        frame.y_border)))
 
3204
                        my = frame.y +
 
3205
                        ((decorations.titlebar) ? frame.title_h : frame.y_border);
 
3206
 
 
3207
                if (windowmenu) {
 
3208
                        if (! windowmenu->isVisible()) { // if not window menu is visible then show it
 
3209
                                windowmenu->move(mx, my);
 
3210
                                windowmenu->show();             
 
3211
                                XRaiseWindow(display, windowmenu->getWindowID());
 
3212
                                XRaiseWindow(display, windowmenu->getSendToMenu()->getWindowID());
 
3213
                                XRaiseWindow(display, windowmenu->getSendGroupToMenu()->getWindowID());
 
3214
                        } else //else hide menu
 
3215
                                windowmenu->hide(); 
 
3216
                }
 
3217
                
 
3218
        } else if (be->button == 4) { //scroll to tab right
 
3219
                if (tab && tab->next()) {
 
3220
                        tab->next()->getWindow()->setInputFocus();
 
3221
                        screen->getWorkspace(workspace_number)->raiseWindow(tab->next()->getWindow());
 
3222
                }
 
3223
        } else if (be->button == 5) { //scroll to tab left
 
3224
                if (tab && tab->prev()) {
 
3225
                        tab->prev()->getWindow()->setInputFocus();
 
3226
                        screen->getWorkspace(workspace_number)->raiseWindow(tab->prev()->getWindow());
 
3227
                }
 
3228
        }
 
3229
        
 
3230
        fluxbox->ungrab();
 
3231
}
 
3232
 
 
3233
 
 
3234
void FluxboxWindow::buttonReleaseEvent(XButtonEvent *re) {
 
3235
        Fluxbox *fluxbox = Fluxbox::instance();
 
3236
        BaseDisplay::GrabGuard gg(*fluxbox);
 
3237
        fluxbox->grab();
 
3238
 
 
3239
        if (! validateClient())
 
3240
                return;
 
3241
 
 
3242
        if (moving) {
 
3243
                moving = false;
 
3244
                                                
 
3245
                fluxbox->maskWindowEvents(0, (FluxboxWindow *) 0);
 
3246
 
 
3247
                if (! screen->doOpaqueMove()) {
 
3248
                        XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3249
                                 frame.move_x, frame.move_y, frame.resize_w,
 
3250
                                 frame.resize_h);
 
3251
 
 
3252
                        configure(frame.move_x, frame.move_y, frame.width, frame.height);
 
3253
                        fluxbox->ungrab();
 
3254
                } else
 
3255
                        configure(frame.x, frame.y, frame.width, frame.height);
 
3256
 
 
3257
                screen->hideGeometry();
 
3258
                XUngrabPointer(display, CurrentTime);
 
3259
        } else if (resizing) {
 
3260
                XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3261
                        frame.resize_x, frame.resize_y,
 
3262
                        frame.resize_w, frame.resize_h);
 
3263
 
 
3264
                screen->hideGeometry();
 
3265
 
 
3266
                if (re->window == frame.left_grip)
 
3267
                        left_fixsize();
 
3268
                else
 
3269
                        right_fixsize();
 
3270
 
 
3271
                resizing = false;
 
3272
                configure(frame.resize_x, frame.resize_y,
 
3273
                                frame.resize_w - screen->getBorderWidth2x(),
 
3274
                                frame.resize_h - screen->getBorderWidth2x());
 
3275
        
 
3276
                if (tab)
 
3277
                        tab->resize();
 
3278
                        
 
3279
                fluxbox->ungrab();
 
3280
                XUngrabPointer(display, CurrentTime);
 
3281
        } else if (re->window == frame.window) {
 
3282
                if (re->button == 2 && re->state == Mod1Mask)
 
3283
                        XUngrabPointer(display, CurrentTime);
 
3284
        } else {
 
3285
                if ((re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
 
3286
                        (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
 
3287
                        for (unsigned int i=0; i<buttonlist.size(); i++) {
 
3288
                                if (re->window == buttonlist[i].win &&
 
3289
                                                buttonlist[i].released) {
 
3290
                                        buttonlist[i].released(this, re);       
 
3291
                                        break;                                  
 
3292
                                }
 
3293
                        }
 
3294
                } 
 
3295
                redrawAllButtons();
 
3296
        }
 
3297
 
 
3298
        fluxbox->ungrab();
 
3299
}
 
3300
 
 
3301
 
 
3302
void FluxboxWindow::motionNotifyEvent(XMotionEvent *me) {
 
3303
        Fluxbox *fluxbox = Fluxbox::instance();
 
3304
        if ((me->state & Button1Mask) && functions.move &&
 
3305
                        (frame.title == me->window || frame.label == me->window ||
 
3306
                         frame.handle == me->window || frame.window == me->window) && !resizing) {
 
3307
                         
 
3308
                if (! moving) {
 
3309
                        XGrabPointer(display, me->window, False, Button1MotionMask |
 
3310
                                                                ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
 
3311
                                                                None, fluxbox->getMoveCursor(), CurrentTime);
 
3312
 
 
3313
                        if (windowmenu && windowmenu->isVisible())
 
3314
                                windowmenu->hide();
 
3315
 
 
3316
                        moving = true;
 
3317
 
 
3318
                        fluxbox->maskWindowEvents(client.window, this);
 
3319
 
 
3320
                        if (! screen->doOpaqueMove()) {
 
3321
                                fluxbox->grab();
 
3322
 
 
3323
                                frame.move_x = frame.x;
 
3324
                                frame.move_y = frame.y;
 
3325
                                frame.resize_w = frame.width + screen->getBorderWidth2x();
 
3326
                                frame.resize_h = ((shaded) ? frame.title_h : frame.height) +
 
3327
                                                screen->getBorderWidth2x();
 
3328
 
 
3329
                                screen->showPosition(frame.x, frame.y);
 
3330
 
 
3331
                                XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3332
                                frame.move_x, frame.move_y,
 
3333
                                        frame.resize_w, frame.resize_h);
 
3334
                        }
 
3335
                } else {
 
3336
                        int dx = me->x_root - frame.grab_x, dy = me->y_root - frame.grab_y;
 
3337
 
 
3338
                        dx -= screen->getBorderWidth();
 
3339
                        dy -= screen->getBorderWidth();
 
3340
 
 
3341
                        if (screen->getEdgeSnapThreshold()) {
 
3342
                                int drx = screen->getWidth() - (dx + frame.snap_w);
 
3343
 
 
3344
                                if (dx > 0 && dx < drx && dx < screen->getEdgeSnapThreshold()) 
 
3345
                                        dx = 0;
 
3346
                                else if (drx > 0 && drx < screen->getEdgeSnapThreshold())
 
3347
                                        dx = screen->getWidth() - frame.snap_w;
 
3348
 
 
3349
                                int dtty, dbby, dty, dby;
 
3350
                                switch (screen->getToolbarPlacement()) {
 
3351
                                case Toolbar::TOPLEFT:
 
3352
                                case Toolbar::TOPCENTER:
 
3353
                                case Toolbar::TOPRIGHT:
 
3354
                                        dtty = screen->getToolbar()->getExposedHeight() +
 
3355
                                                        screen->getBorderWidth();
 
3356
                                        dbby = screen->getHeight();
 
3357
                                        break;
 
3358
 
 
3359
                                default:
 
3360
                                        dtty = 0;
 
3361
                                        dbby = screen->getToolbar()->getY();
 
3362
                                        break;
 
3363
                                }
 
3364
 
 
3365
                                dty = dy - dtty;
 
3366
                                dby = dbby - (dy + frame.snap_h);
 
3367
 
 
3368
                                if (dy > 0 && dty < screen->getEdgeSnapThreshold())
 
3369
                                        dy = dtty;
 
3370
                                else if (dby > 0 && dby < screen->getEdgeSnapThreshold())
 
3371
                                        dy = dbby - frame.snap_h;
 
3372
                        }
 
3373
 
 
3374
                        if (! screen->doOpaqueMove()) {
 
3375
                                XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3376
                                                frame.move_x, frame.move_y, frame.resize_w,
 
3377
                                                frame.resize_h);
 
3378
 
 
3379
                                frame.move_x = dx;
 
3380
                                frame.move_y = dy;
 
3381
 
 
3382
                                XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3383
                                         frame.move_x, frame.move_y, frame.resize_w,
 
3384
                                         frame.resize_h);
 
3385
                        } else
 
3386
                                configure(dx, dy, frame.width, frame.height);
 
3387
 
 
3388
                                screen->showPosition(dx, dy);
 
3389
                }
 
3390
        } else if (functions.resize &&
 
3391
                        (((me->state & Button1Mask) && (me->window == frame.right_grip ||
 
3392
                         me->window == frame.left_grip)) ||
 
3393
                         me->window == frame.window)) {
 
3394
                bool left = (me->window == frame.left_grip);
 
3395
 
 
3396
                if (! resizing) {
 
3397
                        XGrabPointer(display, me->window, false, ButtonMotionMask |
 
3398
                                ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None,
 
3399
                                ((left) ? fluxbox->getLowerLeftAngleCursor() :
 
3400
                                fluxbox->getLowerRightAngleCursor()),
 
3401
                                CurrentTime);
 
3402
 
 
3403
                        resizing = true;
 
3404
 
 
3405
//                      fluxbox->grab();
 
3406
 
 
3407
                        int gx, gy;
 
3408
                        frame.grab_x = me->x - screen->getBorderWidth();
 
3409
                        frame.grab_y = me->y - screen->getBorderWidth2x();
 
3410
                        frame.resize_x = frame.x;
 
3411
                        frame.resize_y = frame.y;
 
3412
                        frame.resize_w = frame.width + screen->getBorderWidth2x();
 
3413
                        frame.resize_h = frame.height + screen->getBorderWidth2x();
 
3414
 
 
3415
                        if (left)
 
3416
                                left_fixsize(&gx, &gy);
 
3417
                        else
 
3418
                                right_fixsize(&gx, &gy);
 
3419
 
 
3420
                        screen->showGeometry(gx, gy);
 
3421
 
 
3422
                        XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3423
                                frame.resize_x, frame.resize_y,
 
3424
                                frame.resize_w, frame.resize_h);
 
3425
                } else if (resizing) {
 
3426
                        XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3427
                                frame.resize_x, frame.resize_y,
 
3428
                                frame.resize_w, frame.resize_h);
 
3429
 
 
3430
                        int gx, gy;
 
3431
 
 
3432
                        frame.resize_h = frame.height + (me->y - frame.grab_y);
 
3433
                        if (frame.resize_h < 1)
 
3434
                                frame.resize_h = 1;
 
3435
 
 
3436
                        if (left) {
 
3437
                                frame.resize_x = me->x_root - frame.grab_x;
 
3438
                                if (frame.resize_x > (signed) (frame.x + frame.width))
 
3439
                                        frame.resize_x = frame.resize_x + frame.width - 1;
 
3440
 
 
3441
                                left_fixsize(&gx, &gy);
 
3442
                        } else {
 
3443
                                frame.resize_w = frame.width + (me->x - frame.grab_x);
 
3444
                                if (frame.resize_w < 1)
 
3445
                                        frame.resize_w = 1;
 
3446
 
 
3447
                                right_fixsize(&gx, &gy);
 
3448
                        }
 
3449
 
 
3450
                        XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 
3451
                                        frame.resize_x, frame.resize_y,
 
3452
                                        frame.resize_w, frame.resize_h);
 
3453
 
 
3454
                        screen->showGeometry(gx, gy);
 
3455
                }
 
3456
        }
 
3457
}
 
3458
 
 
3459
 
 
3460
#ifdef          SHAPE
 
3461
void FluxboxWindow::shapeEvent(XShapeEvent *) {
 
3462
        Fluxbox *fluxbox = Fluxbox::instance();
 
3463
        BaseDisplay::GrabGuard gg(*fluxbox);
 
3464
        
 
3465
        if (fluxbox->hasShapeExtensions()) {
 
3466
                if (frame.shaped) {                     
 
3467
                        fluxbox->grab();
 
3468
                        if (! validateClient())
 
3469
                                return;
 
3470
                        XShapeCombineShape(display, frame.window, ShapeBounding,
 
3471
                                frame.mwm_border_w, frame.y_border +
 
3472
                                frame.mwm_border_w, client.window,
 
3473
                                ShapeBounding, ShapeSet);
 
3474
 
 
3475
                        int num = 1;
 
3476
                        XRectangle xrect[2];
 
3477
                        xrect[0].x = xrect[0].y = 0;
 
3478
                        xrect[0].width = frame.width;
 
3479
                        xrect[0].height = frame.y_border;
 
3480
 
 
3481
                        if (decorations.handle) {
 
3482
                                xrect[1].x = 0;
 
3483
                                xrect[1].y = frame.y_handle;
 
3484
                                xrect[1].width = frame.width;
 
3485
                                xrect[1].height = frame.handle_h + screen->getBorderWidth();
 
3486
                                num++;
 
3487
                        }
 
3488
 
 
3489
                        XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
 
3490
                                        xrect, num, ShapeUnion, Unsorted);
 
3491
                        fluxbox->ungrab();
 
3492
                }
 
3493
        }
 
3494
}
 
3495
#endif // SHAPE
 
3496
 
 
3497
 
 
3498
bool FluxboxWindow::validateClient(void) {
 
3499
        XSync(display, false);
 
3500
 
 
3501
        XEvent e;
 
3502
        if (XCheckTypedWindowEvent(display, client.window, DestroyNotify, &e) ||
 
3503
                        XCheckTypedWindowEvent(display, client.window, UnmapNotify, &e)) {
 
3504
                XPutBackEvent(display, &e);
 
3505
                Fluxbox::instance()->ungrab();
 
3506
 
 
3507
                return false;
 
3508
        }
 
3509
 
 
3510
        return true;
 
3511
}
 
3512
 
 
3513
 
 
3514
void FluxboxWindow::restore(void) {
 
3515
        XChangeSaveSet(display, client.window, SetModeDelete);
 
3516
        XSelectInput(display, client.window, NoEventMask);
 
3517
 
 
3518
        restoreGravity();
 
3519
 
 
3520
        XUnmapWindow(display, frame.window);
 
3521
        XUnmapWindow(display, client.window);
 
3522
 
 
3523
        XSetWindowBorderWidth(display, client.window, client.old_bw);
 
3524
        XReparentWindow(display, client.window, screen->getRootWindow(),
 
3525
                                                                        client.x, client.y);
 
3526
        XMapWindow(display, client.window);
 
3527
                
 
3528
        XFlush(display);
 
3529
}
 
3530
 
 
3531
 
 
3532
void FluxboxWindow::timeout(void) {
 
3533
        if (tab)
 
3534
                tab->raise();
 
3535
        screen->getWorkspace(workspace_number)->raiseWindow(this);
 
3536
}
 
3537
 
 
3538
 
 
3539
void FluxboxWindow::changeBlackboxHints(BaseDisplay::BlackboxHints *net) {
 
3540
        if ((net->flags & BaseDisplay::ATTRIB_SHADED) &&
 
3541
                        ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_SHADED) !=
 
3542
                        (net->attrib & BaseDisplay::ATTRIB_SHADED)))
 
3543
                shade();
 
3544
 
 
3545
        if ((net->flags & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) &&
 
3546
                        ((blackbox_attrib.attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) !=
 
3547
                                (net->attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)))) {
 
3548
                if (maximized) {
 
3549
                        maximize(0);
 
3550
                } else {
 
3551
                        int m = 0;
 
3552
 
 
3553
                        if ((net->flags & BaseDisplay::ATTRIB_MAXHORIZ) && (net->flags & BaseDisplay::ATTRIB_MAXVERT))
 
3554
                                m = ((net->attrib & (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ?     1 : 0);
 
3555
                        else if (net->flags & BaseDisplay::ATTRIB_MAXVERT)
 
3556
                                m = ((net->attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
 
3557
                        else if (net->flags & BaseDisplay::ATTRIB_MAXHORIZ)
 
3558
                                m = ((net->attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
 
3559
 
 
3560
                        maximize(m);
 
3561
                }
 
3562
        }
 
3563
 
 
3564
        if ((net->flags & BaseDisplay::ATTRIB_OMNIPRESENT) &&
 
3565
                        ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_OMNIPRESENT) !=
 
3566
                        (net->attrib & BaseDisplay::ATTRIB_OMNIPRESENT)))
 
3567
                stick();
 
3568
 
 
3569
        if ((net->flags & BaseDisplay::ATTRIB_WORKSPACE) &&
 
3570
                        (workspace_number != (signed) net->workspace)) {
 
3571
                screen->reassociateWindow(this, net->workspace, true);
 
3572
 
 
3573
                if (screen->getCurrentWorkspaceID() != (signed) net->workspace)
 
3574
                        withdraw();
 
3575
                else 
 
3576
                        deiconify();
 
3577
        }
 
3578
 
 
3579
        if (net->flags & BaseDisplay::ATTRIB_DECORATION) {
 
3580
                switch (net->decoration) {
 
3581
                case BaseDisplay::DECOR_NONE:
 
3582
                        decorations.titlebar = decorations.border = decorations.handle =
 
3583
                                decorations.iconify = decorations.maximize =
 
3584
                                decorations.menu = decorations.tab = false; //tab is also a decor
 
3585
                        functions.resize = functions.move = functions.iconify =
 
3586
                                functions.maximize = false;
 
3587
 
 
3588
                        break;
 
3589
 
 
3590
                default:
 
3591
                case BaseDisplay::DECOR_NORMAL:
 
3592
                        decorations.titlebar = decorations.border = decorations.handle =
 
3593
                                decorations.iconify = decorations.maximize =
 
3594
                                decorations.menu = true;
 
3595
                        functions.resize = functions.move = functions.iconify =
 
3596
                                functions.maximize = true;
 
3597
 
 
3598
                        break;
 
3599
 
 
3600
                case BaseDisplay::DECOR_TINY:
 
3601
                        decorations.titlebar = decorations.iconify = decorations.menu =
 
3602
                                functions.move = functions.iconify = true;
 
3603
                        decorations.border = decorations.handle = decorations.maximize =
 
3604
                                functions.resize = functions.maximize = false;
 
3605
 
 
3606
                        break;
 
3607
 
 
3608
                case BaseDisplay::DECOR_TOOL:
 
3609
                        decorations.titlebar = decorations.menu = functions.move = true;
 
3610
                        decorations.iconify = decorations.border = decorations.handle =
 
3611
                                decorations.maximize = functions.resize = functions.maximize =
 
3612
                                functions.iconify = false;
 
3613
 
 
3614
                        break;
 
3615
                }
 
3616
 
 
3617
                reconfigure();
 
3618
        }
 
3619
}
 
3620
 
 
3621
 
 
3622
void FluxboxWindow::upsize(void) {
 
3623
        // convert client.width/height into frame sizes
 
3624
 
 
3625
        frame.bevel_w = screen->getBevelWidth();
 
3626
        frame.mwm_border_w = screen->getFrameWidth() * decorations.border;
 
3627
        
 
3628
        if (I18n::instance()->multibyte()) {
 
3629
                frame.title_h = (screen->getWindowStyle()->font.set_extents->
 
3630
                                max_ink_extent.height +
 
3631
                                (frame.bevel_w * 2) + 2) * decorations.titlebar;
 
3632
        } else
 
3633
                frame.title_h = (screen->getWindowStyle()->font.fontstruct->ascent +
 
3634
                                screen->getWindowStyle()->font.fontstruct->descent +
 
3635
                                (frame.bevel_w * 2) + 2) * decorations.titlebar;
 
3636
 
 
3637
        frame.label_h = (frame.title_h - (frame.bevel_w * 2)) * decorations.titlebar;
 
3638
        frame.button_w = frame.button_h = frame.label_h - 2;
 
3639
 
 
3640
        frame.y_border = (frame.title_h + screen->getBorderWidth()) * decorations.titlebar;
 
3641
        frame.border_h = client.height + (frame.mwm_border_w * 2);
 
3642
 
 
3643
        frame.y_handle = frame.y_border + frame.border_h +
 
3644
                                                        (screen->getBorderWidth() * decorations.handle);
 
3645
        frame.handle_h = decorations.handle * screen->getHandleWidth();
 
3646
 
 
3647
        frame.grip_w = (frame.button_h * 2) * decorations.handle;
 
3648
        frame.grip_h = screen->getHandleWidth() * decorations.handle;
 
3649
 
 
3650
        frame.width = client.width + (frame.mwm_border_w * 2);
 
3651
        frame.height = frame.y_handle + frame.handle_h;
 
3652
 
 
3653
        frame.snap_w = frame.width + screen->getBorderWidth2x();
 
3654
        frame.snap_h = frame.height + screen->getBorderWidth2x();
 
3655
}
 
3656
 
 
3657
 
 
3658
void FluxboxWindow::downsize(void) {
 
3659
        // convert frame.width/height into client sizes
 
3660
 
 
3661
        frame.y_handle = frame.height - frame.handle_h;
 
3662
        frame.border_h = frame.y_handle - frame.y_border -
 
3663
                                                        (screen->getBorderWidth() * decorations.handle);
 
3664
 
 
3665
        client.x = frame.x + frame.mwm_border_w + screen->getBorderWidth();
 
3666
        client.y = frame.y + frame.y_border + frame.mwm_border_w +
 
3667
                                                        screen->getBorderWidth();
 
3668
 
 
3669
        client.width = frame.width - (frame.mwm_border_w * 2);
 
3670
        client.height = frame.height - frame.y_border -
 
3671
                                                (frame.mwm_border_w * 2) - frame.handle_h -
 
3672
                                                (screen->getBorderWidth() * decorations.handle);
 
3673
 
 
3674
        frame.y_handle = frame.border_h + frame.y_border + screen->getBorderWidth();
 
3675
 
 
3676
        frame.snap_w = frame.width + screen->getBorderWidth2x();
 
3677
        frame.snap_h = frame.height + screen->getBorderWidth2x();
 
3678
}
 
3679
 
 
3680
 
 
3681
void FluxboxWindow::right_fixsize(int *gx, int *gy) {
 
3682
        // calculate the size of the client window and conform it to the
 
3683
        // size specified by the size hints of the client window...
 
3684
        int dx = frame.resize_w - client.base_width - (frame.mwm_border_w * 2) -
 
3685
                screen->getBorderWidth2x();
 
3686
        int dy = frame.resize_h - frame.y_border - client.base_height -
 
3687
                frame.handle_h - (screen->getBorderWidth() * 3) - (frame.mwm_border_w * 2);
 
3688
 
 
3689
        if (dx < (signed) client.min_width)
 
3690
                dx = client.min_width;
 
3691
        if (dy < (signed) client.min_height)
 
3692
                dy = client.min_height;
 
3693
        if ((unsigned) dx > client.max_width)
 
3694
                dx = client.max_width;
 
3695
        if ((unsigned) dy > client.max_height)
 
3696
                dy = client.max_height;
 
3697
 
 
3698
        dx /= client.width_inc;
 
3699
        dy /= client.height_inc;
 
3700
 
 
3701
        if (gx) *gx = dx;
 
3702
        if (gy) *gy = dy;
 
3703
 
 
3704
        dx = (dx * client.width_inc) + client.base_width;
 
3705
        dy = (dy * client.height_inc) + client.base_height;
 
3706
 
 
3707
        frame.resize_w = dx + (frame.mwm_border_w * 2) + screen->getBorderWidth2x();
 
3708
        frame.resize_h = dy + frame.y_border + frame.handle_h +
 
3709
                                                                (frame.mwm_border_w * 2) +      (screen->getBorderWidth() * 3);
 
3710
}
 
3711
 
 
3712
 
 
3713
void FluxboxWindow::left_fixsize(int *gx, int *gy) {
 
3714
        // calculate the size of the client window and conform it to the
 
3715
        // size specified by the size hints of the client window...
 
3716
        int dx = frame.x + frame.width - frame.resize_x - client.base_width -
 
3717
                (frame.mwm_border_w * 2);
 
3718
        int dy = frame.resize_h - frame.y_border - client.base_height -
 
3719
                frame.handle_h - (screen->getBorderWidth() * 3) - (frame.mwm_border_w * 2);
 
3720
 
 
3721
        if (dx < (signed) client.min_width) dx = client.min_width;
 
3722
        if (dy < (signed) client.min_height) dy = client.min_height;
 
3723
        if ((unsigned) dx > client.max_width) dx = client.max_width;
 
3724
        if ((unsigned) dy > client.max_height) dy = client.max_height;
 
3725
 
 
3726
        dx /= client.width_inc;
 
3727
        dy /= client.height_inc;
 
3728
 
 
3729
        if (gx) *gx = dx;
 
3730
        if (gy) *gy = dy;
 
3731
 
 
3732
        dx = (dx * client.width_inc) + client.base_width;
 
3733
        dy = (dy * client.height_inc) + client.base_height;
 
3734
 
 
3735
        frame.resize_w = dx + (frame.mwm_border_w * 2) + screen->getBorderWidth2x();
 
3736
        frame.resize_x = frame.x + frame.width - frame.resize_w +
 
3737
                                                                         screen->getBorderWidth2x();
 
3738
        frame.resize_h = dy + frame.y_border + frame.handle_h +
 
3739
                                                                         (frame.mwm_border_w * 2) + (screen->getBorderWidth() * 3);
 
3740
}