1 // cycling.cc for bbkeys
3 // Copyright (c) 2001 by Ben Jansens <xor@orodu.net>
4 // Copyright (c) 2001 by Jason Kasper (vanRijn) <vR@movingparts.net>
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 // (See the included file COPYING / GPL-2.0)
26 #endif // HAVE_CONFIG_H
28 #include "stackmenu.hh"
30 #include "LinkedList.hh"
31 #include "wminterface.hh"
34 #include <X11/Xutil.h>
37 Stackmenu::Stackmenu(ToolWindow
*tool
) :
42 setTitleVisibility(False
);
44 setAlignment(AlignBottom
);
45 XSelectInput(bbtool
->getXDisplay(), getWindowID(), VisibilityChangeMask
);
48 Stackmenu::~Stackmenu() {
51 void Stackmenu::itemSelected(int,int) {
54 void Stackmenu::reconfigure()
56 Basemenu::reconfigure();
59 void Stackmenu::setMenuItems() {
60 XTextProperty text_prop
;
65 LinkedListIterator
<WindowList
> it(bbtool
->windowList
);
68 for (; it
.current(); it
++) {
69 if (((bbtool
->getShowAllWorkspaces()) &&
70 ((!it
.current()->sticky
) ||
71 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr())))
73 ((!bbtool
->getShowAllWorkspaces()) &&
74 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr()))) {
81 // what's our window name?
82 if (XGetWMName(bbtool
->getXDisplay(), it
.current()->win
, &text_prop
)) {
83 if (text_prop
.value
&& text_prop
.nitems
> 0) {
84 if (text_prop
.encoding
!= XA_STRING
) {
85 text_prop
.nitems
= strlen((char *) text_prop
.value
);
87 if ((XmbTextPropertyToTextList(bbtool
->getXDisplay(), &text_prop
,
88 &list
, &num
) == Success
) &&
90 title
= bstrdup(*list
);
91 XFreeStringList(list
);
93 title
= bstrdup((char *) text_prop
.value
);
95 title
= bstrdup((char *) text_prop
.value
);
97 XFree((char *) text_prop
.value
);
99 title
= bstrdup( "Unnamed");
101 title
= bstrdup( "Unnamed");
103 // now tack on the workspace name if we need to
104 if (bbtool
->getShowAllWorkspaces()) {
105 int size
= strlen(title
) + strlen(" (workspace )") + 2;
106 char *workspace
= (char*) malloc(size
);
108 snprintf(workspace
, size
, "%s (workspace %i)", title
,
109 it
.current()->desktop
+1);
119 void Stackmenu::clearMenu() {
124 void Stackmenu::selectFocused(bool raise
)
129 int selected
= menuPosition
;
130 LinkedListIterator
<WindowList
> it(bbtool
->windowList
);
131 for(; it
.current(); it
++)
132 if (((bbtool
->getShowAllWorkspaces()) &&
133 ((!it
.current()->sticky
) ||
134 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr())))
136 ((!bbtool
->getShowAllWorkspaces()) &&
137 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr()))) {
139 bbtool
->wminterface
->setWindowFocus(it
.current()->win
);
141 // okay, an explanation is in order... First, we have to
142 // hide our window so that focusWindow() actually does
144 // Next, if the window to focus is on a different desktop than
145 // the current one, we need to switch there.
146 // Then we XRaiseWindow, because if we did
147 // focusWindow() first, we'd then XRaise() the wrong window.
148 // Lastly, we update bbkey's stack with what we just
150 if (bbtool
->getCurrentDesktopNr() != it
.current()->desktop
)
151 bbtool
->wminterface
->changeDesktop(it
.current()->desktop
, False
);
152 XRaiseWindow(bbtool
->getXDisplay(), it
.current()->win
);
153 bbtool
->focusWindow(it
.current()->win
);
159 void Stackmenu::key_press(int grabInt
)
163 case grabNextWindowAllWorkspaces
:
164 if(++menuPosition
>= getCount())
166 setSelected(menuPosition
);
167 selectFocused(False
);
170 if(--menuPosition
< 0)
171 menuPosition
= getCount() - 1;
172 setSelected(menuPosition
);
173 selectFocused(False
);
180 void Stackmenu::hide()
182 XUngrabKeyboard(bbtool
->getXDisplay(), CurrentTime
);
184 bbtool
->setCycling(False
);
188 void Stackmenu::show(void)
194 void Stackmenu::show(bool forward
, bool showMenu
)
197 if (getCount() < 1) return; // no windows, just return
198 if (getCount() == 1) {
199 // only 1 window, focus it and leave
200 LinkedListIterator
<WindowList
> it(bbtool
->windowList
);
201 for (; it
.current(); it
++)
202 if (it
.current()->desktop
== bbtool
->getCurrentDesktopNr())
203 bbtool
->wminterface
->setWindowFocus(it
.current()->win
);
207 XRaiseWindow(bbtool
->getXDisplay(), getWindowID());
208 XGrabKeyboard(bbtool
->getXDisplay(),
209 bbtool
->getScreenInfo(0)->getRootWindow(), True
,
210 GrabModeAsync
, GrabModeAsync
, CurrentTime
);
213 key_press(forward
?grabNextWindow
:grabPrevWindow
);
215 bbtool
->setCycling(True
);
223 void Stackmenu::centerPosition()
225 int x
= (bbtool
->getCurrentScreenInfo()->getWidth()>>1) - (getWidth()>>1);
226 int y
= (bbtool
->getCurrentScreenInfo()->getHeight()>>1) - (getHeight()>>1);
228 Basemenu::move(x
, y
);
231 void Stackmenu::setSelected(int sel
)
233 if ((sel
<0) || (sel
>=getCount())) return;