aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2014-04-09 20:40:13 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2014-04-09 20:40:13 (GMT)
commit617635f8eb87bd21ef9e57a578398fbba14173f2 (patch)
treed4bdc5357effa12b2af765d3cfd40bb7b5d1300d /src
parent121bd23862ad49e2acb3d47bc19cad5294383e4e (diff)
downloadfluxbox-617635f8eb87bd21ef9e57a578398fbba14173f2.zip
fluxbox-617635f8eb87bd21ef9e57a578398fbba14173f2.tar.bz2
fix excessive loading of keys file caused by xmodmap
xmodmap (and other tools) trigger MappingNotify events. a single xmodmap expression such as "keycode comma = comma semicolon" might trigger 4 or 5 MappingNotify events. loading the keys file on each of them is quite unefficient. fluxbox now uses a (250ms) timer which is reset upon further events.
Diffstat (limited to 'src')
-rw-r--r--src/fluxbox.cc53
-rw-r--r--src/fluxbox.hh1
2 files changed, 43 insertions, 11 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 07419ba..995ab91 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -187,6 +187,29 @@ int handleXIOErrors(Display* d) {
187} 187}
188 188
189 189
190
191class KeyReloadHelper {
192public:
193 void reload() {
194 Fluxbox* f = Fluxbox::instance();
195 Keys* k = (f ? f->keys() : 0);
196 if (k) {
197 XRefreshKeyboardMapping(&(this->xmapping));
198 FbTk::KeyUtil::instance().init();
199 k->regrab();
200 }
201 }
202
203 XMappingEvent xmapping;
204};
205
206KeyReloadHelper s_key_reloader;
207
208typedef FbTk::SimpleCommand<KeyReloadHelper> KeyReloadHelperCmd;
209typedef FbTk::SimpleCommand<Fluxbox> FluxboxCmd;
210
211
212
190/* functor to call a memberfunction with by a reference argument 213/* functor to call a memberfunction with by a reference argument
191 other places needs this helper as well it should be moved 214 other places needs this helper as well it should be moved
192 to FbTk/ 215 to FbTk/
@@ -303,11 +326,21 @@ Fluxbox::Fluxbox(int argc, char **argv,
303 // Because when the command is executed we shouldn't do reconfig directly 326 // Because when the command is executed we shouldn't do reconfig directly
304 // because it could affect ongoing menu stuff so we need to reconfig in 327 // because it could affect ongoing menu stuff so we need to reconfig in
305 // the next event "round". 328 // the next event "round".
306 FbTk::RefCount<FbTk::Command<void> > reconfig_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::timed_reconfigure)); 329 FluxboxCmd* reconfig_cmd = new FluxboxCmd(*this, &Fluxbox::timed_reconfigure);
307 m_reconfig_timer.setTimeout(1); 330 m_reconfig_timer.setTimeout(1);
308 m_reconfig_timer.setCommand(reconfig_cmd); 331 m_reconfig_timer.setCommand(FbTk::RefCount<FbTk::Command<void> >(reconfig_cmd));
309 m_reconfig_timer.fireOnce(true); 332 m_reconfig_timer.fireOnce(true);
310 333
334 // xmodmap and other tools send a lot of MappingNotify events under some
335 // circumstances ("keysym comma = comma semicolon" creates 4 or 5).
336 // reloading the keys-file for every one of them is unclever. we postpone
337 // the reload() via a timer.
338 KeyReloadHelperCmd* rh_cmd =
339 new KeyReloadHelperCmd(s_key_reloader, &KeyReloadHelper::reload);
340 m_key_reload_timer.setTimeout(250 * FbTk::FbTime::IN_MILLISECONDS);
341 m_key_reload_timer.setCommand(FbTk::RefCount<FbTk::Command<void> >(rh_cmd));
342 m_key_reload_timer.fireOnce(true);
343
311 if (xsync) 344 if (xsync)
312 XSynchronize(disp, True); 345 XSynchronize(disp, True);
313 346
@@ -675,21 +708,18 @@ void Fluxbox::handleEvent(XEvent * const e) {
675 break; 708 break;
676 case UnmapNotify: 709 case UnmapNotify:
677 handleUnmapNotify(e->xunmap); 710 handleUnmapNotify(e->xunmap);
678 break; 711 break;
679 case MappingNotify: 712 case MappingNotify: // Update stored modifier mapping
680 // Update stored modifier mapping
681 fbdbg<<"MappingNotify"<<endl;
682 713
683 if (e->xmapping.request == MappingKeyboard 714 if (e->xmapping.request == MappingKeyboard
684 || e->xmapping.request == MappingModifier) { 715 || e->xmapping.request == MappingModifier) {
685 XRefreshKeyboardMapping(&e->xmapping); 716
686 FbTk::KeyUtil::instance().init(); // reinitialise the key utils 717 s_key_reloader.xmapping = e->xmapping;
687 // reconfigure keys (if the mapping changes, they don't otherwise update 718 m_key_reload_timer.start();
688 m_key->regrab();
689 } 719 }
690 break; 720 break;
691 case CreateNotify: 721 case CreateNotify:
692 break; 722 break;
693 case DestroyNotify: { 723 case DestroyNotify: {
694 WinClient *winclient = searchWindow(e->xdestroywindow.window); 724 WinClient *winclient = searchWindow(e->xdestroywindow.window);
695 if (winclient != 0) { 725 if (winclient != 0) {
@@ -1239,6 +1269,7 @@ void Fluxbox::load_rc(BScreen &screen) {
1239} 1269}
1240 1270
1241void Fluxbox::reconfigure() { 1271void Fluxbox::reconfigure() {
1272 m_key_reload_timer.stop();
1242 load_rc(); 1273 load_rc();
1243 m_reconfigure_wait = true; 1274 m_reconfigure_wait = true;
1244 m_reconfig_timer.start(); 1275 m_reconfig_timer.start();
diff --git a/src/fluxbox.hh b/src/fluxbox.hh
index f6a8f26..d0bc239 100644
--- a/src/fluxbox.hh
+++ b/src/fluxbox.hh
@@ -277,6 +277,7 @@ private:
277 277
278 ///< when we execute reconfig command we must wait until next event round 278 ///< when we execute reconfig command we must wait until next event round
279 FbTk::Timer m_reconfig_timer; 279 FbTk::Timer m_reconfig_timer;
280 FbTk::Timer m_key_reload_timer;
280 bool m_showing_dialog; 281 bool m_showing_dialog;
281 282
282 std::auto_ptr<Keys> m_key; 283 std::auto_ptr<Keys> m_key;