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