all repos — openbox @ 084d6f4e42396a5d2baf72877b5abf3ae6fef7be

openbox fork - make it a bit more like ryudo

src/bindings.hh (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
#ifndef __binding_hh
#define __binding_hh

/*! @file bindings.hh
  @brief I dunno.. some binding stuff?
*/

#include "actions.hh"
#include "python.hh"
#include "otk/timer.hh"

extern "C" {
#include <Python.h>
}

#include <string>
#include <list>
#include <vector>

namespace ob {

class Client;

typedef std::list<PyObject *> CallbackList;

typedef struct Binding {
  unsigned int modifiers;
  unsigned int key;

  bool operator==(struct Binding &b2) { return key == b2.key &&
					  modifiers == b2.modifiers; }
  bool operator!=(struct Binding &b2) { return key != b2.key ||
					  modifiers != b2.modifiers; }
  Binding(unsigned int mod, unsigned int k) { modifiers = mod; key = k; }
} Binding;

typedef struct KeyBindingTree {
  Binding binding;
  CallbackList callbacks; // the callbacks given for the binding in add()
  bool chain;     // true if this is a chain to another key (not an action)

  struct KeyBindingTree *next_sibling; // the next binding in the tree at the same
                                    // level
  struct KeyBindingTree *first_child;  // the first child of this binding (next
                                    // binding in a chained sequence).
  KeyBindingTree() : binding(0, 0) {
    chain = true; next_sibling = first_child = 0;
  }
} KeyBindingTree;

typedef struct ButtonBinding {
  Binding binding;
  CallbackList callbacks[NUM_MOUSE_ACTION];
  ButtonBinding() : binding(0, 0) {}
};

class Bindings {
public:
  //! A list of strings
  typedef std::vector<std::string> StringVect;

private:
  // root node of the tree (this doesn't have siblings!)
  KeyBindingTree _keytree; 
  KeyBindingTree *_curpos; // position in the keytree

  Binding _resetkey; // the key which resets the key chain status

  otk::Timer *_timer;
  
  KeyBindingTree *find(KeyBindingTree *search, bool *conflict) const;
  KeyBindingTree *buildtree(const StringVect &keylist,
                            PyObject *callback) const;
  void assimilate(KeyBindingTree *node);

  static void resetChains(Bindings *self); // the timer's timeout function

  typedef std::list <ButtonBinding*> ButtonBindingList;
  ButtonBindingList _buttons[NUM_MOUSE_CONTEXT];

  void grabButton(bool grab, const Binding &b, MouseContext context,
                  Client *client);

  CallbackList _eventlist[NUM_EVENTS];

  PyObject *_keybgrab_callback;
  
public:
  //! Initializes an Bindings object
  Bindings();
  //! Destroys the Bindings object
  virtual ~Bindings();

  //! Translates a binding string into the actual Binding
  bool translate(const std::string &str, Binding &b, bool askey = true) const;
  
  //! Adds a new key binding
  /*!
    A binding will fail to be added if the binding already exists (as part of
    a chain or not), or if any of the strings in the keylist are invalid.    
    @return true if the binding could be added; false if it could not.
  */
  bool addKey(const StringVect &keylist, PyObject *callback);

  //! Removes a key binding
  /*!
    @return The callbackid of the binding, or '< 0' if there was no binding to
            be removed.
  */
  bool removeKey(const StringVect &keylist, PyObject *callback);

  //! Removes all key bindings
  void removeAllKeys();

  void fireKey(int screen, unsigned int modifiers,unsigned int key, Time time,
               KeyAction action);

  void setResetKey(const std::string &key);

  void grabKeys(bool grab);

  bool grabKeyboard(int screen, PyObject *callback);
  void ungrabKeyboard();

  bool addButton(const std::string &but, MouseContext context,
                 MouseAction action, PyObject *callback);

  void grabButtons(bool grab, Client *client);

  //! Removes all button bindings
  void removeAllButtons();

  void fireButton(MouseData *data);

  //! Bind a callback for an event
  bool addEvent(EventAction action, PyObject *callback);

  //! Unbind the callback function from an event
  bool removeEvent(EventAction action, PyObject *callback);

  //! Remove all callback functions
  void removeAllEvents();

  void fireEvent(EventData *data);
};

}

#endif // __binding_hh