aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbCommandFactory.cc6
-rw-r--r--src/Keys.cc59
-rw-r--r--src/Keys.hh11
-rw-r--r--src/Screen.cc3
-rw-r--r--src/Toolbar.cc2
-rw-r--r--src/Window.cc96
-rw-r--r--src/fluxbox.cc2
7 files changed, 97 insertions, 82 deletions
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc
index 8f5dcf8..902461c 100644
--- a/src/FbCommandFactory.cc
+++ b/src/FbCommandFactory.cc
@@ -257,6 +257,8 @@ FbCommandFactory::FbCommandFactory() {
257 "setresourcevalue", 257 "setresourcevalue",
258 "setresourcevaluedialog", 258 "setresourcevaluedialog",
259 "shade", 259 "shade",
260 "shadeon",
261 "shadeoff",
260 "shadewindow", 262 "shadewindow",
261 "showdesktop", 263 "showdesktop",
262 "startmoving", 264 "startmoving",
@@ -541,6 +543,10 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
541 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); 543 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments);
542 else if (command == "shade" || command == "shadewindow") 544 else if (command == "shade" || command == "shadewindow")
543 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); 545 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments);
546 else if (command == "shadeon" )
547 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOn)), arguments);
548 else if (command == "shadeoff" )
549 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOff)), arguments);
544 else if (command == "stick" || command == "stickwindow") 550 else if (command == "stick" || command == "stickwindow")
545 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); 551 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments);
546 else if (command == "toggledecor") 552 else if (command == "toggledecor")
diff --git a/src/Keys.cc b/src/Keys.cc
index f3cd092..06a0d48 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -212,7 +212,7 @@ bool Keys::load(const char *filename) {
212 // free memory of previous grabs 212 // free memory of previous grabs
213 deleteTree(); 213 deleteTree();
214 214
215 m_map["default:"] = new t_key(0,0,0,0); 215 m_map["default:"] = new t_key(0,0,0,0,false);
216 216
217 unsigned int current_line = 0; //so we can tell the user where the fault is 217 unsigned int current_line = 0; //so we can tell the user where the fault is
218 218
@@ -245,7 +245,7 @@ void Keys::loadDefaults() {
245 cerr<<"Loading default key bindings"<<endl; 245 cerr<<"Loading default key bindings"<<endl;
246#endif 246#endif
247 deleteTree(); 247 deleteTree();
248 m_map["default:"] = new t_key(0,0,0,0); 248 m_map["default:"] = new t_key(0,0,0,0,false);
249 addBinding("OnDesktop Mouse1 :HideMenus"); 249 addBinding("OnDesktop Mouse1 :HideMenus");
250 addBinding("OnDesktop Mouse2 :WorkspaceMenu"); 250 addBinding("OnDesktop Mouse2 :WorkspaceMenu");
251 addBinding("OnDesktop Mouse3 :RootMenu"); 251 addBinding("OnDesktop Mouse3 :RootMenu");
@@ -280,6 +280,7 @@ bool Keys::addBinding(const string &linebuffer) {
280 280
281 unsigned int key = 0, mod = 0; 281 unsigned int key = 0, mod = 0;
282 int type = 0, context = 0; 282 int type = 0, context = 0;
283 bool isdouble = false;
283 size_t argc = 0; 284 size_t argc = 0;
284 t_key *current_key=m_map["default:"]; 285 t_key *current_key=m_map["default:"];
285 t_key *first_new_keylist = current_key, *first_new_key=0; 286 t_key *first_new_keylist = current_key, *first_new_key=0;
@@ -288,7 +289,7 @@ bool Keys::addBinding(const string &linebuffer) {
288 argc++; 289 argc++;
289 keyspace_t::iterator it = m_map.find(val[0]); 290 keyspace_t::iterator it = m_map.find(val[0]);
290 if (it == m_map.end()) 291 if (it == m_map.end())
291 m_map[val[0]] = new t_key(0,0,0,0); 292 m_map[val[0]] = new t_key(0,0,0,0,false);
292 current_key = m_map[val[0]]; 293 current_key = m_map[val[0]];
293 } 294 }
294 // for each argument 295 // for each argument
@@ -305,6 +306,10 @@ bool Keys::addBinding(const string &linebuffer) {
305 context |= ON_TOOLBAR; 306 context |= ON_TOOLBAR;
306 else if (strcasecmp("onwindow", val[argc].c_str()) == 0) 307 else if (strcasecmp("onwindow", val[argc].c_str()) == 0)
307 context |= ON_WINDOW; 308 context |= ON_WINDOW;
309 else if (strcasecmp("ontitlebar", val[argc].c_str()) == 0)
310 context |= ON_TITLEBAR;
311 else if (strcasecmp("double", val[argc].c_str()) == 0)
312 isdouble = true;
308 else if (strcasecmp("NONE",val[argc].c_str())) { 313 else if (strcasecmp("NONE",val[argc].c_str())) {
309 // check if it's a mouse button 314 // check if it's a mouse button
310 if (strcasecmp("focusin", val[argc].c_str()) == 0) { 315 if (strcasecmp("focusin", val[argc].c_str()) == 0) {
@@ -358,16 +363,21 @@ bool Keys::addBinding(const string &linebuffer) {
358 363
359 if (key == 0 && (type == KeyPress || type == ButtonPress)) 364 if (key == 0 && (type == KeyPress || type == ButtonPress))
360 return false; 365 return false;
366 if (type != ButtonPress)
367 isdouble = false;
361 if (!first_new_key) { 368 if (!first_new_key) {
362 first_new_keylist = current_key; 369 first_new_keylist = current_key;
363 current_key = current_key->find(type, mod, key, context); 370 current_key = current_key->find(type, mod, key, context,
371 isdouble);
364 if (!current_key) { 372 if (!current_key) {
365 first_new_key = new t_key(type, mod, key, context); 373 first_new_key = new t_key(type, mod, key, context,
374 isdouble);
366 current_key = first_new_key; 375 current_key = first_new_key;
367 } else if (*current_key->m_command) // already being used 376 } else if (*current_key->m_command) // already being used
368 return false; 377 return false;
369 } else { 378 } else {
370 t_key *temp_key = new t_key(type, mod, key, context); 379 t_key *temp_key = new t_key(type, mod, key, context,
380 isdouble);
371 current_key->keylist.push_back(temp_key); 381 current_key->keylist.push_back(temp_key);
372 current_key = temp_key; 382 current_key = temp_key;
373 } 383 }
@@ -375,6 +385,7 @@ bool Keys::addBinding(const string &linebuffer) {
375 key = 0; 385 key = 0;
376 type = 0; 386 type = 0;
377 context = 0; 387 context = 0;
388 isdouble = false;
378 } 389 }
379 390
380 } else { // parse command line 391 } else { // parse command line
@@ -402,14 +413,40 @@ bool Keys::addBinding(const string &linebuffer) {
402 413
403// return true if bound to a command, else false 414// return true if bound to a command, else false
404bool Keys::doAction(int type, unsigned int mods, unsigned int key, 415bool Keys::doAction(int type, unsigned int mods, unsigned int key,
405 int context) { 416 int context, Time time) {
417
418 static Time last_button_time = 0;
419 static unsigned int last_button = 0;
420
421 // need to remember whether or not this is a double-click, e.g. when
422 // double-clicking on the titlebar when there's an OnWindow Double command
423 // we just don't update it if timestamp is the same
424 static bool double_click = false;
425
426 // actual value used for searching
427 bool isdouble = false;
428
429 if (type == ButtonPress) {
430 if (time > last_button_time)
431 double_click = (time - last_button_time <
432 Fluxbox::instance()->getDoubleClickInterval()) &&
433 last_button == key;
434 last_button_time = time;
435 last_button = key;
436 isdouble = double_click;
437 }
406 438
407 static t_key* next_key = m_keylist; 439 static t_key* next_key = m_keylist;
408 if (!next_key) 440 if (!next_key)
409 next_key = m_keylist; 441 next_key = m_keylist;
410 442
411 mods = FbTk::KeyUtil::instance().cleanMods(mods); 443 mods = FbTk::KeyUtil::instance().cleanMods(mods);
412 t_key *temp_key = next_key->find(type, mods, key, context); 444 t_key *temp_key = next_key->find(type, mods, key, context, isdouble);
445
446 // just because we double-clicked doesn't mean we shouldn't look for single
447 // click commands
448 if (!temp_key && isdouble)
449 temp_key = next_key->find(type, mods, key, context, false);
413 450
414 // need to save this for emacs-style keybindings 451 // need to save this for emacs-style keybindings
415 static t_key *saved_keymode = 0; 452 static t_key *saved_keymode = 0;
@@ -506,12 +543,13 @@ void Keys::setKeyMode(t_key *keyMode) {
506} 543}
507 544
508Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, 545Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_,
509 int context_, FbTk::RefCount<FbTk::Command> command) { 546 int context_, bool isdouble_) {
510 key = key_; 547 key = key_;
511 mod = mod_; 548 mod = mod_;
512 type = type_; 549 type = type_;
513 context = context_ ? context_ : GLOBAL; 550 context = context_ ? context_ : GLOBAL;
514 m_command = command; 551 isdouble = isdouble_;
552 m_command = 0;
515} 553}
516 554
517Keys::t_key::t_key(t_key *k) { 555Keys::t_key::t_key(t_key *k) {
@@ -519,6 +557,7 @@ Keys::t_key::t_key(t_key *k) {
519 mod = k->mod; 557 mod = k->mod;
520 type = k->type; 558 type = k->type;
521 context = k->context; 559 context = k->context;
560 isdouble = k->isdouble;
522 m_command = k->m_command; 561 m_command = k->m_command;
523} 562}
524 563
diff --git a/src/Keys.hh b/src/Keys.hh
index a8684ed..f5c8cea 100644
--- a/src/Keys.hh
+++ b/src/Keys.hh
@@ -79,7 +79,8 @@ public:
79 /** 79 /**
80 do action from XKeyEvent; return false if not bound to anything 80 do action from XKeyEvent; return false if not bound to anything
81 */ 81 */
82 bool doAction(int type, unsigned int mods, unsigned int key, int context); 82 bool doAction(int type, unsigned int mods, unsigned int key, int context,
83 Time time = 0);
83 84
84 /// register a window so that proper keys/buttons get grabbed on it 85 /// register a window so that proper keys/buttons get grabbed on it
85 void registerWindow(Window win, FbTk::EventHandler &handler, int context); 86 void registerWindow(Window win, FbTk::EventHandler &handler, int context);
@@ -113,18 +114,19 @@ private:
113 class t_key { 114 class t_key {
114 public: 115 public:
115 t_key(int type, unsigned int mod, unsigned int key, int context, 116 t_key(int type, unsigned int mod, unsigned int key, int context,
116 FbTk::RefCount<FbTk::Command> command = FbTk::RefCount<FbTk::Command>(0)); 117 bool isdouble);
117 t_key(t_key *k); 118 t_key(t_key *k);
118 ~t_key(); 119 ~t_key();
119 120
120 t_key *find(int type_, unsigned int mod_, unsigned int key_, 121 t_key *find(int type_, unsigned int mod_, unsigned int key_,
121 int context_) { 122 int context_, bool isdouble_) {
122 // t_key ctor sets context_ of 0 to GLOBAL, so we must here too 123 // t_key ctor sets context_ of 0 to GLOBAL, so we must here too
123 context_ = context_ ? context_ : GLOBAL; 124 context_ = context_ ? context_ : GLOBAL;
124 keylist_t::iterator it = keylist.begin(), it_end = keylist.end(); 125 keylist_t::iterator it = keylist.begin(), it_end = keylist.end();
125 for (; it != it_end; it++) { 126 for (; it != it_end; it++) {
126 if ((*it)->type == type_ && (*it)->key == key_ && 127 if ((*it)->type == type_ && (*it)->key == key_ &&
127 ((*it)->context & context_) > 0 && (*it)->mod == 128 ((*it)->context & context_) > 0 &&
129 isdouble_ == (*it)->isdouble && (*it)->mod ==
128 FbTk::KeyUtil::instance().isolateModifierMask(mod_)) 130 FbTk::KeyUtil::instance().isolateModifierMask(mod_))
129 return *it; 131 return *it;
130 } 132 }
@@ -137,6 +139,7 @@ private:
137 int type; // KeyPress or ButtonPress 139 int type; // KeyPress or ButtonPress
138 unsigned int key; // key code or button number 140 unsigned int key; // key code or button number
139 unsigned int mod; 141 unsigned int mod;
142 bool isdouble;
140 keylist_t keylist; 143 keylist_t keylist;
141 }; 144 };
142 145
diff --git a/src/Screen.cc b/src/Screen.cc
index ebcaaed..7682075 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -849,7 +849,8 @@ void BScreen::buttonPressEvent(XButtonEvent &be) {
849 849
850 Keys *keys = Fluxbox::instance()->keys(); 850 Keys *keys = Fluxbox::instance()->keys();
851 WindowCmd<void>::setWindow(FocusControl::focusedFbWindow()); 851 WindowCmd<void>::setWindow(FocusControl::focusedFbWindow());
852 keys->doAction(be.type, be.state, be.button, Keys::GLOBAL|Keys::ON_DESKTOP); 852 keys->doAction(be.type, be.state, be.button, Keys::GLOBAL|Keys::ON_DESKTOP,
853 be.time);
853} 854}
854 855
855void BScreen::notifyUngrabKeyboard() { 856void BScreen::notifyUngrabKeyboard() {
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 3639df7..f67311c 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -527,7 +527,7 @@ void Toolbar::reconfigure() {
527void Toolbar::buttonPressEvent(XButtonEvent &be) { 527void Toolbar::buttonPressEvent(XButtonEvent &be) {
528 WindowCmd<void>::setWindow(0); 528 WindowCmd<void>::setWindow(0);
529 if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, 529 if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button,
530 Keys::ON_TOOLBAR)) 530 Keys::ON_TOOLBAR, be.time))
531 return; 531 return;
532 if (be.button == 1) 532 if (be.button == 1)
533 raise(); 533 raise();
diff --git a/src/Window.cc b/src/Window.cc
index 6a12664..82bdc5e 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -905,29 +905,27 @@ void FluxboxWindow::moveClientTo(WinClient &win, int x, int y) {
905 905
906void FluxboxWindow::moveClientLeftOf(WinClient &win, WinClient &dest) { 906void FluxboxWindow::moveClientLeftOf(WinClient &win, WinClient &dest) {
907 907
908 frame().moveLabelButtonLeftOf(*m_labelbuttons[&win], *m_labelbuttons[&dest]); 908 frame().moveLabelButtonLeftOf(*m_labelbuttons[&win], *m_labelbuttons[&dest]);
909 909
910 ClientList::iterator it = find(m_clientlist.begin(), 910 ClientList::iterator it = find(m_clientlist.begin(),
911 m_clientlist.end(), 911 m_clientlist.end(),
912 &win); 912 &win);
913 ClientList::iterator new_pos = find(m_clientlist.begin(), 913 ClientList::iterator new_pos = find(m_clientlist.begin(),
914 m_clientlist.end(), 914 m_clientlist.end(),
915 &dest); 915 &dest);
916 916
917 // make sure we found them 917 // make sure we found them
918 if (it == m_clientlist.end() || new_pos==m_clientlist.end()) { 918 if (it == m_clientlist.end() || new_pos==m_clientlist.end())
919 return; 919 return;
920 } 920 //moving a button to the left of itself results in no change
921 //moving a button to the left of itself results in no change 921 if (new_pos == it)
922 if( new_pos == it) { 922 return;
923 return; 923 //remove from list
924 } 924 m_clientlist.erase(it);
925 //remove from list 925 //insert on the new place
926 m_clientlist.erase(it); 926 m_clientlist.insert(new_pos, &win);
927 //insert on the new place
928 m_clientlist.insert(new_pos, &win);
929 927
930 updateClientLeftWindow(); 928 updateClientLeftWindow();
931} 929}
932 930
933 931
@@ -2560,10 +2558,20 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
2560 m_last_button_x = be.x_root; 2558 m_last_button_x = be.x_root;
2561 m_last_button_y = be.y_root; 2559 m_last_button_y = be.y_root;
2562 2560
2561 bool onTitlebar = frame().gripLeft().window() != be.window &&
2562 frame().gripRight().window() != be.window &&
2563 frame().clientArea().window() != be.window &&
2564 frame().window() != be.window;
2565
2566 if (onTitlebar && be.button == 1)
2567 raise();
2568
2563 // check keys file first 2569 // check keys file first
2564 WindowCmd<void>::setWindow(this); 2570 WindowCmd<void>::setWindow(this);
2565 if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, 2571 Keys *k = Fluxbox::instance()->keys();
2566 Keys::ON_WINDOW)) { 2572 if (onTitlebar && k->doAction(be.type, be.state, be.button,
2573 Keys::ON_TITLEBAR, be.time) ||
2574 k->doAction(be.type, be.state, be.button, Keys::ON_WINDOW, be.time)) {
2567 return; 2575 return;
2568 } 2576 }
2569 2577
@@ -2572,13 +2580,6 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
2572 if (!m_focused && acceptsFocus()) //check focus 2580 if (!m_focused && acceptsFocus()) //check focus
2573 focus(); 2581 focus();
2574 2582
2575 // click on titlebar
2576 if (frame().gripLeft().window() != be.window &&
2577 frame().gripRight().window() != be.window &&
2578 frame().clientArea().window() != be.window &&
2579 frame().window() != be.window)
2580 raise();
2581
2582 if (frame().window().window() == be.window || 2583 if (frame().window().window() == be.window ||
2583 frame().tabcontainer().window() == be.window) { 2584 frame().tabcontainer().window() == be.window) {
2584 if (screen().clickRaises()) 2585 if (screen().clickRaises())
@@ -2607,43 +2608,8 @@ void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) {
2607 stopResizing(); 2608 stopResizing();
2608 else if (m_attaching_tab) 2609 else if (m_attaching_tab)
2609 attachTo(re.x_root, re.y_root); 2610 attachTo(re.x_root, re.y_root);
2610 else { 2611 else
2611 frame().tabcontainer().tryButtonReleaseEvent(re); 2612 frame().tabcontainer().tryButtonReleaseEvent(re);
2612 if (frame().gripLeft().window() == re.window ||
2613 frame().gripRight().window() == re.window ||
2614 frame().clientArea().window() == re.window ||
2615 frame().handle().window() == re.window ||
2616 frame().window() == re.window)
2617 return;
2618
2619 static Time last_release_time = 0;
2620 bool double_click = (re.time - last_release_time <=
2621 Fluxbox::instance()->getDoubleClickInterval());
2622 last_release_time = re.time;
2623
2624 if (re.button == 1 && double_click)
2625 shade();
2626 if (re.button == 3)
2627 popupMenu();
2628 if (re.button == 2)
2629 lower();
2630
2631 unsigned int reverse = (screen().getScrollReverse() ? 1 : 0);
2632 if (re.button == 4 || re.button == 5) {
2633 if (StringUtil::toLower(screen().getScrollAction()) == "shade") {
2634 if (re.button == 5 - reverse)
2635 shadeOn();
2636 else
2637 shadeOff();
2638 }
2639 if (StringUtil::toLower(screen().getScrollAction()) == "nexttab") {
2640 if (re.button == 5 - reverse)
2641 nextClient();
2642 else
2643 prevClient();
2644 }
2645 }
2646 }
2647 2613
2648} 2614}
2649 2615
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 3c30c14..7cf165e 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -643,7 +643,7 @@ void Fluxbox::setupConfigFiles() {
643 if (create_init) 643 if (create_init)
644 FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); 644 FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str());
645 645
646#define CONFIG_VERSION 5 646#define CONFIG_VERSION 6
647 FbTk::Resource<int> config_version(m_resourcemanager, 0, 647 FbTk::Resource<int> config_version(m_resourcemanager, 0,
648 "session.configVersion", "Session.ConfigVersion"); 648 "session.configVersion", "Session.ConfigVersion");
649 if (*config_version < CONFIG_VERSION) { 649 if (*config_version < CONFIG_VERSION) {