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