all repos — fluxbox @ 4c1a242968dff12e504f281224819b7cd3850a04

custom fork of the fluxbox windowmanager

moved some code around (regarding event handling) in preparation for upcoming features
markt markt
commit

4c1a242968dff12e504f281224819b7cd3850a04

parent

9477af82a5835b7336fec8879967abb67f3bd848

M src/FbTk/EventHandler.hhsrc/FbTk/EventHandler.hh

@@ -54,11 +54,11 @@ virtual void buttonReleaseEvent(XButtonEvent &) { }

virtual void exposeEvent(XExposeEvent &) { } virtual void motionNotifyEvent(XMotionEvent &) { } virtual void keyPressEvent(XKeyEvent &) { } -#ifdef NOT_USED virtual void keyReleaseEvent(XKeyEvent &) { } -#endif virtual void leaveNotifyEvent(XCrossingEvent &) { } virtual void enterNotifyEvent(XCrossingEvent &) { } + + virtual void notifyUngrabKeyboard() { } }; } // end namespace FbTk
M src/FbTk/EventManager.ccsrc/FbTk/EventManager.cc

@@ -66,6 +66,26 @@ EventHandler *EventManager::find(Window win) {

return m_eventhandlers[win]; } +bool EventManager::grabKeyboard(EventHandler &ev, Window win) { + if (m_grabbing_keyboard) + ungrabKeyboard(); + + int ret = XGrabKeyboard(App::instance()->display(), win, False, + GrabModeAsync, GrabModeAsync, CurrentTime); + + if (ret == Success) { + m_grabbing_keyboard = &ev; + return true; + } + return false; +} + +void EventManager::ungrabKeyboard() { + XUngrabKeyboard(App::instance()->display(), CurrentTime); + if (m_grabbing_keyboard) + m_grabbing_keyboard->notifyUngrabKeyboard(); + m_grabbing_keyboard = 0; +} Window EventManager::getEventWindow(XEvent &ev) { // we only have cases for events that differ from xany

@@ -156,9 +176,7 @@ case KeyPress:

evhand->keyPressEvent(ev.xkey); break; case KeyRelease: -#ifdef NOT_USED evhand->keyReleaseEvent(ev.xkey); -#endif break; case ButtonPress: evhand->buttonPressEvent(ev.xbutton);
M src/FbTk/EventManager.hhsrc/FbTk/EventManager.hh

@@ -43,6 +43,10 @@ void remove(const FbWindow &win);

void add(EventHandler &ev, Window win) { registerEventHandler(ev, win); } void remove(Window win) { unregisterEventHandler(win); } + bool grabKeyboard(EventHandler &ev, Window win); + void ungrabKeyboard(); + EventHandler *grabbingKeyboard() { return m_grabbing_keyboard; } + EventHandler *find(Window win); // Some events have the parent window as the xany.window

@@ -53,13 +57,14 @@ void registerEventHandler(EventHandler &ev, Window win);

void unregisterEventHandler(Window win); private: - EventManager() { } + EventManager(): m_grabbing_keyboard(0) { } ~EventManager(); void dispatch(Window win, XEvent &event, bool parent = false); typedef std::map<Window, EventHandler *> EventHandlerMap; EventHandlerMap m_eventhandlers; EventHandlerMap m_parent; + EventHandler *m_grabbing_keyboard; }; } //end namespace FbTk
M src/FocusControl.ccsrc/FocusControl.cc

@@ -30,6 +30,8 @@ #include "Workspace.hh"

#include "fluxbox.hh" #include "FbWinFrameTheme.hh" +#include "FbTk/EventManager.hh" + #include <string> #include <iostream>

@@ -82,7 +84,7 @@

void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_reverse) { if (!m_cycling_list) { - if (&m_screen == Fluxbox::instance()->watchingScreen()) + if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard()) // only set this when we're waiting for modifiers m_cycling_list = window_list; m_was_iconic = 0;
M src/Screen.ccsrc/Screen.cc

@@ -28,6 +28,7 @@

#include "Screen.hh" #include "fluxbox.hh" +#include "Keys.hh" #include "Window.hh" #include "Workspace.hh" #include "Netizen.hh"

@@ -364,6 +365,7 @@ m_name(screenname),

m_altname(altscreenname), m_focus_control(new FocusControl(*this)), m_placement_strategy(new ScreenPlacement(*this)), + m_cycling(false), m_xinerama_headinfo(0), m_restart(false), m_shutdown(false) {

@@ -416,7 +418,8 @@ "informational message saying screen number (%d), visual (%lx), and colour depth (%d)").c_str(),

screenNumber(), XVisualIDFromVisual(rootWindow().visual()), rootWindow().depth()); - + FbTk::EventManager *evm = FbTk::EventManager::instance(); + evm->add(*this, rootWindow()); rootWindow().setCursor(XCreateFontCursor(disp, XC_left_ptr)); // load this screens resources

@@ -537,6 +540,9 @@

if (! managed) return; + + FbTk::EventManager *evm = FbTk::EventManager::instance(); + evm->remove(rootWindow()); if (m_rootmenu.get() != 0) m_rootmenu->removeAll();

@@ -778,6 +784,59 @@ const Icons::iterator it_end = iconList().end();

for (; it != it_end; ++it) fluxbox->updateFrameExtents(**it); +} + +void BScreen::keyPressEvent(XKeyEvent &ke) { + Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode); +} + +void BScreen::keyReleaseEvent(XKeyEvent &ke) { + if (!m_cycling) + return; + + unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state); + state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); + + if (!state) // all modifiers were released + FbTk::EventManager::instance()->ungrabKeyboard(); +} + +void BScreen::buttonPressEvent(XButtonEvent &be) { + if (be.button == 1 && !isRootColormapInstalled()) + imageControl().installRootColormap(); + + Keys *keys = Fluxbox::instance()->keys(); + keys->doAction(be.type, be.state, be.button); +} + +void BScreen::notifyUngrabKeyboard() { + m_cycling = false; + focusControl().stopCyclingFocus(); +} + +void BScreen::cycleFocus(int options, bool reverse) { + // get modifiers from event that causes this for focus order cycling + XEvent ev = Fluxbox::instance()->lastEvent(); + unsigned int mods = 0; + if (ev.type == KeyPress) + mods = FbTk::KeyUtil::instance().cleanMods(ev.xkey.state); + else if (ev.type == ButtonPress) + mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); + + if (!m_cycling && mods) { + m_cycling = true; + FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window()); + } + + if (mods == 0) // can't stacked cycle unless there is a mod to grab + options |= FocusControl::CYCLELINEAR; + + FocusControl::FocusedWindows *win_list = + (options & FocusControl::CYCLELINEAR) ? + &focusControl().creationOrderList() : + &focusControl().focusedOrderList(); + + focusControl().cycleFocus(win_list, options, reverse); } FbTk::Menu *BScreen::createMenu(const string &label) {

@@ -2052,16 +2111,6 @@

if (tmp) imageControl().removeImage(tmp); -} - - - - -/** - Called when a set of watched modifiers has been released -*/ -void BScreen::notifyReleasedKeys() { - focusControl().stopCyclingFocus(); } void BScreen::updateSize() {
M src/Screen.hhsrc/Screen.hh

@@ -32,6 +32,8 @@ #include "FbRootWindow.hh"

#include "MenuTheme.hh" #include "PlacementStrategy.hh" +#include "FbTk/EventHandler.hh" +#include "FbTk/TypeAhead.hh" #include "FbTk/Resource.hh" #include "FbTk/Subject.hh" #include "FbTk/MultLayers.hh"

@@ -78,7 +80,8 @@ /// Handles screen connection, screen clients and workspaces

/** Create workspaces, handles switching between workspaces and windows */ -class BScreen : public FbTk::Observer, private FbTk::NotCopyable { +class BScreen: public FbTk::EventHandler, public FbTk::Observer, + private FbTk::NotCopyable { public: /// a window becomes active / focussed on a different workspace enum FollowModel {

@@ -209,6 +212,13 @@ //@}

void update(FbTk::Subject *subj); + void keyPressEvent(XKeyEvent &ke); + void keyReleaseEvent(XKeyEvent &ke); + void buttonPressEvent(XButtonEvent &be); + void notifyUngrabKeyboard(); + + void cycleFocus(int opts, bool reverse); + FbTk::Menu *createMenu(const std::string &label); FbTk::Menu *createToggleMenu(const std::string &label); void hideMenus();

@@ -293,8 +303,6 @@ void hidePosition();

/// show geomentry with "width x height"-text, not size of window void showGeometry(int width, int height); void hideGeometry(); - - void notifyReleasedKeys(); void setLayer(FbTk::XLayerItem &item, int layernum); // remove? no, items are never removed from their layer until they die

@@ -476,6 +484,8 @@ // This is a map of windows to clients for clients that had a left

// window set, but that window wasn't present at the time typedef std::map<Window, WinClient *> Groupables; Groupables m_expecting_groups; + + bool m_cycling; // Xinerama related private data bool m_xinerama_avail;
M src/WorkspaceCmd.ccsrc/WorkspaceCmd.cc

@@ -42,59 +42,15 @@ #include <algorithm>

#include <functional> void NextWindowCmd::execute() { - Fluxbox *fb = Fluxbox::instance(); - BScreen *screen = fb->keyScreen(); - if (screen != 0) { - // get modifiers from event that causes this for focus order cycling - unsigned int mods = 0; - XEvent ev = fb->lastEvent(); - if (ev.type == KeyPress) { - mods = FbTk::KeyUtil::instance().cleanMods(ev.xkey.state); - } else if (ev.type == ButtonPress) { - mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); - } - int options = m_option; - if (mods == 0) // can't stacked cycle unless there is a mod to grab - options |= FocusControl::CYCLELINEAR; - else - // set a watch for the release of exactly these modifiers - fb->watchKeyRelease(*screen, mods); - - FocusControl::FocusedWindows *win_list = - (options & FocusControl::CYCLELINEAR) ? - &screen->focusControl().creationOrderList() : - &screen->focusControl().focusedOrderList(); - - screen->focusControl().cycleFocus(win_list, m_option); - } + BScreen *screen = Fluxbox::instance()->keyScreen(); + if (screen != 0) + screen->cycleFocus(m_option, false); } void PrevWindowCmd::execute() { - Fluxbox *fb = Fluxbox::instance(); - BScreen *screen = fb->keyScreen(); - if (screen != 0) { - // get modifiers from event that causes this for focus order cycling - unsigned int mods = 0; - XEvent ev = fb->lastEvent(); - if (ev.type == KeyPress) { - mods = FbTk::KeyUtil::instance().cleanMods(ev.xkey.state); - } else if (ev.type == ButtonPress) { - mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); - } - int options = m_option; - if (mods == 0) // can't stacked cycle unless there is a mod to grab - options |= FocusControl::CYCLELINEAR; - else - // set a watch for the release of exactly these modifiers - fb->watchKeyRelease(*screen, mods); - - FocusControl::FocusedWindows *win_list = - (options & FocusControl::CYCLELINEAR) ? - &screen->focusControl().creationOrderList() : - &screen->focusControl().focusedOrderList(); - - screen->focusControl().cycleFocus(win_list, m_option, true); - } + BScreen *screen = Fluxbox::instance()->keyScreen(); + if (screen != 0) + screen->cycleFocus(m_option, true); } void DirFocusCmd::execute() {
M src/fluxbox.ccsrc/fluxbox.cc

@@ -228,7 +228,6 @@ m_rc_mod_key(m_resourcemanager, "Mod1", "session.modKey", "Session.ModKey"),

m_masked_window(0), m_mousescreen(0), m_keyscreen(0), - m_watching_screen(0), m_watch_keyrelease(0), m_last_time(0), m_masked(0), m_rc_file(rcfilename ? rcfilename : ""),

@@ -746,7 +745,6 @@

switch (e->type) { case ButtonRelease: case ButtonPress: - handleButtonEvent(e->xbutton); break; case ConfigureRequest: {

@@ -894,7 +892,6 @@ case Expose:

break; case KeyRelease: case KeyPress: - handleKeyEvent(e->xkey); break; case ColormapNotify: { BScreen *screen = searchScreen(e->xcolormap.window);

@@ -958,20 +955,6 @@

} } -void Fluxbox::handleButtonEvent(XButtonEvent &be) { - m_last_time = be.time; - - BScreen *screen = searchScreen(be.window); - if (be.type == ButtonRelease || !screen) - // no bindings for this type yet - return; - - if (be.button == 1 && !screen->isRootColormapInstalled()) - screen->imageControl().installRootColormap(); - - m_key->doAction(be.type, be.state, be.button); -} - void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) { BScreen *screen = searchScreen(ue.event);

@@ -1092,47 +1075,6 @@

} } -/** - Handles KeyRelease and KeyPress events -*/ -void Fluxbox::handleKeyEvent(XKeyEvent &ke) { - - if (keyScreen() == 0 || mouseScreen() == 0) - return; - - switch (ke.type) { - case KeyPress: - m_key->doAction(ke.type, ke.state, ke.keycode); - break; - case KeyRelease: { - // we ignore most key releases unless we need to use - // a release to stop something (e.g. window cycling). - - // we notify if _all_ of the watched modifiers are released - if (m_watching_screen && m_watch_keyrelease) { - // mask the mod of the released key out - // won't mask anything if it isn't a mod - unsigned int state = FbTk::KeyUtil::instance().isolateModifierMask(ke.state); - state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); - - if ((m_watch_keyrelease & state) == 0) { - - m_watching_screen->notifyReleasedKeys(); - XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); - - // once they are released, we drop the watch - m_watching_screen = 0; - m_watch_keyrelease = 0; - } - } - - break; - } - default: - break; - } -} - /// handle system signals void Fluxbox::handleSignal(int signum) { _FB_USES_NLS;

@@ -1808,28 +1750,6 @@ for (AtomHandlerContainerIt it= m_atomhandler.begin();

it != m_atomhandler.end(); it++) (*it).first->updateFocusedWindow(*old_screen, 0); } -} - -void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { - - if (mods == 0) { - cerr<<"WARNING: attempt to grab without modifiers!"<<endl; - return; - } - // just make sure we are saving the mods with any other flags (xkb) - m_watch_keyrelease = FbTk::KeyUtil::instance().isolateModifierMask(mods); - - if (m_watching_screen == &screen) - return; - if (m_watching_screen) - m_watching_screen->focusControl().stopCyclingFocus(); - m_watching_screen = &screen; - - // TODO: it's possible (and happens to me sometimes) for the mods to be - // released before we grab the keyboard -- not sure of a good way to fix it - XGrabKeyboard(FbTk::App::instance()->display(), - screen.rootWindow().window(), True, - GrabModeAsync, GrabModeAsync, CurrentTime); } void Fluxbox::updateFrameExtents(FluxboxWindow &win) {
M src/fluxbox.hhsrc/fluxbox.hh

@@ -141,8 +141,6 @@

void maskWindowEvents(Window w, FluxboxWindow *bw) { m_masked = w; m_masked_window = bw; } - void watchKeyRelease(BScreen &screen, unsigned int mods); - void shutdown(); void load_rc(BScreen &scr); void saveStyleFilename(const char *val) { m_rc_stylefile = (val == 0 ? "" : val); }

@@ -203,8 +201,6 @@ // screen mouse was in at last key event

BScreen *mouseScreen() { return m_mousescreen; } // screen of window that last key event (i.e. focused window) went to BScreen *keyScreen() { return m_keyscreen; } - // screen we are watching for modifier changes - BScreen *watchingScreen() { return m_watching_screen; } const XEvent &lastEvent() const { return m_last_event; } AttentionNoticeHandler &attentionHandler() { return m_attention_handler; }

@@ -228,10 +224,8 @@

void handleEvent(XEvent *xe); void setupConfigFiles(); - void handleButtonEvent(XButtonEvent &be); void handleUnmapNotify(XUnmapEvent &ue); void handleClientMessage(XClientMessageEvent &ce); - void handleKeyEvent(XKeyEvent &ke); std::auto_ptr<FbAtoms> m_fbatoms;

@@ -272,8 +266,6 @@

FluxboxWindow *m_masked_window; BScreen *m_mousescreen, *m_keyscreen; - BScreen *m_watching_screen; - unsigned int m_watch_keyrelease; Atom m_fluxbox_pid;