This adds a config parser, chaining, and a tonne of other stuff.
Still need to fix up build system for the lex and yacc stuff.
EXTRA_PROGRAMS = epist
-epist_SOURCES = epist.cc window.cc screen.cc main.cc actions.cc
+epist_SOURCES = epist.cc window.cc screen.cc main.cc actions.cc yacc_parser.cc parser.cc keytree.cc lex.yy.c
epist_LDADD = ../../src/XAtom.o ../../src/BaseDisplay.o \
../../src/Util.o ../../src/i18n.o \
../../src/GCCache.o ../../src/Color.o ../../src/Texture.o \
../../src/BaseDisplay.hh ../../src/Timer.hh ../../src/Util.hh
window.o: window.cc window.hh epist.hh ../../src/BaseDisplay.hh \
../../src/Timer.hh ../../src/Util.hh ../../src/XAtom.hh
+yacc_parser.o: yacc_parser.cc yacc_parser.hh epist.hh ../../src/BaseDisplay.hh \
+ ../../src/Timer.hh ../../src/Util.hh ../../src/XAtom.hh
+keytree.o: keytree.cc keytree.hh epist.hh ../../src/BaseDisplay.hh \
+ ../../src/Timer.hh ../../src/Util.hh ../../src/XAtom.hh
+parser.o: parser.cc parser.hh epist.hh ../../src/BaseDisplay.hh \
+ ../../src/Timer.hh ../../src/Util.hh ../../src/XAtom.hh
+lex.yy.o: lex.yy.c
#include "actions.hh"
-Action::Action(enum ActionType type, KeyCode keycode, unsigned int modifierMask,
- int num)
- : _type(type), _keycode(keycode),
- _modifierMask(modifierMask), _numberParam(num)
-{ }
-
Action::Action(enum ActionType type, KeyCode keycode, unsigned int modifierMask,
const std::string &str)
- : _type(type), _keycode(keycode),
- _modifierMask(modifierMask), _stringParam(str)
-{ }
+ : _type(type), _keycode(keycode), _modifierMask(modifierMask)
+{
+ // These are the action types that take string arguments. This
+ // should probably be moved to a static member
+ ActionType str_types[] = {
+ execute,
+ nextWindowOfClass,
+ prevWindowOfClass,
+ nextWindowOfClassOnAllWorkspaces,
+ prevWindowOfClassOnAllWorkspaces,
+ noaction
+ };
+
+ for (int i = 0; str_types[i] != noaction; ++i) {
+ if (type == str_types[i]) {
+ _stringParam = str;
+ return;
+ }
+ }
+
+ _numberParam = atoi( str.c_str() );
+
+ if (type == changeWorkspace)
+ _numberParam;
+}
const KeyCode _keycode;
const unsigned int _modifierMask;
- const int _numberParam;
- const std::string _stringParam;
+ int _numberParam;
+ std::string _stringParam;
public:
inline enum ActionType type() const { return _type;}
inline const KeyCode keycode() const { return _keycode; }
inline const std::string &string() const { return _stringParam; }
Action(enum ActionType type, KeyCode keycode, unsigned int modifierMask,
- int number = 0);
- Action(enum ActionType type, KeyCode keycode, unsigned int modifierMask,
- const std::string &str);
+ const std::string &str = "");
};
typedef std::list<Action> ActionList;
#include "epist.hh"
#include "screen.hh"
#include "window.hh"
+#include "parser.hh"
#include "../../src/XAtom.hh"
if (rc_file)
_rc_file = rc_file;
else
- _rc_file = expandTilde("~/.openbox/epistrc");
+ _rc_file = expandTilde("~/.epistrc");
_xatom = new XAtom(getXDisplay());
::exit(1);
}
- addAction(Action::nextScreen, ControlMask, "Tab");
- addAction(Action::prevScreen, ControlMask | ShiftMask, "Tab");
- addAction(Action::nextWindow, Mod1Mask, "Tab");
- addAction(Action::prevWindow, Mod1Mask | ShiftMask, "Tab");
- addAction(Action::toggleshade, Mod1Mask, "F5");
- addAction(Action::close, Mod1Mask, "F4");
- addAction(Action::nextWindowOnAllWorkspaces, Mod1Mask | ControlMask, "Tab");
- addAction(Action::prevWindowOnAllWorkspaces,
- Mod1Mask | ShiftMask | ControlMask, "Tab");
- addAction(Action::prevWorkspace, Mod1Mask, "Left");
- addAction(Action::nextWorkspace, Mod1Mask, "Right");
- addAction(Action::raise, Mod1Mask, "Up");
- addAction(Action::lower, Mod1Mask, "Down");
- addAction(Action::moveWindowUp, Mod1Mask | ControlMask, "Up", 1);
- addAction(Action::moveWindowDown, Mod1Mask | ControlMask, "Down", 1);
- addAction(Action::moveWindowLeft, Mod1Mask | ControlMask, "Left", 1);
- addAction(Action::moveWindowRight, Mod1Mask | ControlMask, "Right", 1);
- addAction(Action::resizeWindowHeight, ShiftMask | Mod1Mask | ControlMask,
- "Up", -1);
- addAction(Action::resizeWindowHeight, ShiftMask | Mod1Mask | ControlMask,
- "Down", 1);
- addAction(Action::resizeWindowWidth, ShiftMask | Mod1Mask | ControlMask,
- "Left", -1);
- addAction(Action::resizeWindowWidth, ShiftMask | Mod1Mask | ControlMask,
- "Right", 1);
- addAction(Action::iconify, Mod1Mask | ControlMask, "I");
- addAction(Action::toggleomnipresent, Mod1Mask | ControlMask, "O");
- addAction(Action::toggleMaximizeHorizontal, ShiftMask | Mod1Mask, "X");
- addAction(Action::toggleMaximizeVertical, ShiftMask | ControlMask, "X");
- addAction(Action::toggleMaximizeFull, Mod1Mask | ControlMask, "X");
- addAction(Action::changeWorkspace, Mod1Mask | ControlMask, "1", 0);
- addAction(Action::changeWorkspace, Mod1Mask | ControlMask, "2", 1);
- addAction(Action::changeWorkspace, Mod1Mask | ControlMask, "3", 2);
- addAction(Action::changeWorkspace, Mod1Mask | ControlMask, "4", 3);
- addAction(Action::sendToWorkspace, Mod1Mask | ControlMask | ShiftMask,
- "1", 0);
- addAction(Action::sendToWorkspace, Mod1Mask | ControlMask | ShiftMask,
- "2", 1);
- addAction(Action::sendToWorkspace, Mod1Mask | ControlMask | ShiftMask,
- "3", 2);
- addAction(Action::sendToWorkspace, Mod1Mask | ControlMask | ShiftMask,
- "4", 3);
- addAction(Action::execute, Mod1Mask | ControlMask, "Escape",
- "sleep 1 && xset dpms force off");
- addAction(Action::execute, Mod1Mask, "space",
- "rxvt");
+ _ktree = new keytree(getXDisplay());
+
+ // set up the key tree
+ parser p(_ktree);
+ p.parse(_rc_file);
activateGrabs();
}
ScreenList::const_iterator scrit, scrend = _screens.end();
- for (scrit = _screens.begin(); scrit != scrend; ++scrit) {
- ActionList::const_iterator ait, end = _actions.end();
-
- for(ait = _actions.begin(); ait != end; ++ait) {
- (*scrit)->grabKey(ait->keycode(), ait->modifierMask());
- }
- }
+ for (scrit = _screens.begin(); scrit != scrend; ++scrit)
+ _ktree->grabDefaults(*scrit);
}
const XWindow *target = _screens[dest]->lastActiveWindow();
if (target) target->focus();
}
-
-
-void epist::addAction(Action::ActionType act, unsigned int modifiers,
- string key, int number) {
- _actions.push_back(Action(act, XKeysymToKeycode(getXDisplay(),
- XStringToKeysym(key.c_str())),
- modifiers, number));
-}
-
-
-void epist::addAction(Action::ActionType act, unsigned int modifiers,
- string key, string str) {
- _actions.push_back(Action(act, XKeysymToKeycode(getXDisplay(),
- XStringToKeysym(key.c_str())),
- modifiers, str));
-}
#include "actions.hh"
#include "window.hh"
+#include "keytree.hh"
#include "../../src/BaseDisplay.hh"
std::string _rc_file;
XAtom *_xatom;
char **_argv;
+ keytree *_ktree;
typedef std::vector<screen *> ScreenList;
ScreenList _screens;
virtual bool handleSignal(int sig);
void activateGrabs();
- void addAction(Action::ActionType act, unsigned int modifiers,
- std::string key, int number = 0);
- void addAction(Action::ActionType act, unsigned int modifiers,
- std::string key, std::string str);
public:
epist(char **argv, char *display_name, char *rc_file);
}
const ActionList &actions(void) { return _actions; }
+ keytree &getKeyTree(void) { return *_ktree; }
WindowList& clientsList() { return _clients; }
WindowList::iterator& activeWindow() { return _active; }
--- /dev/null
+%{
+#include <stdio.h>
+#include <string.h>
+#include "parser.hh"
+
+#define YYPARSE_PARAM parser_obj
+#define YYSTYPE char*
+
+extern "C" {
+ int yylex();
+ int yywrap() {
+ return 1;
+ }
+}
+
+void yyerror(const char *c) {
+ printf("ERROR: %s\n", c);
+}
+
+
+%}
+
+%token OBRACE EBRACE SEMICOLON DASH ACTION BINDING NUMBER QUOTES WORD
+
+%%
+
+commands:
+ | commands command
+ ;
+
+command:
+ action_command | chain_command
+ ;
+
+action_command:
+ binding ACTION parameter SEMICOLON
+ {
+ ((parser*)parser_obj)->setAction($2);
+ ((parser*)parser_obj)->endAction();
+ }
+
+ ;
+
+chain_command:
+ binding obrace commands ebrace
+ {
+ ((parser*)parser_obj)->endChain();
+ }
+ ;
+
+binding:
+ binding_w_modifier bind_key
+ ;
+
+obrace:
+ OBRACE { ((parser*)parser_obj)->startChain(); }
+ ;
+
+ebrace:
+ EBRACE { /* ((parser*)parser_obj)->endChain(); */ }
+ ;
+
+binding_w_modifier:
+ | BINDING DASH binding_w_modifier { ((parser*)parser_obj)->addModifier($1); }
+ ;
+
+bind_key:
+ OBRACE { ((parser*)parser_obj)->setKey($1); }
+ | EBRACE { ((parser*)parser_obj)->setKey($1); }
+ | DASH { ((parser*)parser_obj)->setKey($1); }
+ | SEMICOLON { ((parser*)parser_obj)->setKey($1); }
+ | NUMBER { ((parser*)parser_obj)->setKey($1); }
+ | WORD { ((parser*)parser_obj)->setKey($1); }
+ ;
+
+parameter:
+ | NUMBER { ((parser*)parser_obj)->setArgument($1); }
+ | DASH NUMBER { ((parser*)parser_obj)->setArgument($1); }
+ | QUOTES { ((parser*)parser_obj)->setArgument($1); }
+ ;
+
+%%
+
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// keytree.cc for Epistophy - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include "keytree.hh"
+
+keytree::keytree(Display *display) : _display(display)
+{
+ _head = new keynode;
+ _head->parent = NULL;
+ _head->action = NULL; // head's action is always NULL
+ _current = _head;
+}
+
+keytree::~keytree()
+{
+ clearTree(_head);
+}
+
+void keytree::clearTree(keynode *node)
+{
+ if (!node)
+ return;
+
+ ChildList::iterator it, end = node->children.end();
+ for (it = node->children.begin(); it != end; ++it)
+ clearTree(*it);
+
+ if (node->action)
+ delete node->action;
+ delete node;
+}
+
+void keytree::grabDefaults(screen *scr)
+{
+ grabChildren(_head, scr);
+}
+
+void keytree::grabChildren(keynode *node, screen *scr)
+{
+ ChildList::const_iterator it, end = node->children.end();
+ for (it = node->children.begin(); it != end; ++it)
+ if ( (*it)->action )
+ scr->grabKey( (*it)->action->keycode(), (*it)->action->modifierMask() );
+}
+
+void keytree::ungrabChildren(keynode *node, screen *scr)
+{
+ ChildList::const_iterator it, end = node->children.end();
+ for (it = node->children.begin(); it != end; ++it)
+ if ( (*it)->action )
+ scr->ungrabKey( (*it)->action->keycode(), (*it)->action->modifierMask());
+}
+
+const Action * keytree::getAction(const XEvent &e, unsigned int state,
+ screen *scr)
+{
+ Action *act;
+
+ if (_current != _head)
+ ungrabChildren(_current, scr);
+
+ ChildList::const_iterator it, end = _current->children.end();
+ for (it = _current->children.begin(); it != end; ++it) {
+ act = (*it)->action;
+ if (e.xkey.keycode == act->keycode() && state == act->modifierMask()) {
+ if ( isLeaf(*it) ) {
+ if (_current != _head)
+ ungrabChildren(_current, scr);
+ _current = _head;
+ return act;
+ }
+ else {
+ _current = *it;
+ grabChildren(_current, scr);
+ return (const Action *)NULL;
+ }
+ }
+ }
+
+ // action not found. back to the head
+ _current = _head;
+ return (const Action *)NULL;
+}
+
+void keytree::addAction(Action::ActionType action, unsigned int mask,
+ string key, string arg)
+{
+ // can't grab non-modifier as topmost key
+ if (_current == _head && (mask == 0 || mask == ShiftMask))
+ return;
+
+ keynode *tmp = new keynode;
+ tmp->action = new Action(action,
+ XKeysymToKeycode(_display,
+ XStringToKeysym(key.c_str())),
+ mask, arg);
+ tmp->parent = _current;
+ _current->children.push_back(tmp);
+}
+
+void keytree::advanceOnNewNode()
+{
+ keynode *tmp = new keynode;
+ tmp->action = NULL;
+ tmp->parent = _current;
+ _current->children.push_back(tmp);
+ _current = tmp;
+}
+
+void keytree::retract()
+{
+ if (_current != _head)
+ _current = _current->parent;
+}
+
+void keytree::setCurrentNodeProps(Action::ActionType action, unsigned int mask,
+ string key, string arg)
+{
+ if (_current->action)
+ delete _current->action;
+ _current->action = new Action(action,
+ XKeysymToKeycode(_display,
+ XStringToKeysym(key.c_str())),
+ mask, arg);
+}
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// keytree.hh for Epistophy - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef _keytree_hh
+#define _keytree_hh
+
+#include <list>
+#include "actions.hh"
+#include "screen.hh"
+
+struct keynode; // forward declaration
+typedef std::list<keynode *> ChildList;
+
+struct keynode {
+ Action *action;
+ keynode *parent;
+ ChildList children;
+};
+
+class keytree {
+public:
+ keytree(Display *);
+ ~keytree();
+
+ void grabDefaults(screen *);
+ const Action * getAction(const XEvent&, unsigned int, screen *);
+
+private:
+ // only mister parser needs to know about our sekrets (BUMMY)
+ friend class parser;
+
+ void grabChildren(keynode *, screen *);
+ void ungrabChildren(keynode *, screen *);
+
+ void addAction(Action::ActionType, unsigned int, std::string, std::string);
+ void advanceOnNewNode();
+ void retract();
+ void setCurrentNodeProps(Action::ActionType, unsigned int, std::string, std::string);
+
+ void reset()
+ { _current = _head; }
+
+ bool isLeaf(keynode *node)
+ { return node->children.empty(); }
+
+ void clearTree(keynode *);
+
+ keynode *_head;
+ keynode *_current;
+ Display *_display;
+};
+
+#endif // _keytree_hh
--- /dev/null
+extern "C" {
+#include <stdio.h>
+}
+#include "parser.hh"
+
+parser::parser(keytree *kt)
+ : _mask(0), _action(Action::noaction), _key(""), _arg(""), _kt(kt)
+{
+}
+
+parser::~parser()
+{
+ // nothing to see here. move along.
+}
+
+void parser::parse(string rc_file)
+{
+ extern int yyparse(void *);
+ extern FILE *yyin;
+
+ yyin = fopen(rc_file.c_str(), "r");
+
+ yyparse(this);
+
+ fclose(yyin);
+ _kt->reset();
+}
+
+void parser::setAction(string act)
+{
+ struct {
+ string str;
+ Action::ActionType act;
+ }
+ actions[] = {
+ { "noaction", Action::noaction },
+ { "execute", Action::execute },
+ { "iconify", Action::iconify },
+ { "raise", Action::raise },
+ { "lower", Action::lower },
+ { "close", Action::close },
+ { "toggleshade", Action::toggleshade },
+ { "toggleomnipresent", Action::toggleomnipresent },
+ { "moveWindowUp", Action::moveWindowUp },
+ { "moveWindowDown", Action::moveWindowDown },
+ { "moveWindowLeft", Action::moveWindowLeft },
+ { "moveWindowRight", Action::moveWindowRight },
+ { "resizeWindowWidth", Action::resizeWindowWidth },
+ { "resizeWindowHeight", Action::resizeWindowHeight },
+ { "toggleMaximizeFull", Action::toggleMaximizeFull },
+ { "toggleMaximizeVertical", Action::toggleMaximizeVertical },
+ { "toggleMaximizeHorizontal", Action::toggleMaximizeHorizontal },
+ { "sendToWorkspace", Action::sendToWorkspace },
+ { "nextWindow", Action::nextWindow },
+ { "prevWindow", Action::prevWindow },
+ { "nextWindowOnAllWorkspaces", Action::nextWindowOnAllWorkspaces },
+ { "prevWindowOnAllWorkspaces", Action::prevWindowOnAllWorkspaces },
+ { "nextWindowOnAllScreens", Action::nextWindowOnAllScreens },
+ { "prevWindowOnAllScreens", Action::prevWindowOnAllScreens },
+ { "nextWindowOfClass", Action::nextWindowOfClass },
+ { "prevWindowOfClass", Action::prevWindowOfClass },
+ { "nextWindowOfClassOnAllWorkspaces", Action::nextWindowOfClassOnAllWorkspaces },
+ { "prevWindowOfClassOnAllWorkspaces", Action::prevWindowOfClassOnAllWorkspaces },
+ { "changeWorkspace", Action::changeWorkspace },
+ { "nextWorkspace", Action::nextWorkspace },
+ { "prevWorkspace", Action::prevWorkspace },
+ { "nextScreen", Action::nextScreen },
+ { "prevScreen", Action::prevScreen },
+ { "showRootMenu", Action::showRootMenu },
+ { "showWorkspaceMenu", Action::showWorkspaceMenu },
+ { "stringChain", Action::stringChain },
+ { "keyChain", Action::keyChain },
+ { "numberChain", Action::numberChain },
+ { "cancel", Action::cancel },
+ { "", Action::noaction }
+ };
+
+ bool found = false;
+
+ for (int i = 0; actions[i].str != ""; ++i) {
+ if (actions[i].str == act) {
+ _action = actions[i].act;
+ found = true;
+ }
+ }
+
+ if (!found)
+ _action = Action::noaction;
+}
+
+void parser::addModifier(string mod)
+{
+ struct {
+ string str;
+ unsigned int mask;
+ }
+ modifiers[] = {
+ { "Mod1", Mod1Mask },
+ { "Mod2", Mod2Mask },
+ { "Mod3", Mod3Mask },
+ { "Control", ControlMask },
+ { "Shift", ShiftMask },
+ { "", 0 }
+ };
+
+ for (int i = 0; modifiers[i].str != ""; ++i) {
+ if (modifiers[i].str == mod)
+ _mask |= modifiers[i].mask;
+ }
+}
+
+void parser::endAction()
+{
+ _kt->addAction(_action, _mask, _key, _arg);
+ reset();
+}
+
+void parser::startChain()
+{
+ _kt->advanceOnNewNode();
+ setChainBinding();
+ reset();
+}
+
+void parser::endChain()
+{
+ _kt->retract();
+ reset();
+}
+
+void parser::setChainBinding()
+{
+ if (_mask != 0 && _key != "") {
+ _kt->setCurrentNodeProps(Action::noaction, _mask, _key, "");
+ reset();
+ }
+}
+
+void parser::reset()
+{
+ _mask = 0;
+ _action = Action::noaction;
+ _key = "";
+ _arg = "";
+}
--- /dev/null
+#include <string>
+#include "actions.hh"
+#include "keytree.hh"
+
+class parser {
+public:
+ parser(keytree *);
+ ~parser();
+
+ void parse(std::string);
+
+ void setKey(std::string key)
+ { _key = key; }
+
+ void setArgument(std::string arg)
+ { _arg = arg; }
+
+ void setAction(std::string);
+ void addModifier(std::string);
+ void endAction();
+ void startChain();
+ void setChainBinding();
+ void endChain();
+
+private:
+ void reset();
+
+ keytree *_kt;
+ unsigned int _mask;
+ Action::ActionType _action;
+ std::string _key;
+ std::string _arg;
+};
void screen::handleKeypress(const XEvent &e) {
int scrolllockMask, numlockMask;
-
- ActionList::const_iterator it = _epist->actions().begin();
- ActionList::const_iterator end = _epist->actions().end();
-
_epist->getLockModifiers(numlockMask, scrolllockMask);
- for (; it != end; ++it) {
- unsigned int state = e.xkey.state & ~(LockMask|scrolllockMask|numlockMask);
-
- if (e.xkey.keycode == it->keycode() &&
- state == it->modifierMask()) {
- switch (it->type()) {
- case Action::nextScreen:
- _epist->cycleScreen(_number, true);
- return;
-
- case Action::prevScreen:
- _epist->cycleScreen(_number, false);
- return;
-
- case Action::nextWorkspace:
- cycleWorkspace(true);
- return;
+ // Mask out the lock modifiers. We want our keys to always work
+ // This should be made an option
+ unsigned int state = e.xkey.state & ~(LockMask|scrolllockMask|numlockMask);
+ const Action *it = _epist->getKeyTree().getAction(e, state, this);
+
+ if (!it)
+ return;
- case Action::prevWorkspace:
- cycleWorkspace(false);
- return;
+ switch (it->type()) {
+ case Action::nextScreen:
+ _epist->cycleScreen(_number, true);
+ return;
- case Action::nextWindow:
- cycleWindow(true);
- return;
+ case Action::prevScreen:
+ _epist->cycleScreen(_number, false);
+ return;
- case Action::prevWindow:
- cycleWindow(false);
- return;
+ case Action::nextWorkspace:
+ cycleWorkspace(true);
+ return;
- case Action::nextWindowOnAllWorkspaces:
- cycleWindow(true, false, true);
- return;
+ case Action::prevWorkspace:
+ cycleWorkspace(false);
+ return;
- case Action::prevWindowOnAllWorkspaces:
- cycleWindow(false, false, true);
- return;
+ case Action::nextWindow:
+ cycleWindow(true);
+ return;
- case Action::nextWindowOnAllScreens:
- cycleWindow(true, true);
- return;
+ case Action::prevWindow:
+ cycleWindow(false);
+ return;
- case Action::prevWindowOnAllScreens:
- cycleWindow(false, true);
- return;
+ case Action::nextWindowOnAllWorkspaces:
+ cycleWindow(true, false, true);
+ return;
- case Action::nextWindowOfClass:
- cycleWindow(true, false, false, true, it->string());
- return;
+ case Action::prevWindowOnAllWorkspaces:
+ cycleWindow(false, false, true);
+ return;
- case Action::prevWindowOfClass:
- cycleWindow(false, false, false, true, it->string());
- return;
+ case Action::nextWindowOnAllScreens:
+ cycleWindow(true, true);
+ return;
- case Action::nextWindowOfClassOnAllWorkspaces:
- cycleWindow(true, false, true, true, it->string());
- return;
+ case Action::prevWindowOnAllScreens:
+ cycleWindow(false, true);
+ return;
- case Action::prevWindowOfClassOnAllWorkspaces:
- cycleWindow(false, false, true, true, it->string());
- return;
+ case Action::nextWindowOfClass:
+ cycleWindow(true, false, false, true, it->string());
+ return;
- case Action::changeWorkspace:
- changeWorkspace(it->number());
- return;
+ case Action::prevWindowOfClass:
+ cycleWindow(false, false, false, true, it->string());
+ return;
+
+ case Action::nextWindowOfClassOnAllWorkspaces:
+ cycleWindow(true, false, true, true, it->string());
+ return;
+
+ case Action::prevWindowOfClassOnAllWorkspaces:
+ cycleWindow(false, false, true, true, it->string());
+ return;
- case Action::execute:
- execCommand(it->string());
- return;
+ case Action::changeWorkspace:
+ // we subtract one so counting starts at 1 in the config file
+ changeWorkspace(it->number() - 1);
+ return;
- default:
- break;
- }
+ case Action::execute:
+ execCommand(it->string());
+ return;
- // these actions require an active window
- if (_active != _clients.end()) {
- XWindow *window = *_active;
+ default:
+ break;
+ }
- switch (it->type()) {
- case Action::iconify:
+ // these actions require an active window
+ if (_active != _clients.end()) {
+ XWindow *window = *_active;
+
+ switch (it->type()) {
+ case Action::iconify:
window->iconify();
return;
- case Action::close:
+ case Action::close:
window->close();
return;
- case Action::raise:
+ case Action::raise:
window->raise();
return;
- case Action::lower:
+ case Action::lower:
window->lower();
return;
- case Action::sendToWorkspace:
+ case Action::sendToWorkspace:
window->sendTo(it->number());
return;
- case Action::toggleomnipresent:
+ case Action::toggleomnipresent:
if (window->desktop() == 0xffffffff)
window->sendTo(_active_desktop);
else
window->sendTo(0xffffffff);
return;
- case Action::moveWindowUp:
+ case Action::moveWindowUp:
window->move(window->x(), window->y() - it->number());
return;
- case Action::moveWindowDown:
+ case Action::moveWindowDown:
window->move(window->x(), window->y() + it->number());
return;
- case Action::moveWindowLeft:
+ case Action::moveWindowLeft:
window->move(window->x() - it->number(), window->y());
return;
- case Action::moveWindowRight:
+ case Action::moveWindowRight:
window->move(window->x() + it->number(), window->y());
return;
- case Action::resizeWindowWidth:
+ case Action::resizeWindowWidth:
window->resize(window->width() + it->number(), window->height());
return;
- case Action::resizeWindowHeight:
+ case Action::resizeWindowHeight:
window->resize(window->width(), window->height() + it->number());
return;
- case Action::toggleshade:
+ case Action::toggleshade:
window->shade(! window->shaded());
return;
- case Action::toggleMaximizeHorizontal:
+ case Action::toggleMaximizeHorizontal:
window->toggleMaximize(XWindow::Max_Horz);
return;
- case Action::toggleMaximizeVertical:
+ case Action::toggleMaximizeVertical:
window->toggleMaximize(XWindow::Max_Vert);
return;
- case Action::toggleMaximizeFull:
+ case Action::toggleMaximizeFull:
window->toggleMaximize(XWindow::Max_Full);
return;
- default:
+ default:
assert(false); // unhandled action type!
break;
- }
}
- }
}
}
modifierMask|numlockMask|LockMask|scrolllockMask,
_root, True, GrabModeAsync, GrabModeAsync);
}
+
+void screen::ungrabKey(const KeyCode keyCode, const int modifierMask) const {
+
+ Display *display = _epist->getXDisplay();
+ int numlockMask, scrolllockMask;
+
+ _epist->getLockModifiers(numlockMask, scrolllockMask);
+
+ XUngrabKey(display, keyCode, modifierMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|LockMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|scrolllockMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|numlockMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|LockMask|scrolllockMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|scrolllockMask|numlockMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|numlockMask|LockMask, _root);
+ XUngrabKey(display, keyCode, modifierMask|numlockMask|LockMask|
+ scrolllockMask, _root);
+}
void execCommand(const std::string &cmd) const;
void grabKey(const KeyCode keyCode, const int modifierMask) const;
+ void ungrabKey(const KeyCode keyCode, const int modifierMask) const;
};
#endif // __screen_hh