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