all repos — fluxbox @ 58e19dc91eba51739d4b8ed2dfdbb49e28d96379

custom fork of the fluxbox windowmanager

add most recently used window cycling (Simon)
It is now the default cycling action
rathnor rathnor
commit

58e19dc91eba51739d4b8ed2dfdbb49e28d96379

parent

1aa5ede1b70dfba6519eeaa38101948bbdfea8a2

9 files changed, 289 insertions(+), 80 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,8 @@

(Format: Year/Month/Day) Changes for 0.9.1: +*03/04/15: + * Add most recently used/stacked window cycling, set as default (Simon) + Window.cc Screen.hh/cc fluxbox.hh/cc Keys.hh/cc *03/04/14: * Don't create menuconfig during install and style cleanups (Han) fluxbox_generate_menu
M RoadMapRoadMap

@@ -82,7 +82,7 @@ Major Features:

* Toolbar modes (Simon) = Tabs embedded in titlebar (Henrik) = Tabgroup rewrite (Henrik) - = Most recently used window cycling (Simon) + * Most recently used window cycling (Simon) Minor Features: - per workspace backgrounds (Simon) - more keybinding actions (Both)
M src/Keys.ccsrc/Keys.cc

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Keys.cc,v 1.24 2003/04/14 12:10:16 fluxgen Exp $ +//$Id: Keys.cc,v 1.25 2003/04/15 00:50:24 rathnor Exp $ #include "Keys.hh"

@@ -140,14 +140,18 @@ m_capslock_mod(0),

m_numlock_mod(0), m_scrolllock_mod(0), m_abortkey(0), - m_display(FbTk::App::instance()->display()) + m_display(FbTk::App::instance()->display()), + m_modmap(0) { - determineModmap(); + loadModmap(); if (filename != 0) load(filename); } Keys::~Keys() { + if (m_modmap) { + XFreeModifiermap(m_modmap); + } ungrabKeys(); deleteTree(); }

@@ -458,7 +462,7 @@ */

Keys::KeyAction Keys::getAction(XKeyEvent *ke) { static t_key *next_key = 0; //remove numlock, capslock and scrolllock - ke->state &= ~Mod2Mask & ~Mod5Mask & ~LockMask; + ke->state = cleanMods(ke->state); if (m_abortkey && *m_abortkey==ke) { //abort current keychain next_key = 0;

@@ -636,9 +640,14 @@ }

} /** - determines modifier mapping for caps, num and scroll lock -*/ -void Keys::determineModmap() { + * load state relating to the modifier map + */ +void Keys::loadModmap() { + if (m_modmap) { + XFreeModifiermap(m_modmap); + } + m_modmap = XGetModifierMapping(m_display); + // mask to use for modifier int mods[] = { ShiftMask,

@@ -652,15 +661,14 @@ Mod5Mask,

0 }; - XModifierKeymap *map = XGetModifierMapping(m_display); // find modifiers and set them for (int i=0, realkey=0; i<8; ++i) { - for (int key=0; key<map->max_keypermod; ++key, ++realkey) { + for (int key=0; key<m_modmap->max_keypermod; ++key, ++realkey) { - if (map->modifiermap[realkey] == 0) + if (m_modmap->modifiermap[realkey] == 0) continue; - KeySym ks = XKeycodeToKeysym(m_display, map->modifiermap[realkey], 0); + KeySym ks = XKeycodeToKeysym(m_display, m_modmap->modifiermap[realkey], 0); switch (ks) { case XK_Caps_Lock:

@@ -675,5 +683,21 @@ break;

} } } - XFreeModifiermap(map); +} + +unsigned int Keys::keycodeToModmask(unsigned int keycode) { + if (!m_modmap) return 0; + + // search through modmap for this keycode + for (int mod=0; mod < 8; mod++) { + for (int key=0; key < m_modmap->max_keypermod; ++key) { + // modifiermap is an array with 8 sets of keycodes + // each max_keypermod long, but in a linear array. + if (m_modmap->modifiermap[m_modmap->max_keypermod*mod + key] == keycode) { + return (1<<mod); + } + } + } + // no luck + return 0; }
M src/Keys.hhsrc/Keys.hh

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Keys.hh,v 1.21 2003/04/14 12:10:14 fluxgen Exp $ +// $Id: Keys.hh,v 1.22 2003/04/15 00:50:24 rathnor Exp $ #ifndef KEYS_HH #define KEYS_HH

@@ -74,6 +74,18 @@ */

explicit Keys(const char *filename=0); /// destructor ~Keys(); + + /** + Strip out modifiers we want to ignore + @return the cleaned state number + */ + static unsigned int cleanMods(unsigned int mods) + //remove numlock, capslock and scrolllock + { return mods & (~Mod2Mask & ~Mod5Mask & ~LockMask);} + + unsigned int keycodeToModmask(unsigned int keycode); + void loadModmap(); + /** Load configuration from file @return true on success, else false

@@ -170,8 +182,6 @@ void showTree();

/// debug function void showKeyTree(t_key *key, unsigned int w=0); #endif //DEBUG - /// determine key modifier maps for caps-, num- and scrolllock - void determineModmap(); struct t_actionstr{ const char *string;

@@ -187,6 +197,7 @@ t_key *m_abortkey; ///< abortkey for keygrabbing chain

std::string m_execcmdstring; ///< copy of the execcommandstring int m_param; ///< copy of the param argument Display *m_display; ///< display connection + XModifierKeymap *m_modmap; // Modifier->keycode mapping }; #endif // _KEYS_HH_
M src/Screen.ccsrc/Screen.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.119 2003/04/14 14:49:47 fluxgen Exp $ +// $Id: Screen.cc,v 1.120 2003/04/15 00:50:24 rathnor Exp $ #include "Screen.hh"

@@ -407,6 +407,7 @@ m_workspacecount_sig(*this), // workspace count signal

m_workspacenames_sig(*this), // workspace names signal m_currentworkspace_sig(*this), // current workspace signal m_layermanager(num_layers), + cycling_focus(false), theme(0), m_windowtheme(scrn), m_menutheme(new FbTk::MenuTheme(scrn)), resource(rm, screenname, altscreenname),

@@ -449,6 +450,7 @@ sizeof(pid_t) * 8, PropModeReplace,

(unsigned char *) &bpid, 1); #endif // HAVE_GETPID + cycling_window = focused_list.end(); XDefineCursor(disp, getRootWindow(), fluxbox->getSessionCursor());

@@ -841,6 +843,15 @@ for (; it != it_end; ++it)

(*it)->removeWindow(win); } + +void BScreen::removeClient(WinClient &client) { + WinClient *cyc = *cycling_window; + focused_list.remove(&client); + if (cyc == &client) { + cycling_window = focused_list.end(); + } +} + FluxboxWindow *BScreen::getIcon(unsigned int index) { if (index < iconList.size()) return iconList[index];

@@ -1130,12 +1141,17 @@ if (!win->isManaged()) {

delete win; return 0; } else { + // always put on end of focused list, if it gets focused it'll get pushed up + // there is only the one win client at this stage + focused_list.push_back(&win->winClient()); + + //TODO: is next line needed? Fluxbox::instance()->saveWindowSearch(client, win); Fluxbox::instance()->attachSignals(*win); setupWindowActions(*win); } if (win->getWorkspaceNumber() == getCurrentWorkspaceID() || win->isStuck()) { - win->show(); + win->show(); } XSync(FbTk::App::instance()->display(), False); return win;

@@ -1153,6 +1169,9 @@ if (!win->isManaged()) {

delete win; return 0; } + // don't add to focused_list, as it should already be in there (since the + // WinClient already exists). + Fluxbox::instance()->saveWindowSearch(client.window(), win); Fluxbox::instance()->attachSignals(*win); setupWindowActions(*win);

@@ -1343,27 +1362,58 @@ }

} if (num_windows >= 1) { - Workspace *wksp = getCurrentWorkspace(); - Workspace::Windows &wins = wksp->getWindowList(); - Workspace::Windows::iterator it = wins.begin(); + if (!(opts & CYCLELINEAR)) { + if (!cycling_focus) { + cycling_focus = True; + cycling_window = focused_list.begin(); + } + // if it is stacked, we want the highest window in the focused list + // that is on the same workspace + FocusedWindows::iterator it = cycling_window; + FocusedWindows::iterator it_end = focused_list.end(); - if (!have_focused) { - focused = (*it); - } else { - for (; (*it) != focused; ++it) //get focused window iterator - continue; + while (true) { + ++it; + if (it == it_end) { + it = focused_list.begin(); + } + // give up [do nothing] if we reach the current focused again + if ((*it) == (*cycling_window)) { + break; + } + + FluxboxWindow *fbwin = (*it)->m_win; + if (fbwin && !fbwin->isIconic() && + (fbwin->isStuck() + || fbwin->getWorkspaceNumber() == getCurrentWorkspaceID())) { + // either on this workspace, or stuck + if (! (doSkipWindow(fbwin, opts) || !fbwin->setInputFocus()) ) + break; + } + } + cycling_window = it; + } else { // not stacked cycling + Workspace *wksp = getCurrentWorkspace(); + Workspace::Windows &wins = wksp->getWindowList(); + Workspace::Windows::iterator it = wins.begin(); + + if (!have_focused) { + focused = (*it); + } else { + for (; (*it) != focused; ++it) //get focused window iterator + continue; + } + do { + ++it; + if (it == wins.end()) + it = wins.begin(); + // see if the window should be skipped + if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) ) + break; + } while ((*it) != focused); + if ((*it) != focused && it != wins.end()) + (*it)->raise(); } - do { - ++it; - if (it == wins.end()) - it = wins.begin(); - // see if the window should be skipped - if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) ) - break; - } while ((*it) != focused); - - if ((*it) != focused && it != wins.end()) - (*it)->raise(); }

@@ -1385,29 +1435,62 @@ }

} if (num_windows >= 1) { - Workspace *wksp = getCurrentWorkspace(); - Workspace::Windows &wins = wksp->getWindowList(); - Workspace::Windows::iterator it = wins.begin(); + if (!(opts & CYCLELINEAR)) { + if (!cycling_focus) { + cycling_focus = True; + cycling_window = focused_list.end(); + } + // if it is stacked, we want the highest window in the focused list + // that is on the same workspace + FocusedWindows::iterator it = cycling_window; + FocusedWindows::iterator it_end = focused_list.end(); + + while (true) { + --it; + if (it == it_end) { + it = focused_list.end(); + --it; + } + // give up [do nothing] if we reach the current focused again + if ((*it) == (*cycling_window)) { + break; + } - if (!have_focused) { - focused = (*it); - } else { - for (; (*it) != focused; ++it) //get focused window iterator - continue; + FluxboxWindow *fbwin = (*it)->m_win; + if (fbwin && !fbwin->isIconic() && + (fbwin->isStuck() + || fbwin->getWorkspaceNumber() == getCurrentWorkspaceID())) { + // either on this workspace, or stuck + if (! (doSkipWindow(fbwin, opts) || !fbwin->setInputFocus()) ) + break; + } + } + cycling_window = it; + } else { // not stacked cycling + + Workspace *wksp = getCurrentWorkspace(); + Workspace::Windows &wins = wksp->getWindowList(); + Workspace::Windows::iterator it = wins.begin(); + + if (!have_focused) { + focused = (*it); + } else { + for (; (*it) != focused; ++it) //get focused window iterator + continue; + } + + do { + if (it == wins.begin()) + it = wins.end(); + --it; + // see if the window should be skipped + if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) ) + break; + } while ((*it) != focused); + + if ((*it) != focused && it != wins.end()) + (*it)->raise(); } - - do { - if (it == wins.begin()) - it = wins.end(); - --it; - // see if the window should be skipped - if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) ) - break; - } while ((*it) != focused); - - if ((*it) != focused && it != wins.end()) - (*it)->raise(); - } }

@@ -1426,6 +1509,15 @@ }

if ((getCurrentWorkspace()->getCount() > 1) && have_focused) fb->getFocusedWindow()->raise(); +} + +void BScreen::setFocusedWindow(WinClient &winclient) { + // raise newly focused window to the top of the focused list + if (!cycling_focus) { // don't change the order if we're cycling + focused_list.remove(&winclient); + focused_list.push_front(&winclient); + cycling_window = focused_list.begin(); + } } void BScreen::initMenu() {

@@ -2057,6 +2149,19 @@ bool BScreen::doSkipWindow(const FluxboxWindow *w, int opts) {

return ((opts & CYCLESKIPSTUCK) != 0 && w->isStuck() || // skip if stuck (opts & CYCLESKIPLOWERTABS) != 0 && w->isLowerTab() || // skip if lower tab (opts & CYCLESKIPSHADED) != 0 && w->isShaded()); // skip if shaded +} + +/** + Called when a set of watched modifiers has been released +*/ +void BScreen::notifyReleasedKeys(XKeyEvent &ke) { + if (cycling_focus) { + cycling_focus = false; + // put currently focused window to top + WinClient *client = *cycling_window; + focused_list.erase(cycling_window); + focused_list.push_front(client); + } } /**
M src/Screen.hhsrc/Screen.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.74 2003/04/14 12:13:36 fluxgen Exp $ +// $Id: Screen.hh,v 1.75 2003/04/15 00:50:24 rathnor Exp $ #ifndef SCREEN_HH #define SCREEN_HH

@@ -151,6 +151,7 @@ unsigned int getMaxTop() const;

unsigned int getMaxBottom() const; typedef std::vector<FluxboxWindow *> Icons; + typedef std::list<WinClient *> FocusedWindows; /// @return number of workspaces inline unsigned int getCount() const { return workspacesList.size(); }

@@ -158,6 +159,8 @@ /// @return number of icons

inline unsigned int getIconCount() const { return iconList.size(); } inline const Icons &getIconList() const { return iconList; } inline Icons &getIconList() { return iconList; } + inline const FocusedWindows &getFocusedList() const { return focused_list; } + inline FocusedWindows &getFocusedList() { return focused_list; } const Workspaces &getWorkspacesList() const { return workspacesList; } const WorkspaceNames &getWorkspaceNames() const { return workspaceNames; } /**

@@ -258,6 +261,7 @@ void addIcon(FluxboxWindow *win);

void removeIcon(FluxboxWindow *win); // remove window void removeWindow(FluxboxWindow *win); + void removeClient(WinClient &client); std::string getNameOfWorkspace(unsigned int workspace) const; void changeWorkspaceID(unsigned int);

@@ -269,12 +273,16 @@ void nextFocus() { nextFocus(0); }

void prevFocus(int options); void nextFocus(int options); void raiseFocus(); + void setFocusedWindow(WinClient &winclient); + void reconfigure(); void rereadMenu(); void shutdown(); void showPosition(int x, int y); void showGeometry(unsigned int, unsigned int); void hideGeometry(); + + void notifyReleasedKeys(XKeyEvent &ke); void setLayer(FbTk::XLayerItem &item, int layernum); // remove? no, items are never removed from their layer until they die

@@ -306,7 +314,7 @@ WINDOWSHADE, WINDOWICONIFY, WINDOWMAXIMIZE, WINDOWCLOSE, WINDOWRAISE,

WINDOWLOWER, WINDOWSTICK, WINDOWKILL, SETSTYLE, WINDOWTAB}; // prevFocus/nextFocus option bits enum { CYCLESKIPLOWERTABS = 0x01, CYCLESKIPSTUCK = 0x02, CYCLESKIPSHADED = 0x04, - CYCLEDEFAULT = 0x00 }; + CYCLELINEAR = 0x08, CYCLEDEFAULT = 0x00 }; class ScreenSubject:public FbTk::Subject { public:

@@ -334,10 +342,8 @@ m_workspacenames_sig, ///< workspace names signal

m_currentworkspace_sig; ///< current workspace signal FbTk::MultLayers m_layermanager; - //!! - Theme *theme; ///< obsolete - Bool root_colormap_installed, managed, geom_visible; + Bool root_colormap_installed, managed, geom_visible, cycling_focus; GC opGC; Pixmap geom_pixmap; FbTk::FbWindow geom_window;

@@ -353,6 +359,12 @@

Rootmenus rootmenuList; Netizens netizenList; Icons iconList; + + // This list keeps the order of window focusing for this screen + // Screen global so it works for sticky windows too. + FocusedWindows focused_list; + FocusedWindows::iterator cycling_window; + #ifdef SLIT std::auto_ptr<Slit> m_slit; #endif // SLIT

@@ -368,6 +380,9 @@ Workspaces workspacesList;

Window auto_group_window; + //!! + Theme *theme; ///< obsolete + FbWinFrameTheme m_windowtheme; std::auto_ptr<FbTk::MenuTheme> m_menutheme;
M src/Window.ccsrc/Window.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.131 2003/04/14 14:58:12 fluxgen Exp $ +// $Id: Window.cc,v 1.132 2003/04/15 00:50:25 rathnor Exp $ #include "Window.hh"

@@ -1143,7 +1143,8 @@ return false;

} m_frame.setFocus(true); - + screen.setFocusedWindow(*m_client); + Fluxbox::instance()->setFocusedWindow(this); if (send_focus_message)
M src/fluxbox.ccsrc/fluxbox.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.106 2003/04/14 15:28:52 fluxgen Exp $ +// $Id: fluxbox.cc,v 1.107 2003/04/15 00:50:25 rathnor Exp $ #include "fluxbox.hh"

@@ -373,6 +373,7 @@ m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"),

m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), focused_window(0), masked_window(0), timer(this), + watching_screen(0), watch_keyrelease(0), no_focus(false), rc_file(rc ? rc : ""), argv(m_argv), argc(m_argc),

@@ -699,6 +700,15 @@

case UnmapNotify: handleUnmapNotify(e->xunmap); break; + case MappingNotify: + // Update stored modifier mapping +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<"): MappingNotify"<<endl; +#endif // DEBUG + if (key.get()) { + key->loadModmap(); + } + break; case CreateNotify: break; case DestroyNotify: {

@@ -767,6 +777,7 @@ win->exposeEvent(e->xexpose);

} break; + case KeyRelease: case KeyPress: handleKeyEvent(e->xkey); break;

@@ -1136,9 +1147,19 @@ focused_window->getClientWindow());

} break; case Keys::NEXTWINDOW: //activate next window + if (!watching_screen && !(key->getParam() & BScreen::CYCLELINEAR)) { + // if stacked cycling, then set a watch for + // the release of exactly these modifiers + watchKeyRelease(screen, Keys::cleanMods(ke.state)); + } screen->nextFocus(key->getParam()); break; case Keys::PREVWINDOW: //activate prev window + if (!watching_screen && !(key->getParam() & BScreen::CYCLELINEAR)) { + // if stacked cycling, then set a watch for + // the release of exactly these modifiers + watchKeyRelease(screen, Keys::cleanMods(ke.state)); + } screen->prevFocus(key->getParam()); break; case Keys::NEXTTAB:

@@ -1242,7 +1263,30 @@ }

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 (watching_screen && watch_keyrelease) { + // mask the mod of the released key out + // won't mask anything if it isn't a mod + ke.state &= ~key->keycodeToModmask(ke.keycode); + + if ((watch_keyrelease & ke.state) == 0) { + + watching_screen->notifyReleasedKeys(ke); + XUngrabKeyboard(getXDisplay(), CurrentTime); + + // once they are released, we drop the watch + watching_screen = 0; + watch_keyrelease = 0; + } + } + + break; + } default: break; }

@@ -1470,10 +1514,7 @@ m_atomhandler[i]->updateWindowClose(win);

} // make sure each workspace get this BScreen &scr = win.getScreen(); - for (int workspace = 0; workspace < scr.getNumberOfWorkspaces(); - ++workspace) { - scr.getWorkspace(workspace)->removeWindow(&win); - } + scr.removeWindow(&win); } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal for (size_t i=0; i<m_atomhandler.size(); ++i) {

@@ -1513,13 +1554,12 @@ }

} else if (typeid(*changedsub) == typeid(WinClient::WinClientSubj)) { WinClient::WinClientSubj *subj = dynamic_cast<WinClient::WinClientSubj *>(changedsub); WinClient &client = subj->winClient(); - //!! TODO we shouldn't call update netizen on every screen - // just the screen it was located on - ScreenList::iterator screen_it = screenList.begin(); - const ScreenList::iterator screen_it_end = screenList.end(); - for (; screen_it != screen_it_end; ++screen_it) - (*screen_it)->updateNetizenWindowDel(client.window()); + if (client.fbwindow()) { + BScreen &screen = client.fbwindow()->getScreen(); + screen.updateNetizenWindowDel(client.window()); + screen.removeClient(client); + } removeWindowSearch(client.window()); //!! TODO

@@ -2232,13 +2272,12 @@

if (focused_window != 0) { old_win = focused_window; old_screen = &old_win->getScreen(); - + old_tbar = old_screen->getToolbar(); old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber()); old_win->setFocusFlag(False); old_wkspc->menu().setItemSelected(old_win->getWindowNumber(), false); - } if (win && ! win->isIconic()) {

@@ -2272,3 +2311,10 @@ if (old_screen && old_screen != screen)

old_screen->updateNetizenWindowFocus(); } + +void Fluxbox::watchKeyRelease(BScreen *screen, unsigned int mods) { + watching_screen = screen; + watch_keyrelease = mods; + XGrabKeyboard(getXDisplay(),screen->getRootWindow(), True, + GrabModeAsync, GrabModeAsync, CurrentTime); +}
M src/fluxbox.hhsrc/fluxbox.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.hh,v 1.47 2003/04/14 15:25:14 fluxgen Exp $ +// $Id: fluxbox.hh,v 1.48 2003/04/15 00:50:25 rathnor Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH

@@ -141,6 +141,8 @@ inline void maskWindowEvents(Window w, FluxboxWindow *bw)

{ masked = w; masked_window = bw; } inline void setNoFocus(Bool f) { no_focus = f; } + void watchKeyRelease(BScreen *screen, unsigned int mods); + void setFocusedWindow(FluxboxWindow *w); void shutdown(); void load_rc(BScreen *);

@@ -236,6 +238,8 @@

FluxboxWindow *focused_window, *masked_window; FbTk::Timer timer; + BScreen *watching_screen; + unsigned int watch_keyrelease; #ifdef HAVE_GETPID Atom fluxbox_pid;