"Fossies" - the Fresh Open Source Software Archive

Member "bbkeys-0.9.1/src/WindowlistMenu.cpp" (6 Dec 2007, 7928 Bytes) of package /linux/privat/old/bbkeys-0.9.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "WindowlistMenu.cpp" see the Fossies "Dox" file reference documentation.

    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:
   11 //
   12 // The above copyright notice and this permission notice shall be included in
   13 // all copies or substantial portions of the Software.
   14 //
   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.
   22 
   23 // E_O_H_VR
   24 
   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);
   40   _menu_title = _config->getStringValue("cyclemenutitle", "Switch To...");
   41 }
   42 
   43 void WindowlistMenu::keyPressEvent (const XKeyEvent * const e) {
   44 
   45   unsigned int state = e->state;
   46 
   47   if (_debug)
   48     std::cout << BBTOOL << ": " << "WindowlistMenu: got keyPressEvent!" << std::endl;
   49 
   50   if (!_honor_modifiers) {
   51     state = e->state & ~(LockMask|scrollLockMask|numLockMask);
   52   }
   53 
   54   const Action *it = _keybindings->getAction(e, state, _screen);
   55 
   56   if (it) {
   57     switch (it->type()) {
   58 
   59     case Action::nextWindow:
   60     case Action::nextWindowOnAllWorkspaces:
   61     case Action::nextWindowOnAllScreens:
   62     case Action::nextWindowOfClass:
   63     case Action::nextWindowOfClassOnAllWorkspaces:
   64       selectNext();
   65       break;
   66 
   67     case Action::prevWindow:
   68     case Action::prevWindowOnAllWorkspaces:
   69     case Action::prevWindowOnAllScreens:
   70     case Action::prevWindowOfClass:
   71     case Action::prevWindowOfClassOnAllWorkspaces:
   72       selectPrevious();
   73       break;
   74 
   75     default:
   76       break;
   77     }
   78   }
   79 
   80   // if the user is cancelling the menu/cycle, then set focus back on the
   81   // window they started with.
   82   if (e->keycode == XKeysymToKeycode(_display, XK_Escape)) {
   83     XWindow * win = dynamic_cast<XWindow *>(*_windowList.begin());
   84     win->focus();
   85   } else if (e->keycode == XKeysymToKeycode(_display, XK_Up)) {
   86     selectPrevious(false);
   87   } else if (e->keycode == XKeysymToKeycode(_display, XK_Down)) {
   88     selectNext(false);
   89   }
   90 
   91   bt::Menu::keyPressEvent(e);
   92 
   93 }
   94 
   95 void WindowlistMenu::keyReleaseEvent (const XKeyEvent * const e) {
   96 
   97   if (_debug)
   98     std::cout << BBTOOL << ": " << "WindowlistMenu: got keyReleaseEvent!" << std::endl;
   99 
  100   if (_screen->nothingIsPressed() ){
  101     // get what window is selected so we can focus it
  102     XWindow * win = getSelectedWindow();
  103 
  104     bt::Menu::hide();
  105     _screen->keyReleaseEvent(e);
  106 
  107     // if the user is ending his window-cycling adventure, then raise the window
  108     // for him.
  109     if (win)
  110       win->focus();
  111   }
  112 
  113   bt::Menu::keyReleaseEvent(e);
  114 
  115 }
  116 
  117 void WindowlistMenu::showCycleMenu( WindowList theList ) {
  118 
  119   bt::Menu::clear();
  120   bt::Menu::setTitle(bt::toUnicode(_menu_title));
  121   if (_menu_title.length() > 0)
  122     bt::Menu::showTitle();
  123 
  124   _windowList = theList;
  125 
  126   WindowList::const_iterator it;
  127   const WindowList::const_iterator end = theList.end();
  128 
  129   // first, find out if we have any windows in our list for anything other
  130   // than the current desktop
  131   _desktop_nbr = _screen->getDesktopNumber();
  132   bool onlyThisDesktop = true;
  133   for (it = theList.begin(); it != end; it++) {
  134     unsigned int dNbr = (*it)->desktop();
  135     if ( (dNbr != _desktop_nbr) && (! (*it)->isSticky()) ) {
  136       onlyThisDesktop = false;
  137       break;
  138     }
  139   }
  140 
  141   // now add the windows to our list
  142   unsigned int i = 0;
  143 
  144   for (it = theList.begin(); it != end; it++) {
  145       XWindow *win = (*it);
  146       bt::ustring title = win->title();
  147       unsigned int dNbr = win->desktop();
  148       bt::ustring newTitle = bt::ellideText(title, 100, bt::toUnicode(" ... "));
  149       if (! onlyThisDesktop) {
  150           bt::ustring suffix = _screen->getDesktopName(dNbr);
  151           if (suffix.size() > 0) {
  152               newTitle.append(bt::toUnicode(" ("));
  153               newTitle.append(suffix);
  154               newTitle.append(bt::toUnicode(")"));
  155           }
  156       }
  157       if (win->iconic()) {
  158           newTitle.insert(0, bt::toUnicode("("));
  159           newTitle.append(bt::toUnicode(")"));
  160       }
  161 
  162       bt::Menu::insertItem( newTitle, i++ );
  163   }
  164 
  165   // this is our current window, before cycling.  set it checked as a
  166   // visual indicator
  167   bt::Menu::setItemChecked(0, true);
  168 
  169   int x = _config->getNumberValue("cyclemenux", 20);
  170   int y = _config->getNumberValue("cyclemenuy", 20);
  171 
  172   // now show the menu
  173   bt::Menu::popup(x, y, false);
  174   bt::Menu::move(x,y);
  175 
  176   // reset our marker as we will increment it in selectNext...
  177   _current_index = -1;
  178 
  179   // we don't have anything selected initially, so we need to set the
  180   // selection to the second one (the first one is the
  181   // currently-selected window
  182   selectNext();
  183   selectNext();
  184 
  185 }
  186 
  187 void WindowlistMenu::itemClicked(unsigned int id, unsigned int button) {
  188 
  189   WindowList::const_iterator it = _windowList.begin();
  190   const WindowList::const_iterator end = _windowList.end();
  191 
  192   unsigned int x = 0;
  193   for (; it != end; ++it) {
  194     XWindow * const win = dynamic_cast<XWindow *>(*it);
  195     if ( id == x++ ) {
  196       win->focus();
  197     }
  198   }
  199 
  200 }
  201 
  202 void WindowlistMenu::selectNext(bool manual) {
  203 
  204   // keep track of where we are...
  205   trackIndex(1);
  206 
  207   XWindow * win = getSelectedWindow();
  208   if (win) _screen->focusWindow(win);
  209 
  210   if (manual) {
  211     XKeyEvent neo;
  212     KeyCode keyCode = XKeysymToKeycode(_display, XK_Down);
  213     neo.keycode = keyCode;
  214     bt::Menu::keyPressEvent(&neo);
  215   }
  216 
  217 }
  218 
  219 void WindowlistMenu::selectPrevious(bool manual) {
  220 
  221   // keep track of where we are now...
  222   trackIndex(-1);
  223 
  224   XWindow * win = getSelectedWindow();
  225   if (win) _screen->focusWindow(win);
  226 
  227   if (manual) {
  228     XKeyEvent neo;
  229     KeyCode keyCode = XKeysymToKeycode(_display, XK_Up);
  230     neo.keycode = keyCode;
  231     bt::Menu::keyPressEvent(&neo);
  232   }
  233 
  234 }
  235 
  236 void WindowlistMenu::trackIndex (const int movement) {
  237 
  238   if (movement > 0) {
  239     if (static_cast<unsigned int>(++_current_index) >= _windowList.size() )
  240       _current_index = 0;
  241   } else {
  242     if (--_current_index < 0)
  243       _current_index = _windowList.size() -1;
  244   }
  245 
  246 }
  247 
  248 XWindow * WindowlistMenu::getSelectedWindow() {
  249 
  250   WindowList::const_iterator it = _windowList.begin();
  251   const WindowList::const_iterator end = _windowList.end();
  252 
  253   XWindow * win = 0;
  254 
  255   unsigned int x = 0;
  256   for (; it != end; it++) {
  257     if ( static_cast<unsigned int>(_current_index) == x++ ) {
  258       win = dynamic_cast<XWindow *>(*it);
  259     }
  260   }
  261 
  262   if (0 == win)
  263     std::cerr << BBTOOL << ": " << "WindowlistMenu: getSelectedWindow--couldn't get window.  this won't turn out well.\n";
  264 
  265   if (_debug && win)
  266     std::cout << BBTOOL << ": " << "WindowlistMenu: getSelectedWindow: currently-selected window: ["
  267               << bt::toLocale(win->title()) << "]\n";
  268   return win;
  269 
  270 }