all repos — fluxbox @ 617635f8eb87bd21ef9e57a578398fbba14173f2

custom fork of the fluxbox windowmanager

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.
Mathias Gumz akira at fluxbox dot org
commit

617635f8eb87bd21ef9e57a578398fbba14173f2

parent

121bd23862ad49e2acb3d47bc19cad5294383e4e

2 files changed, 43 insertions(+), 11 deletions(-)

jump to
M src/fluxbox.ccsrc/fluxbox.cc

@@ -187,6 +187,29 @@ exit(1);

} + +class KeyReloadHelper { +public: + void reload() { + Fluxbox* f = Fluxbox::instance(); + Keys* k = (f ? f->keys() : 0); + if (k) { + XRefreshKeyboardMapping(&(this->xmapping)); + FbTk::KeyUtil::instance().init(); + k->regrab(); + } + } + + XMappingEvent xmapping; +}; + +KeyReloadHelper s_key_reloader; + +typedef FbTk::SimpleCommand<KeyReloadHelper> KeyReloadHelperCmd; +typedef FbTk::SimpleCommand<Fluxbox> FluxboxCmd; + + + /* functor to call a memberfunction with by a reference argument other places needs this helper as well it should be moved to FbTk/

@@ -303,10 +326,20 @@ // This timer is used to we can issue a safe reconfig command.

// Because when the command is executed we shouldn't do reconfig directly // because it could affect ongoing menu stuff so we need to reconfig in // the next event "round". - FbTk::RefCount<FbTk::Command<void> > reconfig_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::timed_reconfigure)); + FluxboxCmd* reconfig_cmd = new FluxboxCmd(*this, &Fluxbox::timed_reconfigure); m_reconfig_timer.setTimeout(1); - m_reconfig_timer.setCommand(reconfig_cmd); + m_reconfig_timer.setCommand(FbTk::RefCount<FbTk::Command<void> >(reconfig_cmd)); m_reconfig_timer.fireOnce(true); + + // xmodmap and other tools send a lot of MappingNotify events under some + // circumstances ("keysym comma = comma semicolon" creates 4 or 5). + // reloading the keys-file for every one of them is unclever. we postpone + // the reload() via a timer. + KeyReloadHelperCmd* rh_cmd = + new KeyReloadHelperCmd(s_key_reloader, &KeyReloadHelper::reload); + m_key_reload_timer.setTimeout(250 * FbTk::FbTime::IN_MILLISECONDS); + m_key_reload_timer.setCommand(FbTk::RefCount<FbTk::Command<void> >(rh_cmd)); + m_key_reload_timer.fireOnce(true); if (xsync) XSynchronize(disp, True);

@@ -675,21 +708,18 @@ // handled directly in FluxboxWindow::handleEvent

break; case UnmapNotify: handleUnmapNotify(e->xunmap); - break; - case MappingNotify: - // Update stored modifier mapping - fbdbg<<"MappingNotify"<<endl; + break; + case MappingNotify: // Update stored modifier mapping if (e->xmapping.request == MappingKeyboard || e->xmapping.request == MappingModifier) { - XRefreshKeyboardMapping(&e->xmapping); - FbTk::KeyUtil::instance().init(); // reinitialise the key utils - // reconfigure keys (if the mapping changes, they don't otherwise update - m_key->regrab(); + + s_key_reloader.xmapping = e->xmapping; + m_key_reload_timer.start(); } break; case CreateNotify: - break; + break; case DestroyNotify: { WinClient *winclient = searchWindow(e->xdestroywindow.window); if (winclient != 0) {

@@ -1239,6 +1269,7 @@ }

} void Fluxbox::reconfigure() { + m_key_reload_timer.stop(); load_rc(); m_reconfigure_wait = true; m_reconfig_timer.start();
M src/fluxbox.hhsrc/fluxbox.hh

@@ -277,6 +277,7 @@ XEvent m_last_event;

///< when we execute reconfig command we must wait until next event round FbTk::Timer m_reconfig_timer; + FbTk::Timer m_key_reload_timer; bool m_showing_dialog; std::auto_ptr<Keys> m_key;