moved some code around (regarding event handling) in preparation for upcoming features
This commit is contained in:
parent
9477af82a5
commit
4c1a242968
9 changed files with 110 additions and 158 deletions
|
@ -54,11 +54,11 @@ public:
|
|||
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
|
||||
|
|
|
@ -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 @@ void EventManager::dispatch(Window win, XEvent &ev, bool parent) {
|
|||
evhand->keyPressEvent(ev.xkey);
|
||||
break;
|
||||
case KeyRelease:
|
||||
#ifdef NOT_USED
|
||||
evhand->keyReleaseEvent(ev.xkey);
|
||||
#endif
|
||||
break;
|
||||
case ButtonPress:
|
||||
evhand->buttonPressEvent(ev.xbutton);
|
||||
|
|
|
@ -43,6 +43,10 @@ public:
|
|||
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 @@ public:
|
|||
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
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "fluxbox.hh"
|
||||
#include "FbWinFrameTheme.hh"
|
||||
|
||||
#include "FbTk/EventManager.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -82,7 +84,7 @@ bool doSkipWindow(const WinClient &winclient, int opts) {
|
|||
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;
|
||||
|
|
|
@ -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 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
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 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
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
|
||||
|
@ -538,6 +541,9 @@ BScreen::~BScreen() {
|
|||
if (! managed)
|
||||
return;
|
||||
|
||||
FbTk::EventManager *evm = FbTk::EventManager::instance();
|
||||
evm->remove(rootWindow());
|
||||
|
||||
if (m_rootmenu.get() != 0)
|
||||
m_rootmenu->removeAll();
|
||||
|
||||
|
@ -780,6 +786,59 @@ void BScreen::update(FbTk::Subject *subj) {
|
|||
|
||||
}
|
||||
|
||||
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) {
|
||||
FbTk::Menu *menu = new FbMenu(menuTheme(),
|
||||
imageControl(),
|
||||
|
@ -2054,16 +2113,6 @@ void BScreen::renderPosWindow() {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Called when a set of watched modifiers has been released
|
||||
*/
|
||||
void BScreen::notifyReleasedKeys() {
|
||||
focusControl().stopCyclingFocus();
|
||||
}
|
||||
|
||||
void BScreen::updateSize() {
|
||||
// force update geometry
|
||||
rootWindow().updateGeometry();
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#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 @@ class Subject;
|
|||
/**
|
||||
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 @@ public:
|
|||
|
||||
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();
|
||||
|
@ -294,8 +304,6 @@ public:
|
|||
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
|
||||
|
||||
|
@ -477,6 +485,8 @@ private:
|
|||
typedef std::map<Window, WinClient *> Groupables;
|
||||
Groupables m_expecting_groups;
|
||||
|
||||
bool m_cycling;
|
||||
|
||||
// Xinerama related private data
|
||||
bool m_xinerama_avail;
|
||||
int m_xinerama_num_heads;
|
||||
|
|
|
@ -42,59 +42,15 @@
|
|||
#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() {
|
||||
|
|
|
@ -228,7 +228,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
|
|||
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 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
switch (e->type) {
|
||||
case ButtonRelease:
|
||||
case ButtonPress:
|
||||
handleButtonEvent(e->xbutton);
|
||||
break;
|
||||
case ConfigureRequest: {
|
||||
|
||||
|
@ -894,7 +892,6 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
break;
|
||||
case KeyRelease:
|
||||
case KeyPress:
|
||||
handleKeyEvent(e->xkey);
|
||||
break;
|
||||
case ColormapNotify: {
|
||||
BScreen *screen = searchScreen(e->xcolormap.window);
|
||||
|
@ -958,20 +955,6 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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;
|
||||
|
@ -1810,28 +1752,6 @@ void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
AtomHandlerContainerIt it = m_atomhandler.begin();
|
||||
AtomHandlerContainerIt it_end = m_atomhandler.end();
|
||||
|
|
|
@ -141,8 +141,6 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ private:
|
|||
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 @@ private:
|
|||
FluxboxWindow *m_masked_window;
|
||||
|
||||
BScreen *m_mousescreen, *m_keyscreen;
|
||||
BScreen *m_watching_screen;
|
||||
unsigned int m_watch_keyrelease;
|
||||
|
||||
Atom m_fluxbox_pid;
|
||||
|
||||
|
|
Loading…
Reference in a new issue