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>
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.
25 #include "WindowlistMenu.h"
26 //--------------------------------------------------------
27 // Constructor/Destructor
28 //--------------------------------------------------------
29 WindowlistMenu::WindowlistMenu (ScreenHandler
* s
) :
30 bt::Menu( s
->getKeyClient().getMainApplication(),
31 s
->getScreenNumber() ) {
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
;
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
);
58 case Action::nextWindow
:
59 case Action::nextWindowOnAllWorkspaces
:
60 case Action::nextWindowOnAllScreens
:
61 case Action::nextWindowOfClass
:
62 case Action::nextWindowOfClassOnAllWorkspaces
:
66 case Action::prevWindow
:
67 case Action::prevWindowOnAllWorkspaces
:
68 case Action::prevWindowOnAllScreens
:
69 case Action::prevWindowOfClass
:
70 case Action::prevWindowOfClassOnAllWorkspaces
:
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());
84 } else if (e
->keycode
== XKeysymToKeycode(_display
, XK_Up
)) {
85 selectPrevious(false);
86 } else if (e
->keycode
== XKeysymToKeycode(_display
, XK_Down
)) {
90 bt::Menu::keyPressEvent(e
);
94 void WindowlistMenu::keyReleaseEvent (const XKeyEvent
* const e
) {
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();
104 _screen
->keyReleaseEvent(e
);
106 // if the user is ending his window-cycling adventure, then raise the window
109 _screen
->focusWindow(win
);
112 bt::Menu::keyReleaseEvent(e
);
116 void WindowlistMenu::showCycleMenu( WindowList theList
) {
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;
139 // now add the windows to our list
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
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);
162 bt::Menu::popup(x
, y
, false);
165 // reset our marker as we will increment it in selectNext...
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
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();
182 for (; it
!= end
; ++it
) {
183 XWindow
* const win
= dynamic_cast<XWindow
*>(*it
);
185 _screen
->focusWindow(win
);
191 void WindowlistMenu::selectNext(bool manual
) {
193 // keep track of where we are...
196 XWindow
* win
= getSelectedWindow();
197 if (win
) win
->focus(false);
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...
213 XWindow
* win
= getSelectedWindow();
214 if (win
) win
->focus(false);
218 KeyCode keyCode
= XKeysymToKeycode(_display
, XK_Up
);
219 neo
.keycode
= keyCode
;
220 bt::Menu::keyPressEvent(&neo
);
225 void WindowlistMenu::trackIndex (const int movement
) {
228 if (static_cast<unsigned int>(++_current_index
) >= _windowList
.size() )
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();
245 for (; it
!= end
; it
++) {
246 if ( static_cast<unsigned int>(_current_index
) == x
++ ) {
247 win
= dynamic_cast<XWindow
*>(*it
);
252 std::cerr
<< BBTOOL
<< ": " << "WindowlistMenu: getSelectedWindow--couldn't get window. this won't turn out well.\n";
255 std::cout
<< BBTOOL
<< ": " << "WindowlistMenu: getSelectedWindow: currently-selected window: ["
256 << win
->title() << "]\n";