]> Dogcows Code - chaz/openbox/commitdiff
Big fat merge for epist.
authorScott Moynes <smoynes@nexus.carleton.ca>
Tue, 6 Aug 2002 22:37:06 +0000 (22:37 +0000)
committerScott Moynes <smoynes@nexus.carleton.ca>
Tue, 6 Aug 2002 22:37:06 +0000 (22:37 +0000)
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.

12 files changed:
util/epist/Makefile.am
util/epist/actions.cc
util/epist/actions.hh
util/epist/epist.cc
util/epist/epist.hh
util/epist/epist.y [new file with mode: 0644]
util/epist/keytree.cc [new file with mode: 0644]
util/epist/keytree.hh [new file with mode: 0644]
util/epist/parser.cc [new file with mode: 0644]
util/epist/parser.hh [new file with mode: 0644]
util/epist/screen.cc
util/epist/screen.hh

index 84cad62b6c610ef421ef3419034453f791f06111..2accf1268dc6482ba1ef94f959c314f9aaa9ea65 100644 (file)
@@ -4,7 +4,7 @@ CPPFLAGS= @CPPFLAGS@ @DEBUG@
 
 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 \
@@ -25,3 +25,10 @@ screen.o: screen.cc ../../src/XAtom.hh screen.hh window.hh epist.hh \
   ../../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
index 35ddbb80976c8a962d35ea11ac233cbbc6a48c6a..82e61ae3fdd14854f027700c6f6c1146f3653caf 100644 (file)
 
 #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;
+}
index 25f1e9685d220fd4a43b72148167ad7542646a20..8a7385e11b1e5b415174f4c57eb32e8d96add72c 100644 (file)
@@ -93,8 +93,8 @@ private:
   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; }
@@ -103,9 +103,7 @@ public:
   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;
index f1c577c2df12c126e0f6df9265d66bcdc27a8893..c10f5a8e6caaa7d83367e5d058ebd6815284eff7 100644 (file)
@@ -54,6 +54,7 @@ using std::string;
 #include "epist.hh"
 #include "screen.hh"
 #include "window.hh"
+#include "parser.hh"
 #include "../../src/XAtom.hh"
 
 
@@ -65,7 +66,7 @@ epist::epist(char **argv, char *dpy_name, char *rc_file)
   if (rc_file)
     _rc_file = rc_file;
   else
-    _rc_file = expandTilde("~/.openbox/epistrc");
+    _rc_file = expandTilde("~/.epistrc");
 
   _xatom = new XAtom(getXDisplay());
 
@@ -83,52 +84,11 @@ epist::epist(char **argv, char *dpy_name, char *rc_file)
     ::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();
 }
@@ -142,13 +102,8 @@ void epist::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);
 }
 
 
@@ -222,19 +177,3 @@ void epist::cycleScreen(int current, bool forward) const {
   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));
-}
index 1932902db45918bec99c83ac61fc9a5f9f892c71..37b1d5b8adf52d6d7648c4feef5b46df8beeddd3 100644 (file)
@@ -32,6 +32,7 @@ extern "C" {
 
 #include "actions.hh"
 #include "window.hh"
+#include "keytree.hh"
 
 #include "../../src/BaseDisplay.hh"
 
@@ -43,6 +44,7 @@ private:
   std::string _rc_file;
   XAtom *_xatom;
   char **_argv;
+  keytree *_ktree;
 
   typedef std::vector<screen *> ScreenList;
   ScreenList _screens;
@@ -60,10 +62,6 @@ private:
   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);
@@ -83,6 +81,7 @@ public:
   }
   
   const ActionList &actions(void) { return _actions; }
+  keytree &getKeyTree(void) { return *_ktree; }
   
   WindowList& clientsList() { return _clients; }
   WindowList::iterator& activeWindow() { return _active; }
diff --git a/util/epist/epist.y b/util/epist/epist.y
new file mode 100644 (file)
index 0000000..60fe9aa
--- /dev/null
@@ -0,0 +1,83 @@
+%{
+#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); }
+    ;
+
+%%
+
diff --git a/util/epist/keytree.cc b/util/epist/keytree.cc
new file mode 100644 (file)
index 0000000..2649740
--- /dev/null
@@ -0,0 +1,144 @@
+// -*- 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);
+}
diff --git a/util/epist/keytree.hh b/util/epist/keytree.hh
new file mode 100644 (file)
index 0000000..f64982d
--- /dev/null
@@ -0,0 +1,72 @@
+// -*- 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
diff --git a/util/epist/parser.cc b/util/epist/parser.cc
new file mode 100644 (file)
index 0000000..660a876
--- /dev/null
@@ -0,0 +1,145 @@
+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 = "";
+}
diff --git a/util/epist/parser.hh b/util/epist/parser.hh
new file mode 100644 (file)
index 0000000..148649b
--- /dev/null
@@ -0,0 +1,33 @@
+#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;
+};
index 0ec679bbe48dc13e57ef7876f0c9bd094af82434..f40bff3ca1cd15c37606935477b5ac4612e673a6 100644 (file)
@@ -146,164 +146,162 @@ void screen::processEvent(const XEvent &e) {
 
 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;
-        }
       }
-    }
   }
 }
 
@@ -583,3 +581,21 @@ void screen::grabKey(const KeyCode keyCode, const int modifierMask) const {
            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);
+}
index 6d0c87ba6922c3853c01a99469198307bf715324..1a669bf93fce08aaddf4e048339cecaa27d1278e 100644 (file)
@@ -86,6 +86,7 @@ public:
   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
This page took 0.048134 seconds and 4 git commands to generate.