aboutsummaryrefslogtreecommitdiff
path: root/src/Keys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Keys.cc')
-rw-r--r--src/Keys.cc110
1 files changed, 72 insertions, 38 deletions
diff --git a/src/Keys.cc b/src/Keys.cc
index 72d59cd..6d13cd4 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -101,18 +101,7 @@ using std::vector;
101using std::ifstream; 101using std::ifstream;
102using std::pair; 102using std::pair;
103 103
104Keys::Keys(): 104Keys::Keys(): m_display(FbTk::App::instance()->display()) { }
105 m_display(FbTk::App::instance()->display())
106{
107 typedef std::list<BScreen *> ScreenList;
108 ScreenList screen_list = Fluxbox::instance()->screenList();
109 ScreenList::iterator it = screen_list.begin();
110 ScreenList::iterator it_end = screen_list.end();
111
112 for (; it != it_end; ++it)
113 m_window_list.push_back(RootWindow(m_display,(*it)->screenNumber()));
114
115}
116 105
117Keys::~Keys() { 106Keys::~Keys() {
118 ungrabKeys(); 107 ungrabKeys();
@@ -127,37 +116,69 @@ void Keys::deleteTree() {
127 m_map.clear(); 116 m_map.clear();
128} 117}
129 118
119// keys are only grabbed in global context
130void Keys::grabKey(unsigned int key, unsigned int mod) { 120void Keys::grabKey(unsigned int key, unsigned int mod) {
131 std::list<Window>::iterator it = m_window_list.begin(); 121 WindowMap::iterator it = m_window_map.begin();
132 std::list<Window>::iterator it_end = m_window_list.end(); 122 WindowMap::iterator it_end = m_window_map.end();
133 123
134 for (; it != it_end; ++it) 124 for (; it != it_end; ++it) {
135 FbTk::KeyUtil::grabKey(key, mod, *it); 125 if ((it->second & Keys::GLOBAL) > 0)
126 FbTk::KeyUtil::grabKey(key, mod, it->first);
127 }
136} 128}
137 129
130// keys are only grabbed in global context
138void Keys::ungrabKeys() { 131void Keys::ungrabKeys() {
139 std::list<Window>::iterator it = m_window_list.begin(); 132 WindowMap::iterator it = m_window_map.begin();
140 std::list<Window>::iterator it_end = m_window_list.end(); 133 WindowMap::iterator it_end = m_window_map.end();
141 134
142 for (; it != it_end; ++it) 135 for (; it != it_end; ++it) {
143 FbTk::KeyUtil::ungrabKeys(*it); 136 if ((it->second & Keys::GLOBAL) > 0)
137 FbTk::KeyUtil::ungrabKeys(it->first);
138 }
144} 139}
145 140
146void Keys::grabButton(unsigned int button, unsigned int mod) { 141// ON_DESKTOP context doesn't need to be grabbed
147 std::list<Window>::iterator it = m_window_list.begin(); 142void Keys::grabButton(unsigned int button, unsigned int mod, int context) {
148 std::list<Window>::iterator it_end = m_window_list.end(); 143 WindowMap::iterator it = m_window_map.begin();
144 WindowMap::iterator it_end = m_window_map.end();
149 145
150 for (; it != it_end; ++it) 146 for (; it != it_end; ++it) {
151 FbTk::KeyUtil::grabButton(button, mod, *it, 147 if ((context & it->second & ~Keys::ON_DESKTOP) > 0)
152 ButtonPressMask|ButtonReleaseMask); 148 FbTk::KeyUtil::grabButton(button, mod, it->first,
149 ButtonPressMask|ButtonReleaseMask);
150 }
153} 151}
154 152
155void Keys::ungrabButtons() { 153void Keys::ungrabButtons() {
156 std::list<Window>::iterator it = m_window_list.begin(); 154 WindowMap::iterator it = m_window_map.begin();
157 std::list<Window>::iterator it_end = m_window_list.end(); 155 WindowMap::iterator it_end = m_window_map.end();
158 156
159 for (; it != it_end; ++it) 157 for (; it != it_end; ++it)
160 FbTk::KeyUtil::ungrabButtons(*it); 158 FbTk::KeyUtil::ungrabButtons(it->first);
159}
160
161void Keys::grabWindow(Window win) {
162 if (!m_keylist)
163 return;
164
165 // make sure the window is in our list
166 WindowMap::iterator win_it = m_window_map.find(win);
167 if (win_it == m_window_map.end())
168 return;
169
170 keylist_t::iterator it = m_keylist->keylist.begin();
171 keylist_t::iterator it_end = m_keylist->keylist.end();
172 for (; it != it_end; ++it) {
173 // keys are only grabbed in global context
174 if ((win_it->second & Keys::GLOBAL) > 0 && (*it)->type == KeyPress)
175 FbTk::KeyUtil::grabKey((*it)->key, (*it)->mod, win);
176 // ON_DESKTOP buttons don't need to be grabbed
177 else if ((win_it->second & (*it)->context & ~Keys::ON_DESKTOP) > 0 &&
178 (*it)->type == ButtonPress)
179 FbTk::KeyUtil::grabButton((*it)->key, (*it)->mod, win,
180 ButtonPressMask|ButtonReleaseMask);
181 }
161} 182}
162 183
163/** 184/**
@@ -278,6 +299,8 @@ bool Keys::addBinding(const string &linebuffer) {
278 mod |= tmpmod; //If it's a modifier 299 mod |= tmpmod; //If it's a modifier
279 else if (strcasecmp("ondesktop", val[argc].c_str()) == 0) 300 else if (strcasecmp("ondesktop", val[argc].c_str()) == 0)
280 context |= ON_DESKTOP; 301 context |= ON_DESKTOP;
302 else if (strcasecmp("ontoolbar", val[argc].c_str()) == 0)
303 context |= ON_TOOLBAR;
281 else if (strcasecmp("NONE",val[argc].c_str())) { 304 else if (strcasecmp("NONE",val[argc].c_str())) {
282 // check if it's a mouse button 305 // check if it's a mouse button
283 if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") && 306 if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") &&
@@ -349,16 +372,15 @@ bool Keys::addBinding(const string &linebuffer) {
349} 372}
350 373
351// return true if bound to a command, else false 374// return true if bound to a command, else false
352bool Keys::doAction(int type, unsigned int mods, unsigned int key) { 375bool Keys::doAction(int type, unsigned int mods, unsigned int key,
376 int context) {
353 377
354 static t_key* next_key = m_keylist; 378 static t_key* next_key = m_keylist;
355 if (!next_key) 379 if (!next_key)
356 next_key = m_keylist; 380 next_key = m_keylist;
357 381
358 mods = FbTk::KeyUtil::instance().cleanMods(mods); 382 mods = FbTk::KeyUtil::instance().cleanMods(mods);
359 // at the moment, any key/button that gets here is on root window 383 t_key *temp_key = next_key->find(type, mods, key, context);
360 // context will need to be added as an argument to doAction, though
361 t_key *temp_key = next_key->find(type, mods, key, ON_DESKTOP|GLOBAL);
362 384
363 // need to save this for emacs-style keybindings 385 // need to save this for emacs-style keybindings
364 static t_key *saved_keymode = 0; 386 static t_key *saved_keymode = 0;
@@ -396,6 +418,19 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key) {
396 return true; 418 return true;
397} 419}
398 420
421/// adds the window to m_window_map, so we know to grab buttons on it
422void Keys::registerWindow(Window win, int context) {
423 m_window_map[win] = context;
424 grabWindow(win);
425}
426
427/// remove the window from the window map, probably being deleted
428void Keys::unregisterWindow(Window win) {
429 FbTk::KeyUtil::ungrabKeys(win);
430 FbTk::KeyUtil::ungrabButtons(win);
431 m_window_map.erase(win);
432}
433
399/** 434/**
400 deletes the tree and load configuration 435 deletes the tree and load configuration
401 returns true on success else false 436 returns true on success else false
@@ -419,14 +454,13 @@ void Keys::setKeyMode(t_key *keyMode) {
419 keylist_t::iterator it_end = keyMode->keylist.end(); 454 keylist_t::iterator it_end = keyMode->keylist.end();
420 for (; it != it_end; ++it) { 455 for (; it != it_end; ++it) {
421 if ((*it)->type == KeyPress) 456 if ((*it)->type == KeyPress)
422 grabKey((*it)->key,(*it)->mod); 457 grabKey((*it)->key, (*it)->mod);
423 else if ((*it)->context == GLOBAL) 458 else
424 grabButton((*it)->key,(*it)->mod); 459 grabButton((*it)->key, (*it)->mod, (*it)->context);
425 // we must use root window's event mask to get ON_DESKTOP events
426 } 460 }
427 m_keylist = keyMode; 461 m_keylist = keyMode;
428} 462}
429 463
430Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, 464Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_,
431 int context_, FbTk::RefCount<FbTk::Command> command) { 465 int context_, FbTk::RefCount<FbTk::Command> command) {
432 key = key_; 466 key = key_;