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)
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:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
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.
25 # include "../config.h"
26 #endif // HAVE_CONFIG_H
29 #include <X11/keysym.h>
33 #include "blackbox.hh"
40 Slit::Slit(BScreen
*scr
) {
42 blackbox
= screen
->getBlackbox();
43 slitstr
= "session.screen" + itostring(screen
->getScreenNumber()) + ".slit.";
44 config
= blackbox
->getConfig();
48 display
= screen
->getBaseDisplay()->getXDisplay();
49 frame
.window
= frame
.pixmap
= None
;
51 timer
= new BTimer(blackbox
, this);
52 timer
->setTimeout(blackbox
->getAutoRaiseDelay());
54 slitmenu
= new Slitmenu(this);
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
;
67 frame
.rect
.setSize(1, 1);
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);
77 screen
->addStrut(&strut
);
88 screen
->removeStrut(&strut
);
89 screen
->updateAvailableArea();
91 screen
->getImageControl()->removeImage(frame
.pixmap
);
93 blackbox
->removeSlitSearch(frame
.window
);
95 XDestroyWindow(display
, frame
.window
);
99 void Slit::addClient(Window w
) {
100 if (! blackbox
->validateWindow(w
))
103 SlitClient
*client
= new SlitClient
;
104 client
->client_window
= w
;
106 XWMHints
*wmhints
= XGetWMHints(display
, w
);
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
);
116 client
->icon_window
= wmhints
->icon_window
;
117 client
->window
= client
->icon_window
;
119 client
->icon_window
= None
;
120 client
->window
= client
->client_window
;
125 client
->icon_window
= None
;
126 client
->window
= client
->client_window
;
129 XWindowAttributes attrib
;
130 if (XGetWindowAttributes(display
, client
->window
, &attrib
)) {
131 client
->rect
.setSize(attrib
.width
, attrib
.height
);
133 client
->rect
.setSize(64, 64);
138 if (XGetWMProtocols(display
, client
->window
, &proto
, &num_return
)) {
139 for (int i
= 0; i
< num_return
; ++i
) {
141 blackbox
->getXAtom()->getAtom(XAtom::blackbox_structure_messages
)) {
142 screen
->addNetizen(new Netizen(screen
, client
->window
));
147 XSetWindowBorderWidth(display
, client
->window
, 0);
149 XGrabServer(display
);
150 XSelectInput(display
, frame
.window
, NoEventMask
);
151 XSelectInput(display
, client
->window
, NoEventMask
);
152 XReparentWindow(display
, client
->window
, frame
.window
, 0, 0);
153 XMapRaised(display
, client
->window
);
154 XChangeSaveSet(display
, client
->window
, SetModeInsert
);
155 XSelectInput(display
, frame
.window
, SubstructureRedirectMask
|
156 ButtonPressMask
| EnterWindowMask
| LeaveWindowMask
);
157 XSelectInput(display
, client
->window
, StructureNotifyMask
|
158 SubstructureNotifyMask
| EnterWindowMask
);
160 XUngrabServer(display
);
162 clientList
.push_back(client
);
164 blackbox
->saveSlitSearch(client
->client_window
, this);
165 blackbox
->saveSlitSearch(client
->icon_window
, this);
170 void Slit::removeClient(SlitClient
*client
, bool remap
) {
171 blackbox
->removeSlitSearch(client
->client_window
);
172 blackbox
->removeSlitSearch(client
->icon_window
);
173 clientList
.remove(client
);
175 screen
->removeNetizen(client
->window
);
177 if (remap
&& blackbox
->validateWindow(client
->window
)) {
178 XGrabServer(display
);
179 XSelectInput(display
, frame
.window
, NoEventMask
);
180 XSelectInput(display
, client
->window
, NoEventMask
);
181 XReparentWindow(display
, client
->window
, screen
->getRootWindow(),
182 client
->rect
.x(), client
->rect
.y());
183 XChangeSaveSet(display
, client
->window
, SetModeDelete
);
184 XSelectInput(display
, frame
.window
, SubstructureRedirectMask
|
185 ButtonPressMask
| EnterWindowMask
| LeaveWindowMask
);
186 XUngrabServer(display
);
190 client
= (SlitClient
*) 0;
194 struct SlitClientMatch
{
196 SlitClientMatch(Window w
): window(w
) {}
197 inline bool operator()(const Slit::SlitClient
* client
) const {
198 return (client
->window
== window
);
203 void Slit::removeClient(Window w
, bool remap
) {
204 SlitClientList::iterator it
= clientList
.begin();
205 const SlitClientList::iterator end
= clientList
.end();
207 it
= std::find_if(it
, end
, SlitClientMatch(w
));
209 removeClient(*it
, remap
);
215 void Slit::saveOnTop(bool b
) {
217 config
->setValue(slitstr
+ "onTop", on_top
);
220 void Slit::saveAutoHide(bool b
) {
222 config
->setValue(slitstr
+ "autoHide", do_auto_hide
);
225 void Slit::savePlacement(int p
) {
229 case TopLeft
: pname
= "TopLeft"; break;
230 case CenterLeft
: pname
= "CenterLeft"; break;
231 case BottomLeft
: pname
= "BottomLeft"; break;
232 case TopCenter
: pname
= "TopCenter"; break;
233 case BottomCenter
: pname
= "BottomCenter"; break;
234 case TopRight
: pname
= "TopRight"; break;
235 case BottomRight
: pname
= "BottomRight"; break;
236 case CenterRight
: default: pname
= "CenterRight"; break;
238 config
->setValue(slitstr
+ "placement", pname
);
241 void Slit::saveDirection(int d
) {
243 config
->setValue(slitstr
+ "direction", (direction
== Horizontal
?
244 "Horizontal" : "Vertical"));
247 void Slit::save_rc(void) {
249 saveAutoHide(do_auto_hide
);
250 savePlacement(placement
);
251 saveDirection(direction
);
254 void Slit::load_rc(void) {
257 if (! config
->getValue(slitstr
+ "onTop", on_top
))
260 if (! config
->getValue(slitstr
+ "autoHide", do_auto_hide
))
261 do_auto_hide
= false;
262 hidden
= do_auto_hide
;
264 if (config
->getValue(slitstr
+ "direction", s
) && s
== "Horizontal")
265 direction
= Horizontal
;
267 direction
= Vertical
;
269 if (config
->getValue(slitstr
+ "placement", s
)) {
272 else if (s
== "CenterLeft")
273 placement
= CenterLeft
;
274 else if (s
== "BottomLeft")
275 placement
= BottomLeft
;
276 else if (s
== "TopCenter")
277 placement
= TopCenter
;
278 else if (s
== "BottomCenter")
279 placement
= BottomCenter
;
280 else if (s
== "TopRight")
281 placement
= TopRight
;
282 else if (s
== "BottomRight")
283 placement
= BottomRight
;
284 else //if (s == "CenterRight")
285 placement
= CenterRight
;
287 placement
= CenterRight
;
291 void Slit::reconfigure(void) {
292 SlitClientList::iterator it
= clientList
.begin();
293 const SlitClientList::iterator end
= clientList
.end();
296 unsigned int width
= 0, height
= 0;
300 for (; it
!= end
; ++it
) {
302 height
+= client
->rect
.height() + screen
->getBevelWidth();
304 if (width
< client
->rect
.width())
305 width
= client
->rect
.width();
311 width
+= (screen
->getBevelWidth() * 2);
316 height
+= screen
->getBevelWidth();
321 for (; it
!= end
; ++it
) {
323 width
+= client
->rect
.width() + screen
->getBevelWidth();
325 if (height
< client
->rect
.height())
326 height
= client
->rect
.height();
332 width
+= screen
->getBevelWidth();
337 height
+= (screen
->getBevelWidth() * 2);
341 frame
.rect
.setSize(width
, height
);
345 XSetWindowBorderWidth(display
,frame
.window
, screen
->getBorderWidth());
346 XSetWindowBorder(display
, frame
.window
,
347 screen
->getBorderColor()->pixel());
349 if (clientList
.empty())
350 XUnmapWindow(display
, frame
.window
);
352 XMapWindow(display
, frame
.window
);
354 BTexture
*texture
= &(screen
->getToolbarStyle()->toolbar
);
355 frame
.pixmap
= texture
->render(frame
.rect
.width(), frame
.rect
.height(),
358 XSetWindowBackground(display
, frame
.window
, texture
->color().pixel());
360 XSetWindowBackgroundPixmap(display
, frame
.window
, frame
.pixmap
);
362 XClearWindow(display
, frame
.window
);
364 it
= clientList
.begin();
371 y
= screen
->getBevelWidth();
373 for (; it
!= end
; ++it
) {
375 x
= (frame
.rect
.width() - client
->rect
.width()) / 2;
377 XMoveResizeWindow(display
, client
->window
, x
, y
,
378 client
->rect
.width(), client
->rect
.height());
379 XMapWindow(display
, client
->window
);
381 // for ICCCM compliance
382 client
->rect
.setPos(x
, y
);
385 event
.type
= ConfigureNotify
;
387 event
.xconfigure
.display
= display
;
388 event
.xconfigure
.event
= client
->window
;
389 event
.xconfigure
.window
= client
->window
;
390 event
.xconfigure
.x
= x
;
391 event
.xconfigure
.y
= y
;
392 event
.xconfigure
.width
= client
->rect
.width();
393 event
.xconfigure
.height
= client
->rect
.height();
394 event
.xconfigure
.border_width
= 0;
395 event
.xconfigure
.above
= frame
.window
;
396 event
.xconfigure
.override_redirect
= False
;
398 XSendEvent(display
, client
->window
, False
, StructureNotifyMask
, &event
);
400 y
+= client
->rect
.height() + screen
->getBevelWidth();
406 x
= screen
->getBevelWidth();
409 for (; it
!= end
; ++it
) {
411 y
= (frame
.rect
.height() - client
->rect
.height()) / 2;
413 XMoveResizeWindow(display
, client
->window
, x
, y
,
414 client
->rect
.width(), client
->rect
.height());
415 XMapWindow(display
, client
->window
);
417 // for ICCCM compliance
418 client
->rect
.setPos(x
, y
);
421 event
.type
= ConfigureNotify
;
423 event
.xconfigure
.display
= display
;
424 event
.xconfigure
.event
= client
->window
;
425 event
.xconfigure
.window
= client
->window
;
426 event
.xconfigure
.x
= x
;
427 event
.xconfigure
.y
= y
;
428 event
.xconfigure
.width
= client
->rect
.width();
429 event
.xconfigure
.height
= client
->rect
.height();
430 event
.xconfigure
.border_width
= 0;
431 event
.xconfigure
.above
= frame
.window
;
432 event
.xconfigure
.override_redirect
= False
;
434 XSendEvent(display
, client
->window
, False
, StructureNotifyMask
, &event
);
436 x
+= client
->rect
.width() + screen
->getBevelWidth();
441 slitmenu
->reconfigure();
445 void Slit::updateStrut(void) {
446 strut
.top
= strut
.bottom
= strut
.left
= strut
.right
= 0;
448 if (! clientList
.empty()) {
449 // when not hidden both borders are in use, when hidden only one is
450 unsigned int border_width
= screen
->getBorderWidth();
458 strut
.top
= getExposedHeight() + border_width
;
461 strut
.bottom
= getExposedHeight() + border_width
;
466 strut
.left
= getExposedWidth() + border_width
;
471 strut
.right
= getExposedWidth() + border_width
;
480 strut
.top
= frame
.rect
.top() + getExposedHeight() + border_width
;
487 pos
= frame
.y_hidden
;
489 pos
= frame
.rect
.y();
490 strut
.bottom
= (screen
->getRect().bottom() - pos
);
493 strut
.left
= getExposedWidth() + border_width
;
496 strut
.right
= getExposedWidth() + border_width
;
503 // update area with new Strut info
504 screen
->updateAvailableArea();
508 void Slit::reposition(void) {
516 frame
.x_hidden
= screen
->getBevelWidth() - screen
->getBorderWidth()
517 - frame
.rect
.width();
519 if (placement
== TopLeft
)
521 else if (placement
== CenterLeft
)
522 y
= (screen
->getHeight() - frame
.rect
.height()) / 2;
524 y
= screen
->getHeight() - frame
.rect
.height()
525 - (screen
->getBorderWidth() * 2);
531 x
= (screen
->getWidth() - frame
.rect
.width()) / 2;
534 if (placement
== TopCenter
)
537 y
= screen
->getHeight() - frame
.rect
.height()
538 - (screen
->getBorderWidth() * 2);
545 x
= screen
->getWidth() - frame
.rect
.width()
546 - (screen
->getBorderWidth() * 2);
547 frame
.x_hidden
= screen
->getWidth() - screen
->getBevelWidth()
548 - screen
->getBorderWidth();
550 if (placement
== TopRight
)
552 else if (placement
== CenterRight
)
553 y
= (screen
->getHeight() - frame
.rect
.height()) / 2;
555 y
= screen
->getHeight() - frame
.rect
.height()
556 - (screen
->getBorderWidth() * 2);
560 frame
.rect
.setPos(x
, y
);
562 // we have to add the border to the rect as it is not accounted for
563 Rect tbar_rect
= screen
->getToolbar()->getRect();
564 tbar_rect
.setSize(tbar_rect
.width() + (screen
->getBorderWidth() * 2),
565 tbar_rect
.height() + (screen
->getBorderWidth() * 2));
566 Rect slit_rect
= frame
.rect
;
567 slit_rect
.setSize(slit_rect
.width() + (screen
->getBorderWidth() * 2),
568 slit_rect
.height() + (screen
->getBorderWidth() * 2));
570 if (! screen
->doHideToolbar() && slit_rect
.intersects(tbar_rect
)) {
571 int delta
= screen
->getToolbar()->getExposedHeight() +
572 screen
->getBorderWidth();
573 if (frame
.rect
.bottom() <= tbar_rect
.bottom())
576 frame
.rect
.setY(frame
.rect
.y() + delta
);
579 if (placement
== TopCenter
)
580 frame
.y_hidden
= 0 - frame
.rect
.height() + screen
->getBorderWidth()
581 + screen
->getBevelWidth();
582 else if (placement
== BottomCenter
)
583 frame
.y_hidden
= screen
->getHeight() - screen
->getBorderWidth()
584 - screen
->getBevelWidth();
586 frame
.y_hidden
= frame
.rect
.y();
591 XMoveResizeWindow(display
, frame
.window
,
592 frame
.x_hidden
, frame
.y_hidden
,
593 frame
.rect
.width(), frame
.rect
.height());
595 XMoveResizeWindow(display
, frame
.window
,
596 frame
.rect
.x(), frame
.rect
.y(),
597 frame
.rect
.width(), frame
.rect
.height());
601 void Slit::shutdown(void) {
602 while (! clientList
.empty())
603 removeClient(clientList
.front());
607 void Slit::buttonPressEvent(const XButtonEvent
*e
) {
608 if (e
->window
!= frame
.window
) return;
610 if (e
->button
== Button1
&& (! on_top
)) {
611 Window w
[1] = { frame
.window
};
612 screen
->raiseWindows(w
, 1);
613 } else if (e
->button
== Button2
&& (! on_top
)) {
614 XLowerWindow(display
, frame
.window
);
615 } else if (e
->button
== Button3
) {
616 if (! slitmenu
->isVisible()) {
619 x
= e
->x_root
- (slitmenu
->getWidth() / 2);
620 y
= e
->y_root
- (slitmenu
->getHeight() / 2);
624 else if (x
+ slitmenu
->getWidth() > screen
->getWidth())
625 x
= screen
->getWidth() - slitmenu
->getWidth();
629 else if (y
+ slitmenu
->getHeight() > screen
->getHeight())
630 y
= screen
->getHeight() - slitmenu
->getHeight();
632 slitmenu
->move(x
, y
);
641 void Slit::enterNotifyEvent(const XCrossingEvent
*) {
646 if (! timer
->isTiming()) timer
->start();
648 if (timer
->isTiming()) timer
->stop();
653 void Slit::leaveNotifyEvent(const XCrossingEvent
*) {
658 if (timer
->isTiming()) timer
->stop();
659 } else if (! slitmenu
->isVisible()) {
660 if (! timer
->isTiming()) timer
->start();
665 void Slit::configureRequestEvent(const XConfigureRequestEvent
*e
) {
666 if (! blackbox
->validateWindow(e
->window
))
673 xwc
.width
= e
->width
;
674 xwc
.height
= e
->height
;
675 xwc
.border_width
= 0;
676 xwc
.sibling
= e
->above
;
677 xwc
.stack_mode
= e
->detail
;
679 XConfigureWindow(display
, e
->window
, e
->value_mask
, &xwc
);
681 SlitClientList::iterator it
= clientList
.begin();
682 const SlitClientList::iterator end
= clientList
.end();
683 for (; it
!= end
; ++it
) {
684 SlitClient
*client
= *it
;
685 if (client
->window
== e
->window
&&
686 (static_cast<signed>(client
->rect
.width()) != e
->width
||
687 static_cast<signed>(client
->rect
.height()) != e
->height
)) {
688 client
->rect
.setSize(e
->width
, e
->height
);
697 void Slit::timeout(void) {
700 XMoveWindow(display
, frame
.window
, frame
.x_hidden
, frame
.y_hidden
);
702 XMoveWindow(display
, frame
.window
, frame
.rect
.x(), frame
.rect
.y());
706 void Slit::toggleAutoHide(void) {
707 saveAutoHide(do_auto_hide
? False
: True
);
711 if (do_auto_hide
== False
&& hidden
) {
712 // force the slit to be visible
713 if (timer
->isTiming()) timer
->stop();
719 void Slit::unmapNotifyEvent(const XUnmapEvent
*e
) {
720 removeClient(e
->window
);
724 Slitmenu::Slitmenu(Slit
*sl
) : Basemenu(sl
->screen
) {
727 setLabel(i18n(SlitSet
, SlitSlitTitle
, "Slit"));
730 directionmenu
= new Directionmenu(this);
731 placementmenu
= new Placementmenu(this);
733 insert(i18n(CommonSet
, CommonDirectionTitle
, "Direction"),
735 insert(i18n(CommonSet
, CommonPlacementTitle
, "Placement"),
737 insert(i18n(CommonSet
, CommonAlwaysOnTop
, "Always on top"), 1);
738 insert(i18n(CommonSet
, CommonAutoHide
, "Auto hide"), 2);
742 if (slit
->isOnTop()) setItemSelected(2, True
);
743 if (slit
->doAutoHide()) setItemSelected(3, True
);
747 Slitmenu::~Slitmenu(void) {
748 delete directionmenu
;
749 delete placementmenu
;
753 void Slitmenu::itemSelected(int button
, unsigned int index
) {
757 BasemenuItem
*item
= find(index
);
760 switch (item
->function()) {
761 case 1: { // always on top
762 slit
->saveOnTop(! slit
->isOnTop());
763 setItemSelected(2, slit
->isOnTop());
765 if (slit
->isOnTop()) slit
->screen
->raiseWindows((Window
*) 0, 0);
769 case 2: { // auto hide
770 slit
->toggleAutoHide();
771 setItemSelected(3, slit
->doAutoHide());
779 void Slitmenu::internal_hide(void) {
780 Basemenu::internal_hide();
781 if (slit
->doAutoHide())
786 void Slitmenu::reconfigure(void) {
787 directionmenu
->reconfigure();
788 placementmenu
->reconfigure();
790 Basemenu::reconfigure();
794 Slitmenu::Directionmenu::Directionmenu(Slitmenu
*sm
)
795 : Basemenu(sm
->slit
->screen
), slit(sm
->slit
) {
797 setLabel(i18n(SlitSet
, SlitSlitDirection
, "Slit Direction"));
800 insert(i18n(CommonSet
, CommonDirectionHoriz
, "Horizontal"),
802 insert(i18n(CommonSet
, CommonDirectionVert
, "Vertical"),
810 void Slitmenu::Directionmenu::reconfigure(void) {
812 Basemenu::reconfigure();
816 void Slitmenu::Directionmenu::setValues(void) {
817 const bool horiz
= slit
->getDirection() == Slit::Horizontal
;
818 setItemSelected(0, horiz
);
819 setItemSelected(1, ! horiz
);
823 void Slitmenu::Directionmenu::itemSelected(int button
, unsigned int index
) {
827 BasemenuItem
*item
= find(index
);
830 slit
->saveDirection(item
->function());
836 Slitmenu::Placementmenu::Placementmenu(Slitmenu
*sm
)
837 : Basemenu(sm
->slit
->screen
), slit(sm
->slit
) {
839 setLabel(i18n(SlitSet
, SlitSlitPlacement
, "Slit Placement"));
840 setMinimumSublevels(3);
843 insert(i18n(CommonSet
, CommonPlacementTopLeft
, "Top Left"),
845 insert(i18n(CommonSet
, CommonPlacementCenterLeft
, "Center Left"),
847 insert(i18n(CommonSet
, CommonPlacementBottomLeft
, "Bottom Left"),
849 insert(i18n(CommonSet
, CommonPlacementTopCenter
, "Top Center"),
852 insert(i18n(CommonSet
, CommonPlacementBottomCenter
, "Bottom Center"),
854 insert(i18n(CommonSet
, CommonPlacementTopRight
, "Top Right"),
856 insert(i18n(CommonSet
, CommonPlacementCenterRight
, "Center Right"),
858 insert(i18n(CommonSet
, CommonPlacementBottomRight
, "Bottom Right"),
867 void Slitmenu::Placementmenu::reconfigure(void) {
869 Basemenu::reconfigure();
873 void Slitmenu::Placementmenu::setValues(void) {
875 switch (slit
->getPlacement()) {
876 case Slit::BottomRight
:
878 case Slit::CenterRight
:
882 case Slit::BottomCenter
:
884 case Slit::TopCenter
:
886 case Slit::BottomLeft
:
888 case Slit::CenterLeft
:
893 setItemSelected(0, 0 == place
);
894 setItemSelected(1, 1 == place
);
895 setItemSelected(2, 2 == place
);
896 setItemSelected(3, 3 == place
);
897 setItemSelected(5, 4 == place
);
898 setItemSelected(6, 5 == place
);
899 setItemSelected(7, 6 == place
);
900 setItemSelected(8, 7 == place
);
904 void Slitmenu::Placementmenu::itemSelected(int button
, unsigned int index
) {
908 BasemenuItem
*item
= find(index
);
909 if (! (item
&& item
->function())) return;
911 slit
->savePlacement(item
->function());