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)
25 #include "LinkedList.hh"
27 #include <X11/Xutil.h>
30 # include "../config.h"
31 #endif // HAVE_CONFIG_H
33 Stackmenu::Stackmenu(ToolWindow
*tool
) :
38 setTitleVisibility(False
);
40 setAlignment(AlignBottom
);
41 XSelectInput(bbtool
->getXDisplay(), getWindowID(), VisibilityChangeMask
);
44 Stackmenu::~Stackmenu() {
47 void Stackmenu::itemSelected(int,int) {
50 void Stackmenu::reconfigure()
52 Basemenu::reconfigure();
55 void Stackmenu::setMenuItems() {
56 XTextProperty text_prop
;
61 LinkedListIterator
<WindowList
> it(bbtool
->windowList
);
64 for (; it
.current(); it
++) {
65 if (((bbtool
->getShowAllWorkspaces()) &&
66 ((!it
.current()->sticky
) ||
67 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr())))
69 ((!bbtool
->getShowAllWorkspaces()) &&
70 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr()))) {
77 // what's our window name?
78 if (XGetWMName(bbtool
->getXDisplay(), it
.current()->win
, &text_prop
)) {
79 if (text_prop
.value
&& text_prop
.nitems
> 0) {
80 if (text_prop
.encoding
!= XA_STRING
) {
81 text_prop
.nitems
= strlen((char *) text_prop
.value
);
83 if ((XmbTextPropertyToTextList(bbtool
->getXDisplay(), &text_prop
,
84 &list
, &num
) == Success
) &&
86 title
= bstrdup(*list
);
87 XFreeStringList(list
);
89 title
= bstrdup((char *) text_prop
.value
);
91 title
= bstrdup((char *) text_prop
.value
);
93 XFree((char *) text_prop
.value
);
95 title
= bstrdup( "Unnamed");
97 title
= bstrdup( "Unnamed");
99 // now tack on the workspace name if we need to
100 if (bbtool
->getShowAllWorkspaces()) {
101 int size
= strlen(title
) + strlen(" (workspace )") + 2;
102 char *workspace
= (char*) malloc(size
);
104 snprintf(workspace
, size
, "%s (workspace %i)", title
,
105 it
.current()->desktop
+1);
115 void Stackmenu::clearMenu() {
120 void Stackmenu::selectFocused(bool raise
)
122 int selected
= menuPosition
;
123 LinkedListIterator
<WindowList
> it(bbtool
->windowList
);
124 for(; it
.current(); it
++)
125 if (((bbtool
->getShowAllWorkspaces()) &&
126 ((!it
.current()->sticky
) ||
127 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr())))
129 ((!bbtool
->getShowAllWorkspaces()) &&
130 (it
.current()->desktop
== bbtool
->getCurrentDesktopNr()))) {
132 bbtool
->wminterface
->setWindowFocus(it
.current()->win
);
134 // okay, an explanation is in order... First, we have to
135 // hide our window so that focusWindow() actually does
137 // Next, if the window to focus is on a different desktop than
138 // the current one, we need to switch there.
139 // Then we XRaiseWindow, because if we did
140 // focusWindow() first, we'd then XRaise() the wrong window.
141 // Lastly, we update bbkey's stack with what we just
144 if (bbtool
->getCurrentDesktopNr() != it
.current()->desktop
)
145 bbtool
->wminterface
->changeDesktop(it
.current()->desktop
, False
);
146 XRaiseWindow(bbtool
->getXDisplay(), it
.current()->win
);
147 bbtool
->focusWindow(it
.current()->win
);
156 void Stackmenu::key_press(int grabInt
)
160 case grabNextWindowAllWorkspaces
:
161 if(++menuPosition
>= getCount())
163 setSelected(menuPosition
);
164 selectFocused(False
);
167 if(--menuPosition
< 0)
168 menuPosition
= getCount() - 1;
169 setSelected(menuPosition
);
170 selectFocused(False
);
177 void Stackmenu::hide()
179 XUngrabKeyboard(bbtool
->getXDisplay(), CurrentTime
);
181 bbtool
->setCycling(False
);
184 void Stackmenu::show(bool forward
, bool showMenu
)
187 if (getCount() < 1) return; // no windows, just return
188 if (getCount() == 1) {
189 // only 1 window, focus it and leave
190 LinkedListIterator
<WindowList
> it(bbtool
->windowList
);
191 for (; it
.current(); it
++)
192 if (it
.current()->desktop
== bbtool
->getCurrentDesktopNr())
193 bbtool
->wminterface
->setWindowFocus(it
.current()->win
);
197 XRaiseWindow(bbtool
->getXDisplay(), getWindowID());
198 XGrabKeyboard(bbtool
->getXDisplay(),
199 bbtool
->getScreenInfo(0)->getRootWindow(), True
,
200 GrabModeAsync
, GrabModeAsync
, CurrentTime
);
203 key_press(forward
?grabNextWindow
:grabPrevWindow
);
205 bbtool
->setCycling(True
);
213 void Stackmenu::centerPosition()
215 int x
= (bbtool
->getCurrentScreenInfo()->getWidth()>>1) - (getWidth()>>1);
216 int y
= (bbtool
->getCurrentScreenInfo()->getHeight()>>1) - (getHeight()>>1);
218 Basemenu::move(x
, y
);
221 void Stackmenu::setSelected(int sel
)
223 if ((sel
<0) || (sel
>=getCount())) return;