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

« back to all changes in this revision

Viewing changes to src/Slit.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
// Slit.cc for Blackbox - an X11 Window manager
 
2
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
 
3
//
 
4
// Permission is hereby granted, free of charge, to any person obtaining a
 
5
// copy of this software and associated documentation files (the "Software"),
 
6
// to deal in the Software without restriction, including without limitation
 
7
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
// and/or sell copies of the Software, and to permit persons to whom the
 
9
// Software is furnished to do so, subject to the following conditions:
 
10
//
 
11
// The above copyright notice and this permission notice shall be included in
 
12
// all copies or substantial portions of the Software.
 
13
//
 
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.        IN NO EVENT SHALL
 
17
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
18
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
19
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
20
// DEALINGS IN THE SOFTWARE.
 
21
 
 
22
// stupid macros needed to access some functions in version 2 of the GNU C
 
23
// library
 
24
#ifndef  _GNU_SOURCE
 
25
#define  _GNU_SOURCE
 
26
#endif // _GNU_SOURCE
 
27
 
 
28
#ifdef          HAVE_CONFIG_H
 
29
#       include "../config.h"
 
30
#endif // HAVE_CONFIG_H
 
31
 
 
32
#ifdef          SLIT
 
33
 
 
34
#include <X11/keysym.h>
 
35
 
 
36
#include "i18n.hh"
 
37
#include "fluxbox.hh"
 
38
#include "Image.hh"
 
39
#include "Screen.hh"
 
40
#include "Slit.hh"
 
41
#include "Toolbar.hh"
 
42
 
 
43
#include <algorithm>
 
44
 
 
45
 
 
46
Slit::Slit(BScreen *scr) {
 
47
        screen = scr;
 
48
        fluxbox = Fluxbox::instance();
 
49
 
 
50
        on_top = screen->isSlitOnTop();
 
51
        hidden = do_auto_hide = screen->doSlitAutoHide();
 
52
 
 
53
        display = screen->getBaseDisplay()->getXDisplay();
 
54
        frame.window = frame.pixmap = None;
 
55
 
 
56
        timer = new BTimer(fluxbox, this);
 
57
        timer->setTimeout(fluxbox->getAutoRaiseDelay());
 
58
        timer->fireOnce(True);
 
59
 
 
60
        slitmenu = new Slitmenu(this);
 
61
 
 
62
        XSetWindowAttributes attrib;
 
63
        unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
 
64
                CWColormap | CWOverrideRedirect | CWEventMask;
 
65
        attrib.background_pixmap = None;
 
66
        attrib.background_pixel = attrib.border_pixel =
 
67
                screen->getBorderColor()->getPixel();
 
68
        attrib.colormap = screen->getColormap();
 
69
        attrib.override_redirect = True;
 
70
        attrib.event_mask = SubstructureRedirectMask | ButtonPressMask |
 
71
                                                                                        EnterWindowMask | LeaveWindowMask;
 
72
 
 
73
        frame.x = frame.y = 0;
 
74
        frame.width = frame.height = 1;
 
75
 
 
76
        frame.window =
 
77
                XCreateWindow(display, screen->getRootWindow(), frame.x, frame.y,
 
78
                        frame.width, frame.height, screen->getBorderWidth(),
 
79
                                                                        screen->getDepth(), InputOutput, screen->getVisual(),
 
80
                                                                        create_mask, &attrib);
 
81
        fluxbox->saveSlitSearch(frame.window, this);
 
82
 
 
83
        reconfigure();
 
84
}
 
85
 
 
86
 
 
87
Slit::~Slit() {
 
88
        fluxbox->grab();
 
89
 
 
90
        delete timer;
 
91
 
 
92
        delete slitmenu;
 
93
 
 
94
        screen->getImageControl()->removeImage(frame.pixmap);
 
95
 
 
96
        fluxbox->removeSlitSearch(frame.window);
 
97
 
 
98
        XDestroyWindow(display, frame.window);
 
99
 
 
100
        fluxbox->ungrab();
 
101
}
 
102
 
 
103
 
 
104
void Slit::addClient(Window w) {
 
105
        fluxbox->grab();
 
106
        #ifdef DEBUG
 
107
        fprintf(stderr, "%s(%d): adding Client\n", __FILE__, __LINE__);
 
108
        #endif 
 
109
        if (fluxbox->validateWindow(w)) {
 
110
                SlitClient *client = new SlitClient;
 
111
                client->client_window = w;
 
112
 
 
113
                XWMHints *wmhints = XGetWMHints(display, w);
 
114
 
 
115
                if (wmhints) {
 
116
                        if ((wmhints->flags & IconWindowHint) &&
 
117
                                        (wmhints->icon_window != None)) {
 
118
                                XMoveWindow(display, client->client_window, screen->getWidth() + 10,
 
119
                                        screen->getHeight() + 10);
 
120
                                XMapWindow(display, client->client_window);                             
 
121
                                client->icon_window = wmhints->icon_window;
 
122
                                client->window = client->icon_window;
 
123
                        } else {
 
124
                                client->icon_window = None;
 
125
                                client->window = client->client_window;
 
126
                        }
 
127
 
 
128
                        XFree(wmhints);
 
129
                } else {
 
130
                        client->icon_window = None;
 
131
                        client->window = client->client_window;
 
132
                }
 
133
        #ifndef KDE 
 
134
                XWindowAttributes attrib;
 
135
                if (XGetWindowAttributes(display, client->window, &attrib)) {
 
136
                        client->width = attrib.width;
 
137
                        client->height = attrib.height;
 
138
                } else {
 
139
                        client->width = client->height = 64;
 
140
                }
 
141
        #else //KDE stuff starts here
 
142
          XWindowAttributes attrib;
 
143
                //Check and see if new client is a KDE dock applet
 
144
                //If so force reasonable size
 
145
                bool iskdedockapp=false;
 
146
                Atom ajunk;
 
147
                int ijunk;
 
148
                unsigned long *data = (unsigned long *) 0, uljunk;
 
149
 
 
150
                // Check if KDE v2.x dock applet
 
151
                if (XGetWindowProperty(fluxbox->getXDisplay(), w,
 
152
                                fluxbox->getKWM2DockwindowAtom(), 0l, 1l, False,
 
153
                                fluxbox->getKWM2DockwindowAtom(),
 
154
                                &ajunk, &ijunk, &uljunk, &uljunk,
 
155
                                (unsigned char **) &data) == Success) {
 
156
                        iskdedockapp = (data && data[0] != 0);
 
157
                        XFree((char *) data);
 
158
                }
 
159
 
 
160
                // Check if KDE v1.x dock applet
 
161
                if (!iskdedockapp) {
 
162
                        if (XGetWindowProperty(fluxbox->getXDisplay(), w,
 
163
                                        fluxbox->getKWM1DockwindowAtom(), 0l, 1l, False,
 
164
                                        fluxbox->getKWM1DockwindowAtom(),
 
165
                                        &ajunk, &ijunk, &uljunk, &uljunk,
 
166
                                        (unsigned char **) &data) == Success) {
 
167
                                iskdedockapp = (data && data[0] != 0);
 
168
                            XFree((char *) data);
 
169
                        }
 
170
                }
 
171
 
 
172
                if (iskdedockapp)
 
173
                        client->width = client->height = 24;
 
174
                else {
 
175
                        if (XGetWindowAttributes(display, client->window, &attrib)) {
 
176
                                client->width = attrib.width;
 
177
                                client->height = attrib.height;
 
178
                        }       else
 
179
                                client->width = client->height = 64;
 
180
                }
 
181
        #endif // KDE
 
182
 
 
183
                XSetWindowBorderWidth(display, client->window, 0);
 
184
 
 
185
                XSelectInput(display, frame.window, NoEventMask);
 
186
                XSelectInput(display, client->window, NoEventMask);
 
187
 
 
188
                XReparentWindow(display, client->window, frame.window, 0, 0);
 
189
                XMapRaised(display, client->window);
 
190
                XChangeSaveSet(display, client->window, SetModeInsert);
 
191
 
 
192
                XSelectInput(display, frame.window, SubstructureRedirectMask |
 
193
                        ButtonPressMask | EnterWindowMask | LeaveWindowMask);
 
194
                XSelectInput(display, client->window, StructureNotifyMask |
 
195
                        SubstructureNotifyMask | EnterWindowMask);
 
196
                XFlush(display);
 
197
 
 
198
                clientList.push_back(client);
 
199
 
 
200
                fluxbox->saveSlitSearch(client->client_window, this);
 
201
                fluxbox->saveSlitSearch(client->icon_window, this);
 
202
                reconfigure();
 
203
        }
 
204
 
 
205
        fluxbox->ungrab();
 
206
}
 
207
 
 
208
 
 
209
void Slit::removeClient(SlitClient *client, bool remap) {
 
210
        fluxbox->removeSlitSearch(client->client_window);
 
211
        fluxbox->removeSlitSearch(client->icon_window);
 
212
 
 
213
    clientList.remove(client);
 
214
 
 
215
        screen->removeNetizen(client->window);
 
216
 
 
217
        if (remap && fluxbox->validateWindow(client->window)) {
 
218
                XSelectInput(display, frame.window, NoEventMask);
 
219
                XSelectInput(display, client->window, NoEventMask);
 
220
                XReparentWindow(display, client->window, screen->getRootWindow(),
 
221
                        client->x, client->y);
 
222
                XChangeSaveSet(display, client->window, SetModeDelete);
 
223
                XSelectInput(display, frame.window, SubstructureRedirectMask |
 
224
                        ButtonPressMask | EnterWindowMask | LeaveWindowMask);
 
225
                XFlush(display);
 
226
        }
 
227
 
 
228
        delete client;
 
229
}
 
230
 
 
231
 
 
232
void Slit::removeClient(Window w, bool remap) {
 
233
        fluxbox->grab();
 
234
 
 
235
        bool reconf = false;
 
236
 
 
237
        SlitClients::iterator it = clientList.begin();
 
238
        SlitClients::iterator it_end = clientList.end();
 
239
        for (; it != it_end; ++it) {
 
240
                if ((*it)->window == w) {
 
241
                        removeClient((*it), remap);
 
242
                        reconf = true;
 
243
 
 
244
                        break;
 
245
                }
 
246
        }
 
247
        if (reconf) reconfigure();
 
248
 
 
249
        fluxbox->ungrab();
 
250
}
 
251
 
 
252
 
 
253
void Slit::reconfigure(void) {
 
254
        frame.width = 0;
 
255
        frame.height = 0;
 
256
 
 
257
        switch (screen->getSlitDirection()) {
 
258
        case VERTICAL:
 
259
                {
 
260
                        SlitClients::iterator it = clientList.begin();
 
261
                        SlitClients::iterator it_end = clientList.end();
 
262
                        for (; it != it_end; ++it) {
 
263
                                frame.height += (*it)->height + screen->getBevelWidth();
 
264
 
 
265
                                if (frame.width < (*it)->width)
 
266
                                        frame.width = (*it)->width;
 
267
                        }
 
268
                }
 
269
 
 
270
                if (frame.width < 1)
 
271
                        frame.width = 1;
 
272
                else
 
273
                        frame.width += (screen->getBevelWidth() * 2);
 
274
 
 
275
                if (frame.height < 1)
 
276
                        frame.height = 1;
 
277
                else
 
278
                        frame.height += screen->getBevelWidth();
 
279
 
 
280
                break;
 
281
 
 
282
        case HORIZONTAL:
 
283
                {
 
284
                        SlitClients::iterator it = clientList.begin();
 
285
                        SlitClients::iterator it_end = clientList.end();
 
286
                        for (; it != it_end; ++it) {
 
287
                                frame.width += (*it)->width + screen->getBevelWidth();
 
288
 
 
289
                                if (frame.height < (*it)->height)
 
290
                                        frame.height = (*it)->height;
 
291
                        }
 
292
                }
 
293
 
 
294
                if (frame.width < 1)
 
295
                        frame.width = 1;
 
296
                else
 
297
                        frame.width += screen->getBevelWidth();
 
298
 
 
299
                if (frame.height < 1)
 
300
                        frame.height = 1;
 
301
                else
 
302
                        frame.height += (screen->getBevelWidth() * 2);
 
303
 
 
304
                break;
 
305
        }
 
306
 
 
307
        reposition();
 
308
 
 
309
        XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth());
 
310
        XSetWindowBorder(display, frame.window,
 
311
                screen->getBorderColor()->getPixel());
 
312
 
 
313
        if (clientList.size()==0)
 
314
                XUnmapWindow(display, frame.window);
 
315
        else
 
316
                XMapWindow(display, frame.window);
 
317
 
 
318
        Pixmap tmp = frame.pixmap;
 
319
        BImageControl *image_ctrl = screen->getImageControl();
 
320
        BTexture *texture = &(screen->getToolbarStyle()->toolbar);
 
321
        if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
 
322
                frame.pixmap = None;
 
323
                XSetWindowBackground(display, frame.window,
 
324
                         texture->getColor()->getPixel());
 
325
        } else {
 
326
                frame.pixmap = image_ctrl->renderImage(frame.width, frame.height,
 
327
                        texture);
 
328
                XSetWindowBackgroundPixmap(display, frame.window, frame.pixmap);
 
329
        }
 
330
        if (tmp) image_ctrl->removeImage(tmp);
 
331
        XClearWindow(display, frame.window);
 
332
 
 
333
        int x, y;
 
334
 
 
335
        switch (screen->getSlitDirection()) {
 
336
        case VERTICAL:
 
337
                x = 0;
 
338
                y = screen->getBevelWidth();
 
339
 
 
340
                {
 
341
                        SlitClients::iterator it = clientList.begin();
 
342
                        SlitClients::iterator it_end = clientList.end();
 
343
                        for (; it != it_end; ++it) {
 
344
                                x = (frame.width - (*it)->width) / 2;
 
345
 
 
346
                                XMoveResizeWindow(display, (*it)->window, x, y,
 
347
                                        (*it)->width, (*it)->height);
 
348
                                XMapWindow(display, (*it)->window);
 
349
 
 
350
                                // for ICCCM compliance
 
351
                                (*it)->x = x;
 
352
                                (*it)->y = y;
 
353
 
 
354
                                XEvent event;
 
355
                                event.type = ConfigureNotify;
 
356
 
 
357
                                event.xconfigure.display = display;
 
358
                                event.xconfigure.event = (*it)->window;
 
359
                                event.xconfigure.window = (*it)->window;
 
360
                                event.xconfigure.x = x;
 
361
                                event.xconfigure.y = y;
 
362
                                event.xconfigure.width = (*it)->width;
 
363
                                event.xconfigure.height = (*it)->height;
 
364
                                event.xconfigure.border_width = 0;
 
365
                                event.xconfigure.above = frame.window;
 
366
                                event.xconfigure.override_redirect = False;
 
367
 
 
368
                                XSendEvent(display, (*it)->window, False, StructureNotifyMask,
 
369
                                        &event);
 
370
 
 
371
                                y += (*it)->height + screen->getBevelWidth();
 
372
                        }
 
373
                }
 
374
 
 
375
                break;
 
376
 
 
377
        case HORIZONTAL:
 
378
                x = screen->getBevelWidth();
 
379
                y = 0;
 
380
 
 
381
                {
 
382
                        SlitClients::iterator it = clientList.begin();
 
383
                        SlitClients::iterator it_end = clientList.end();
 
384
                        for (; it != it_end; ++it) {
 
385
                                y = (frame.height - (*it)->height) / 2;
 
386
 
 
387
                                XMoveResizeWindow(display, (*it)->window, x, y,
 
388
                                        (*it)->width, (*it)->height);
 
389
                                XMapWindow(display, (*it)->window);
 
390
 
 
391
                                // for ICCCM compliance
 
392
                                (*it)->x = x;
 
393
                                (*it)->y = y;
 
394
 
 
395
                                XEvent event;
 
396
                                event.type = ConfigureNotify;
 
397
 
 
398
                                event.xconfigure.display = display;
 
399
                                event.xconfigure.event = (*it)->window;
 
400
                                event.xconfigure.window = (*it)->window;
 
401
                                event.xconfigure.x = frame.x + x + screen->getBorderWidth();
 
402
                                event.xconfigure.y = frame.y + y + screen->getBorderWidth();
 
403
                                event.xconfigure.width = (*it)->width;
 
404
                                event.xconfigure.height = (*it)->height;
 
405
                                event.xconfigure.border_width = 0;
 
406
                                event.xconfigure.above = frame.window;
 
407
                                event.xconfigure.override_redirect = False;
 
408
 
 
409
                                XSendEvent(display, (*it)->window, False, StructureNotifyMask,
 
410
                                        &event);
 
411
 
 
412
                                x += (*it)->width + screen->getBevelWidth();
 
413
                        }
 
414
                }
 
415
 
 
416
                break;
 
417
        }
 
418
 
 
419
        slitmenu->reconfigure();
 
420
}
 
421
 
 
422
 
 
423
void Slit::reposition(void) {
 
424
        // place the slit in the appropriate place
 
425
        switch (screen->getSlitPlacement()) {
 
426
        case TOPLEFT:
 
427
                frame.x = 0;
 
428
                frame.y = 0;
 
429
                if (screen->getSlitDirection() == VERTICAL) {
 
430
                        frame.x_hidden = screen->getBevelWidth() -
 
431
                                screen->getBorderWidth() - frame.width;
 
432
                        frame.y_hidden = 0;
 
433
                } else {
 
434
                        frame.x_hidden = 0;
 
435
                        frame.y_hidden = screen->getBevelWidth() -
 
436
                                screen->getBorderWidth() - frame.height;
 
437
                }
 
438
                break;
 
439
 
 
440
        case CENTERLEFT:
 
441
                frame.x = 0;
 
442
                frame.y = (screen->getHeight() - frame.height) / 2;
 
443
                frame.x_hidden = screen->getBevelWidth() -
 
444
                        screen->getBorderWidth() - frame.width;
 
445
                frame.y_hidden = frame.y;
 
446
                break;
 
447
 
 
448
        case BOTTOMLEFT:
 
449
                frame.x = 0;
 
450
                frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x();
 
451
                if (screen->getSlitDirection() == VERTICAL) {
 
452
                        frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
 
453
                                                                 - frame.width;
 
454
                        frame.y_hidden = frame.y;
 
455
                } else {
 
456
                        frame.x_hidden = 0;
 
457
                        frame.y_hidden = screen->getHeight() -
 
458
                                screen->getBevelWidth() - screen->getBorderWidth();
 
459
                }
 
460
                break;
 
461
 
 
462
        case TOPCENTER:
 
463
                frame.x = (screen->getWidth() - frame.width) / 2;
 
464
                frame.y = 0;
 
465
                frame.x_hidden = frame.x;
 
466
                frame.y_hidden = screen->getBevelWidth() -
 
467
                        screen->getBorderWidth() - frame.height;
 
468
                break;
 
469
 
 
470
        case BOTTOMCENTER:
 
471
                frame.x = (screen->getWidth() - frame.width) / 2;
 
472
                frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x();
 
473
                frame.x_hidden = frame.x;
 
474
                frame.y_hidden = screen->getHeight() -
 
475
                        screen->getBevelWidth() - screen->getBorderWidth();
 
476
                break;
 
477
 
 
478
        case TOPRIGHT:
 
479
                frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x();
 
480
                frame.y = 0;
 
481
                if (screen->getSlitDirection() == VERTICAL) {
 
482
                        frame.x_hidden = screen->getWidth() -
 
483
                                screen->getBevelWidth() - screen->getBorderWidth();
 
484
                        frame.y_hidden = 0;
 
485
                } else {
 
486
                        frame.x_hidden = frame.x;
 
487
                        frame.y_hidden = screen->getBevelWidth() -
 
488
                                screen->getBorderWidth() - frame.height;
 
489
                }
 
490
                break;
 
491
 
 
492
        case CENTERRIGHT:
 
493
        default:
 
494
                frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x();
 
495
                frame.y = (screen->getHeight() - frame.height) / 2;
 
496
                frame.x_hidden = screen->getWidth() -
 
497
                        screen->getBevelWidth() - screen->getBorderWidth();
 
498
                frame.y_hidden = frame.y;
 
499
                break;
 
500
 
 
501
        case BOTTOMRIGHT:
 
502
                frame.x = screen->getWidth() - frame.width - screen->getBorderWidth2x();
 
503
                frame.y = screen->getHeight() - frame.height - screen->getBorderWidth2x();
 
504
                if (screen->getSlitDirection() == VERTICAL) {
 
505
                        frame.x_hidden = screen->getWidth() - 
 
506
                                screen->getBevelWidth() - screen->getBorderWidth();
 
507
                        frame.y_hidden = frame.y;
 
508
                } else {
 
509
                        frame.x_hidden = frame.x;
 
510
                        frame.y_hidden = screen->getHeight() - 
 
511
                                screen->getBevelWidth() - screen->getBorderWidth();
 
512
                }
 
513
                break;
 
514
        }
 
515
 
 
516
        Toolbar *tbar = screen->getToolbar();
 
517
        int sw = frame.width + screen->getBorderWidth2x(),
 
518
                sh = frame.height + screen->getBorderWidth2x(),
 
519
                tw = tbar->getWidth() + screen->getBorderWidth(),
 
520
                th = tbar->getHeight() + screen->getBorderWidth();
 
521
 
 
522
        if (tbar->getX() < frame.x + sw && tbar->getX() + tw > frame.x &&
 
523
                        tbar->getY() < frame.y + sh && tbar->getY() + th > frame.y) {
 
524
                if (frame.y < th) {
 
525
                        frame.y += tbar->getExposedHeight();
 
526
                        if (screen->getSlitDirection() == VERTICAL)
 
527
                                frame.y_hidden += tbar->getExposedHeight();
 
528
                        else
 
529
                                frame.y_hidden = frame.y;
 
530
                } else {
 
531
                        frame.y -= tbar->getExposedHeight();
 
532
                        if (screen->getSlitDirection() == VERTICAL)
 
533
                                frame.y_hidden -= tbar->getExposedHeight();
 
534
                        else
 
535
                                frame.y_hidden = frame.y;
 
536
                }
 
537
        }
 
538
 
 
539
        if (hidden)
 
540
                XMoveResizeWindow(display, frame.window, frame.x_hidden,
 
541
                        frame.y_hidden, frame.width, frame.height);
 
542
        else
 
543
                XMoveResizeWindow(display, frame.window, frame.x,
 
544
                        frame.y, frame.width, frame.height);
 
545
}
 
546
 
 
547
 
 
548
void Slit::shutdown(void) {
 
549
        while (clientList.size() != 0)
 
550
                removeClient(clientList.front());
 
551
}
 
552
 
 
553
 
 
554
void Slit::buttonPressEvent(XButtonEvent *e) {
 
555
        if (e->window != frame.window) return;
 
556
 
 
557
        if (e->button == Button1 && (! on_top)) {
 
558
                Window w[1] = { frame.window };
 
559
                screen->raiseWindows(w, 1);
 
560
        } else if (e->button == Button2 && (! on_top)) {
 
561
                XLowerWindow(display, frame.window);
 
562
        } else if (e->button == Button3) {
 
563
                if (! slitmenu->isVisible()) {
 
564
                        int x, y;
 
565
 
 
566
                        x = e->x_root - (slitmenu->getWidth() / 2);
 
567
                        y = e->y_root - (slitmenu->getHeight() / 2);
 
568
 
 
569
                        if (x < 0)
 
570
                                x = 0;
 
571
                        else if (x + slitmenu->getWidth() > screen->getWidth())
 
572
                                x = screen->getWidth() - slitmenu->getWidth();
 
573
 
 
574
                        if (y < 0)
 
575
                                y = 0;
 
576
                        else if (y + slitmenu->getHeight() > screen->getHeight())
 
577
                                y = screen->getHeight() - slitmenu->getHeight();
 
578
 
 
579
                        slitmenu->move(x, y);
 
580
                        slitmenu->show();
 
581
                } else
 
582
                        slitmenu->hide();
 
583
        }
 
584
}
 
585
 
 
586
 
 
587
void Slit::enterNotifyEvent(XCrossingEvent *) {
 
588
        if (! do_auto_hide)
 
589
                return;
 
590
 
 
591
        if (hidden) {
 
592
                if (! timer->isTiming()) timer->start();
 
593
        } else {
 
594
                if (timer->isTiming()) timer->stop();
 
595
        }
 
596
}
 
597
 
 
598
 
 
599
void Slit::leaveNotifyEvent(XCrossingEvent *) {
 
600
        if (! do_auto_hide)
 
601
                return;
 
602
 
 
603
        if (hidden) {
 
604
                if (timer->isTiming()) timer->stop();
 
605
        } else if (! slitmenu->isVisible()) {
 
606
                if (! timer->isTiming()) timer->start();
 
607
        }
 
608
}
 
609
 
 
610
 
 
611
void Slit::configureRequestEvent(XConfigureRequestEvent *e) {
 
612
        fluxbox->grab();
 
613
 
 
614
        if (fluxbox->validateWindow(e->window)) {
 
615
                bool reconf = false;
 
616
                XWindowChanges xwc;
 
617
 
 
618
                xwc.x = e->x;
 
619
                xwc.y = e->y;
 
620
                xwc.width = e->width;
 
621
                xwc.height = e->height;
 
622
                xwc.border_width = 0;
 
623
                xwc.sibling = e->above;
 
624
                xwc.stack_mode = e->detail;
 
625
 
 
626
                XConfigureWindow(display, e->window, e->value_mask, &xwc);
 
627
 
 
628
                SlitClients::iterator it = clientList.begin();
 
629
                SlitClients::iterator it_end = clientList.end();
 
630
                for (; it != it_end; ++it)
 
631
                        if ((*it)->window == e->window)
 
632
                                if ((*it)->width != ((unsigned) e->width) ||
 
633
                                                (*it)->height != ((unsigned) e->height)) {
 
634
                                        (*it)->width = (unsigned) e->width;
 
635
                                        (*it)->height = (unsigned) e->height;
 
636
 
 
637
                                        reconf = true;
 
638
 
 
639
                                        break;
 
640
                                }
 
641
 
 
642
                if (reconf) reconfigure();
 
643
 
 
644
        }
 
645
 
 
646
        fluxbox->ungrab();
 
647
}
 
648
 
 
649
 
 
650
void Slit::timeout(void) {
 
651
        hidden = ! hidden;
 
652
        if (hidden)
 
653
                XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden);
 
654
        else
 
655
                XMoveWindow(display, frame.window, frame.x, frame.y);
 
656
}
 
657
 
 
658
 
 
659
Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) {
 
660
        slit = sl;
 
661
        I18n *i18n = I18n::instance();
 
662
        
 
663
        setLabel(i18n->getMessage(
 
664
#ifdef          NLS
 
665
                                        SlitSet, SlitSlitTitle,
 
666
#else // !NLS
 
667
                                        0, 0,
 
668
#endif // NLS
 
669
                                        "Slit"));
 
670
        setInternalMenu();
 
671
 
 
672
        directionmenu = new Directionmenu(this);
 
673
        placementmenu = new Placementmenu(this);
 
674
 
 
675
        insert(i18n->getMessage(
 
676
#ifdef          NLS
 
677
                                CommonSet, CommonDirectionTitle,
 
678
#else // !NLS
 
679
                                0, 0,
 
680
#endif // NLS
 
681
                                "Direction"),
 
682
         directionmenu);
 
683
        insert(i18n->getMessage(
 
684
#ifdef          NLS
 
685
                                CommonSet, CommonPlacementTitle,
 
686
#else // !NLS
 
687
                                0, 0,
 
688
#endif // NLS
 
689
                                "Placement"),
 
690
         placementmenu);
 
691
        insert(i18n->getMessage(
 
692
#ifdef          NLS
 
693
                                CommonSet, CommonAlwaysOnTop,
 
694
#else // !NLS
 
695
                                0, 0,
 
696
#endif // NLS
 
697
                                "Always on top"), 1);
 
698
        insert(i18n->getMessage(
 
699
#ifdef          NLS
 
700
                                CommonSet, CommonAutoHide,
 
701
#else // !NLS
 
702
                                0, 0,
 
703
#endif // NLS
 
704
                                "Auto hide"), 2);
 
705
 
 
706
        update();
 
707
 
 
708
        if (slit->isOnTop()) setItemSelected(2, True);
 
709
        if (slit->doAutoHide()) setItemSelected(3, True);
 
710
}
 
711
 
 
712
 
 
713
Slitmenu::~Slitmenu(void) {
 
714
        delete directionmenu;
 
715
        delete placementmenu;
 
716
}
 
717
 
 
718
 
 
719
void Slitmenu::itemSelected(int button, int index) {
 
720
        if (button == 1) {
 
721
                BasemenuItem *item = find(index);
 
722
                if (! item) return;
 
723
 
 
724
                switch (item->function()) {
 
725
                case 1: // always on top
 
726
                        {
 
727
        Bool change = ((slit->isOnTop()) ?      False : True);
 
728
        slit->on_top = change;
 
729
        setItemSelected(2, change);
 
730
 
 
731
        if (slit->isOnTop()) slit->screen->raiseWindows((Window *) 0, 0);
 
732
        break;
 
733
                        }
 
734
 
 
735
                case 2: // auto hide
 
736
                        {
 
737
        Bool change = ((slit->doAutoHide()) ?   False : True);
 
738
        slit->do_auto_hide = change;
 
739
        setItemSelected(3, change);
 
740
 
 
741
        break;
 
742
                        }
 
743
                }
 
744
        }
 
745
}
 
746
 
 
747
 
 
748
void Slitmenu::internal_hide(void) {
 
749
        Basemenu::internal_hide();
 
750
        if (slit->doAutoHide())
 
751
                slit->timeout();
 
752
}
 
753
 
 
754
 
 
755
void Slitmenu::reconfigure(void) {
 
756
        directionmenu->reconfigure();
 
757
        placementmenu->reconfigure();
 
758
 
 
759
        Basemenu::reconfigure();
 
760
}
 
761
 
 
762
 
 
763
Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm) : Basemenu(sm->slit->screen) {
 
764
        slitmenu = sm;
 
765
        I18n *i18n = I18n::instance();
 
766
        
 
767
        setLabel(i18n->getMessage(
 
768
#ifdef          NLS
 
769
                                        SlitSet, SlitSlitDirection,
 
770
#else // !NLS
 
771
                                        0, 0,
 
772
#endif // NLS
 
773
                                        "Slit Direction"));
 
774
        setInternalMenu();
 
775
 
 
776
        insert(i18n->getMessage(
 
777
#ifdef          NLS
 
778
                                CommonSet, CommonDirectionHoriz,
 
779
#else // !NLS
 
780
                                0, 0,
 
781
#endif // NLS
 
782
                                "Horizontal"),
 
783
         Slit::HORIZONTAL);
 
784
        insert(i18n->getMessage(
 
785
#ifdef          NLS
 
786
                                CommonSet, CommonDirectionVert,
 
787
#else // !NLS
 
788
                                0, 0,
 
789
#endif // NLS
 
790
                                "Vertical"),
 
791
         Slit::VERTICAL);
 
792
 
 
793
        update();
 
794
 
 
795
        if (sm->slit->screen->getSlitDirection() == Slit::HORIZONTAL)
 
796
                setItemSelected(0, True);
 
797
        else
 
798
                setItemSelected(1, True);
 
799
}
 
800
 
 
801
 
 
802
void Slitmenu::Directionmenu::itemSelected(int button, int index) {
 
803
        if (button == 1) {
 
804
                BasemenuItem *item = find(index);
 
805
                if (! item) return;
 
806
 
 
807
                slitmenu->slit->screen->saveSlitDirection(item->function());
 
808
 
 
809
                if (item->function() == Slit::HORIZONTAL) {
 
810
                        setItemSelected(0, True);
 
811
                        setItemSelected(1, False);
 
812
                } else {
 
813
                        setItemSelected(0, False);
 
814
                        setItemSelected(1, True);
 
815
                }
 
816
 
 
817
                hide();
 
818
                slitmenu->slit->reconfigure();
 
819
        }
 
820
}
 
821
 
 
822
 
 
823
Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm) : Basemenu(sm->slit->screen) {
 
824
        slitmenu = sm;
 
825
        I18n *i18n = I18n::instance();
 
826
        
 
827
        setLabel(i18n->getMessage(
 
828
#ifdef          NLS
 
829
                                        SlitSet, SlitSlitPlacement,
 
830
#else // !NLS
 
831
                                        0, 0,
 
832
#endif // NLS
 
833
                                        "Slit Placement"));
 
834
        setMinimumSublevels(3);
 
835
        setInternalMenu();
 
836
 
 
837
        insert(i18n->getMessage(
 
838
#ifdef          NLS
 
839
                                CommonSet, CommonPlacementTopLeft,
 
840
#else // !NLS
 
841
                                0, 0,
 
842
#endif // NLS
 
843
                                "Top Left"),
 
844
         Slit::TOPLEFT);
 
845
        insert(i18n->getMessage(
 
846
#ifdef          NLS
 
847
                                CommonSet, CommonPlacementCenterLeft,
 
848
#else // !NLS
 
849
                                0, 0,
 
850
#endif // NLS
 
851
                                "Center Left"),
 
852
         Slit::CENTERLEFT);
 
853
        insert(i18n->getMessage(
 
854
#ifdef          NLS
 
855
                                CommonSet, CommonPlacementBottomLeft,
 
856
#else // !NLS
 
857
                                0, 0,
 
858
#endif // NLS
 
859
                                "Bottom Left"),
 
860
         Slit::BOTTOMLEFT);
 
861
        insert(i18n->getMessage(
 
862
#ifdef          NLS
 
863
                                CommonSet, CommonPlacementTopCenter,
 
864
#else // !NLS
 
865
                                0, 0,
 
866
#endif // NLS
 
867
                                "Top Center"),
 
868
         Slit::TOPCENTER);
 
869
        insert("");
 
870
        insert(i18n->getMessage(
 
871
#ifdef          NLS
 
872
                                CommonSet, CommonPlacementBottomCenter,
 
873
#else // !NLS
 
874
                                0, 0,
 
875
#endif // NLS
 
876
                                "Bottom Center"),
 
877
         Slit::BOTTOMCENTER);
 
878
        insert(i18n->getMessage(
 
879
#ifdef          NLS
 
880
                                CommonSet, CommonPlacementTopRight,
 
881
#else // !NLS
 
882
                                0, 0,
 
883
#endif // NLS
 
884
                                "Top Right"),
 
885
         Slit::TOPRIGHT);
 
886
        insert(i18n->getMessage(
 
887
#ifdef          NLS
 
888
                                CommonSet, CommonPlacementCenterRight,
 
889
#else // !NLS
 
890
                                0, 0,
 
891
#endif // NLS
 
892
                                "Center Right"),
 
893
         Slit::CENTERRIGHT);
 
894
        insert(i18n->getMessage(
 
895
#ifdef          NLS
 
896
                                CommonSet, CommonPlacementBottomRight,
 
897
#else // !NLS
 
898
                                0, 0,
 
899
#endif // NLS
 
900
                                "Bottom Right"),
 
901
         Slit::BOTTOMRIGHT);
 
902
 
 
903
        update();
 
904
}
 
905
 
 
906
 
 
907
void Slitmenu::Placementmenu::itemSelected(int button, int index) {
 
908
        if (button == 1) {
 
909
                BasemenuItem *item = find(index);
 
910
                if (! item) return;
 
911
 
 
912
                if (item->function()) {
 
913
                        slitmenu->slit->screen->saveSlitPlacement(item->function());
 
914
                        hide();
 
915
                        slitmenu->slit->reconfigure();
 
916
                }
 
917
        }
 
918
}
 
919
 
 
920
 
 
921
#endif // SLIT