fixing parse error in execcommand
[bbkeys.git] / src / stackmenu.cc
blob3d0f53f1a63e10b54a1b1823d6938e4cee796fe5
1 // cycling.cc for bbkeys
2 //
3 // Copyright (c) 2001 by Ben Jansens <xor@orodu.net>
4 // Copyright (c) 2001 by Jason Kasper (vanRijn) <vR@movingparts.net>
5 //
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)
22 // $Id$
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif // HAVE_CONFIG_H
28 #include "stackmenu.hh"
29 #include "bbkeys.hh"
30 #include "LinkedList.hh"
31 #include "wminterface.hh"
33 extern "C" {
34 #include <X11/Xutil.h>
37 Stackmenu::Stackmenu(ToolWindow *tool) :
38 Basemenu(tool)
40 bbtool = tool;
42 setTitleVisibility(False);
43 setMovable(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;
61 char **list;
62 char *title=0;
63 int num;
65 LinkedListIterator<WindowList> it(bbtool->windowList);
67 clearMenu();
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()))) {
76 if (title) {
77 delete [] title;
78 title = 0;
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) &&
89 (num > 0) && *list) {
90 title = bstrdup(*list);
91 XFreeStringList(list);
92 } else
93 title = bstrdup((char *) text_prop.value);
94 } else
95 title = bstrdup((char *) text_prop.value);
97 XFree((char *) text_prop.value);
98 } else
99 title = bstrdup( "Unnamed");
100 } else
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);
107 if (workspace) {
108 snprintf(workspace, size, "%s (workspace %i)", title,
109 it.current()->desktop+1);
110 insert(workspace);
111 free(workspace);
113 } else
114 insert(title);
119 void Stackmenu::clearMenu() {
120 while (getCount())
121 remove(0);
124 void Stackmenu::selectFocused(bool raise)
126 if ( raise )
127 hide();
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()))) {
138 if(!selected--) {
139 bbtool->wminterface->setWindowFocus(it.current()->win);
140 if ( raise ) {
141 // okay, an explanation is in order... First, we have to
142 // hide our window so that focusWindow() actually does
143 // anything.
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
149 // raised...
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)
161 switch (grabInt) {
162 case grabNextWindow:
163 case grabNextWindowAllWorkspaces:
164 if(++menuPosition >= getCount())
165 menuPosition = 0;
166 setSelected(menuPosition);
167 selectFocused(False);
168 break;
169 case grabPrevWindow:
170 if(--menuPosition < 0)
171 menuPosition = getCount() - 1;
172 setSelected(menuPosition);
173 selectFocused(False);
174 break;
175 default:
176 break;
180 void Stackmenu::hide()
182 XUngrabKeyboard(bbtool->getXDisplay(), CurrentTime);
183 Basemenu::hide();
184 bbtool->setCycling(False);
188 void Stackmenu::show(void)
190 Basemenu::show();
194 void Stackmenu::show(bool forward, bool showMenu)
196 setMenuItems();
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);
204 return;
207 XRaiseWindow(bbtool->getXDisplay(), getWindowID());
208 XGrabKeyboard(bbtool->getXDisplay(),
209 bbtool->getScreenInfo(0)->getRootWindow(), True,
210 GrabModeAsync, GrabModeAsync, CurrentTime);
212 menuPosition = 0;
213 key_press(forward?grabNextWindow:grabPrevWindow);
215 bbtool->setCycling(True);
217 if (showMenu) {
218 show();
219 centerPosition();
223 void Stackmenu::centerPosition()
225 int x = (bbtool->getCurrentScreenInfo()->getWidth()>>1) - (getWidth()>>1);
226 int y = (bbtool->getCurrentScreenInfo()->getHeight()>>1) - (getHeight()>>1);
227 if (x>0 && y>0)
228 Basemenu::move(x, y);
231 void Stackmenu::setSelected(int sel)
233 if ((sel<0) || (sel>=getCount())) return;
234 setHighlight(sel);
235 update();