adding program name to all logging
[bbkeys.git] / src / WindowlistMenu.cpp
blob84b1973ffe6971496f4efe357f330af0f9e200c8
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // -- WindowlistMenu.cpp --
3 // Copyright (c) 2001 - 2003 Jason 'vanRijn' Kasper <vR at movingparts dot net>
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
23 // E_O_H_VR
25 #include "WindowlistMenu.h"
26 //--------------------------------------------------------
27 // Constructor/Destructor
28 //--------------------------------------------------------
29 WindowlistMenu::WindowlistMenu (ScreenHandler * s) :
30 bt::Menu( s->getKeyClient().getMainApplication(),
31 s->getScreenNumber() ) {
32 _screen = s;
33 _keybindings = s->getKeyClient().getKeybindings();
34 _display = s->getKeyClient().XDisplay();
35 _config = s->getKeyClient().getConfig();
36 _debug = _config->getBoolValue("debug", false);
37 _screen_info = & s->getScreenInfo();
38 _honor_modifiers = _config->getBoolValue("honormodifiers", false);
39 _screen->getKeyClient().getLockModifiers(numLockMask, scrollLockMask);
42 void WindowlistMenu::keyPressEvent (const XKeyEvent * const e) {
44 unsigned int state = e->state;
46 if (_debug)
47 std::cout << BBTOOL << ": " << "WindowlistMenu: got keyPressEvent!" << std::endl;
49 if (!_honor_modifiers) {
50 state = e->state & ~(LockMask|scrollLockMask|numLockMask);
53 const Action *it = _keybindings->getAction(e, state, _screen);
55 if (it) {
56 switch (it->type()) {
58 case Action::nextWindow:
59 case Action::nextWindowOnAllWorkspaces:
60 case Action::nextWindowOnAllScreens:
61 case Action::nextWindowOfClass:
62 case Action::nextWindowOfClassOnAllWorkspaces:
63 selectNext();
64 break;
66 case Action::prevWindow:
67 case Action::prevWindowOnAllWorkspaces:
68 case Action::prevWindowOnAllScreens:
69 case Action::prevWindowOfClass:
70 case Action::prevWindowOfClassOnAllWorkspaces:
71 selectPrevious();
72 break;
74 default:
75 break;
79 // if the user is cancelling the menu/cycle, then set focus back on the
80 // window they started with.
81 if (e->keycode == XKeysymToKeycode(_display, XK_Escape)) {
82 XWindow * win = dynamic_cast<XWindow *>(*_windowList.begin());
83 win->focus(true);
84 } else if (e->keycode == XKeysymToKeycode(_display, XK_Up)) {
85 selectPrevious(false);
86 } else if (e->keycode == XKeysymToKeycode(_display, XK_Down)) {
87 selectNext(false);
90 bt::Menu::keyPressEvent(e);
94 void WindowlistMenu::keyReleaseEvent (const XKeyEvent * const e) {
96 if (_debug)
97 std::cout << BBTOOL << ": " << "WindowlistMenu: got keyReleaseEvent!" << std::endl;
99 if (_screen->nothingIsPressed() ){
100 // get what window is selected so we can focus it
101 XWindow * win = getSelectedWindow();
103 bt::Menu::hide();
104 _screen->keyReleaseEvent(e);
106 // if the user is ending his window-cycling adventure, then raise the window
107 // for him.
108 if (win)
109 _screen->focusWindow(win);
112 bt::Menu::keyReleaseEvent(e);
116 void WindowlistMenu::showCycleMenu( WindowList theList ) {
118 bt::Menu::clear();
119 bt::Menu::setTitle("Switch To...");
120 bt::Menu::showTitle();
122 _windowList = theList;
124 WindowList::const_iterator it;
125 const WindowList::const_iterator end = theList.end();
127 // first, find out if we have any windows in our list for anything other
128 // than the current desktop
129 _desktop_nbr = _screen->getDesktopNumber();
130 bool onlyThisDesktop = true;
131 for (it = theList.begin(); it != end; it++) {
132 unsigned int dNbr = (*it)->desktop();
133 if ( (dNbr != _desktop_nbr) && (! (*it)->isSticky()) ) {
134 onlyThisDesktop = false;
135 break;
139 // now add the windows to our list
140 unsigned int i = 0;
142 for (it = theList.begin(); it != end; it++) {
143 std::string title = (*it)->title();
144 unsigned int dNbr = (*it)->desktop();
145 std::string newTitle = bt::ellideText(title, 100, " ... ");
146 if (! onlyThisDesktop) {
147 std::string suffix = _screen->getDesktopName(dNbr);
148 if (suffix.size() > 0)
149 newTitle += " (" + suffix + ")";
151 bt::Menu::insertItem( newTitle, i++ );
154 // this is our current window, before cycling. set it checked as a
155 // visual indicator
156 bt::Menu::setItemChecked(0, true);
158 int x = _config->getNumberValue("cyclemenux", _screen_info->width() /2);
159 int y = _config->getNumberValue("cyclemenuy", _screen_info->height() /2);
161 // now show the menu
162 bt::Menu::popup(x, y, false);
163 bt::Menu::move(x,y);
165 // reset our marker as we will increment it in selectNext...
166 _current_index = -1;
168 // we don't have anything selected initially, so we need to set the
169 // selection to the second one (the first one is the
170 // currently-selected window
171 selectNext();
172 selectNext();
176 void WindowlistMenu::itemClicked(unsigned int id, unsigned int button) {
178 WindowList::const_iterator it = _windowList.begin();
179 const WindowList::const_iterator end = _windowList.end();
181 unsigned int x = 0;
182 for (; it != end; ++it) {
183 XWindow * const win = dynamic_cast<XWindow *>(*it);
184 if ( id == x++ ) {
185 _screen->focusWindow(win);
191 void WindowlistMenu::selectNext(bool manual) {
193 // keep track of where we are...
194 trackIndex(1);
196 XWindow * win = getSelectedWindow();
197 if (win) win->focus(false);
199 if (manual) {
200 XKeyEvent neo;
201 KeyCode keyCode = XKeysymToKeycode(_display, XK_Down);
202 neo.keycode = keyCode;
203 bt::Menu::keyPressEvent(&neo);
208 void WindowlistMenu::selectPrevious(bool manual) {
210 // keep track of where we are now...
211 trackIndex(-1);
213 XWindow * win = getSelectedWindow();
214 if (win) win->focus(false);
216 if (manual) {
217 XKeyEvent neo;
218 KeyCode keyCode = XKeysymToKeycode(_display, XK_Up);
219 neo.keycode = keyCode;
220 bt::Menu::keyPressEvent(&neo);
225 void WindowlistMenu::trackIndex (const int movement) {
227 if (movement > 0) {
228 if (static_cast<unsigned int>(++_current_index) >= _windowList.size() )
229 _current_index = 0;
230 } else {
231 if (--_current_index < 0)
232 _current_index = _windowList.size() -1;
237 XWindow * WindowlistMenu::getSelectedWindow() {
239 WindowList::const_iterator it = _windowList.begin();
240 const WindowList::const_iterator end = _windowList.end();
242 XWindow * win = 0;
244 unsigned int x = 0;
245 for (; it != end; it++) {
246 if ( static_cast<unsigned int>(_current_index) == x++ ) {
247 win = dynamic_cast<XWindow *>(*it);
251 if (0 == win)
252 std::cerr << BBTOOL << ": " << "WindowlistMenu: getSelectedWindow--couldn't get window. this won't turn out well.\n";
254 if (_debug && win)
255 std::cout << BBTOOL << ": " << "WindowlistMenu: getSelectedWindow: currently-selected window: ["
256 << win->title() << "]\n";
257 return win;