Change focused signal to use the new signal system
@@ -1,5 +1,9 @@
(Format: Year/Month/Day) Changes for 1.1.2 +*08/09/28: + * Change focused window signal to use the new signal system (Henrik) + FbTk/Signal.hh, FocusControl.cc, FocusableList.hh/cc, Screen.hh/cc + Window.hh/cc, fluxbox.hh/cc *08/09/21: * Changed icon list signal in BScreen to use the new signal system (Henrik)
@@ -191,8 +191,8 @@ */
class SignalTracker { public: /// Internal type, do not use. - typedef std::list< std::pair<SigImpl::SignalHolder*, - SigImpl::SignalHolder::SlotID> > Connections; + typedef std::map<SigImpl::SignalHolder*, + SigImpl::SignalHolder::SlotID> Connections; typedef Connections::iterator TrackID; ///< \c ID type for join/leave. ~SignalTracker() {@@ -203,9 +203,13 @@ /// Starts tracking a signal.
/// @return A tracking ID ( not unique ) template <typename Signal, typename Functor> TrackID join(Signal& sig, const Functor& functor) { - return - m_connections.insert(m_connections.end(), - Connections::value_type(&sig, sig.connect(functor))); + ValueType value = std::make_pair(&sig, sig.connect(functor)); + std::pair<TrackID, bool> ret = m_connections.insert(value); + if ( !ret.second ) { + // failed to insert this functor + sig.disconnect(value.second); + } + return ret.first; } /// Leave tracking for a signal@@ -217,23 +221,29 @@
/// Leave tracking for a signal /// @param sig the signal to leave template <typename Signal> - void leave(const Signal &sig) { - m_connections.erase(&sig); + void leave(Signal &sig) { + Iterator it = m_connections.find(&sig); + if (it != m_connections.end()) { + it->first->disconnect( it->second ); + m_connections.erase(it); + } } void leaveAll() { // disconnect all connections - for ( Connections::iterator conIt = m_connections.begin(); - conIt != m_connections.end(); ) { + for ( Iterator conIt = m_connections.begin(); + conIt != m_connections.end(); ++conIt) { // keep temporary, while disconnecting we can // in some strange cases get a call to this again - Connections::value_type tmp = *conIt; - conIt = m_connections.erase(conIt); + ValueType tmp = *conIt; + m_connections.erase(conIt); tmp.first->disconnect(tmp.second); } } private: + typedef Connections::value_type ValueType; + typedef Connections::iterator Iterator; /// holds all connections to different signals and slots. Connections m_connections; };
@@ -560,9 +560,9 @@ }
// update AtomHandlers and/or other stuff... if (screen) - screen->focusedWindowSig().notify(); + screen->focusedWindowSig().emit(*screen, s_focused_fbwindow, s_focused_window); if (old_screen && screen != old_screen) - old_screen->focusedWindowSig().notify(); + old_screen->focusedWindowSig().emit(*old_screen, s_focused_fbwindow, s_focused_window); } ////////////////////// FocusControl RESOURCES
@@ -100,8 +100,10 @@ if (m_pat->dependsOnCurrentWorkspace()) {
join(m_screen.currentWorkspaceSig(), FbTk::MemFun(*this, &FocusableList::workspaceChanged)); } - if (m_pat->dependsOnFocusedWindow()) - m_screen.focusedWindowSig().attach(this); + if (m_pat->dependsOnFocusedWindow()) { + join(m_screen.focusedWindowSig(), + FbTk::MemFun(*this, &FocusableList::focusedWindowChanged)); + } } void FocusableList::update(FbTk::Subject *subj) {@@ -150,8 +152,7 @@ return;
if (insertFromParent(*win)) m_ordersig.notify(win); } - } else if (subj == &m_screen.focusedWindowSig()) - reset(); + } } void FocusableList::checkUpdate(Focusable &win) {@@ -315,3 +316,9 @@
void FocusableList::workspaceChanged(BScreen &screen) { reset(); } + +void FocusableList::focusedWindowChanged(BScreen &screen, + FluxboxWindow *focused_win, + WinClient *client) { + reset(); +}
@@ -35,6 +35,8 @@ #include <memory>
class BScreen; class Focusable; +class WinClient; +class FluxboxWindow; class FocusableList: public FbTk::Observer, private FbTk::NotCopyable, private FbTk::SignalTracker {@@ -112,8 +114,8 @@ void attachSignals(Focusable &win);
void detachSignals(Focusable &win); void reset(); void attachChild(FocusableList &child) const; - void workspaceChanged(BScreen& screen); - + void workspaceChanged(BScreen &screen); + void focusedWindowChanged(BScreen &screen, FluxboxWindow *win, WinClient *client); std::auto_ptr<ClientPattern> m_pat; const FocusableList *m_parent; BScreen &m_screen;
@@ -340,7 +340,6 @@ const string &screenname,
const string &altscreenname, int scrn, int num_layers) : m_workspace_area_sig(*this), // workspace area signal - m_focusedwindow_sig(*this), // focused window signal m_reconfigure_sig(*this), // reconfigure signal m_resize_sig(*this), m_layermanager(num_layers),
@@ -223,7 +223,7 @@ FbTk::Subject &workspaceAreaSig() { return m_workspace_area_sig; }
/// current workspace signal ScreenSignal ¤tWorkspaceSig() { return m_currentworkspace_sig; } /// focused window signal - FbTk::Subject &focusedWindowSig() { return m_focusedwindow_sig; } + FbTk::Signal<void, BScreen&, FluxboxWindow*, WinClient*> &focusedWindowSig() { return m_focusedwindow_sig; } /// reconfigure signal FbTk::Subject &reconfigureSig() { return m_reconfigure_sig; } FbTk::Subject &resizeSig() { return m_resize_sig; }@@ -494,10 +494,10 @@ const Strut* availableWorkspaceArea(int head) const;
ScreenSubject m_workspace_area_sig, ///< workspace area changed signal - m_focusedwindow_sig, ///< focused window signal m_reconfigure_sig, ///< reconfigure signal m_resize_sig; ///< resize signal + FbTk::Signal<void, BScreen&, FluxboxWindow*, WinClient*> m_focusedwindow_sig; ///< focused window signal ScreenSignal m_iconlist_sig; ///< notify if a window gets iconified/deiconified ScreenSignal m_clientlist_sig; ///< client signal ScreenSignal m_bg_change_sig; ///< background change signal
@@ -49,6 +49,7 @@ #include "FbTk/EventManager.hh"
#include "FbTk/KeyUtil.hh" #include "FbTk/SimpleCommand.hh" #include "FbTk/Select2nd.hh" +#include "FbTk/MemFun.hh" #ifdef HAVE_CONFIG_H #include "config.h"@@ -1450,8 +1451,10 @@ m_state.fullscreen = true;
frame().applyState(); setFullscreenLayer(); // calls stateSig().notify() - if (!isFocused()) - screen().focusedWindowSig().attach(this); + if (!isFocused()) { + join(screen().focusedWindowSig(), + FbTk::MemFun(*this, &FluxboxWindow::focusedWindowChanged)); + } } else if (!flag && isFullscreen()) {@@ -1769,12 +1772,14 @@ installColormap(focus);
// if we're fullscreen and another window gains focus on the same head, // then we need to let the user see it - if (m_state.fullscreen && !focus) - screen().focusedWindowSig().attach(this); + if (m_state.fullscreen && !focus) { + join(screen().focusedWindowSig(), + FbTk::MemFun(*this, &FluxboxWindow::focusedWindowChanged)); + } if (m_state.fullscreen && focus) { moveToLayer(::Layer::ABOVE_DOCK); - screen().focusedWindowSig().detach(this); + leave(screen().focusedWindowSig()); } if (focus != frame().focused())@@ -2721,9 +2726,6 @@ frame().setFocusTitle(win.title());
titleSig().notify(); } - } else if (subj == &screen().focusedWindowSig()) { - if (FocusControl::focusedFbWindow()) - setFullscreenLayer(); } else if (subj == &m_theme.reconfigSig()) { frame().applyDecorations(); sendConfigureNotify();@@ -3867,3 +3869,10 @@ * NOT YET IMPLEMENTED:
* _NET_WM_WINDOW_TYPE_UTILITY */ } + +void FluxboxWindow::focusedWindowChanged(BScreen &screen, + FluxboxWindow *focused_win, WinClient* client) { + if (focused_win) { + setFullscreenLayer(); + } +}
@@ -31,11 +31,13 @@ #include "FbTk/Subject.hh"
#include "FbTk/Observer.hh" #include "FbTk/EventHandler.hh" #include "FbTk/XLayerItem.hh" +#include "FbTk/Signal.hh" #include "FbWinFrame.hh" #include "Focusable.hh" #include "FocusableTheme.hh" #include "WinButton.hh" + #include <sys/time.h> #include <vector>@@ -58,7 +60,8 @@ }
/// Creates the window frame and handles any window event for it class FluxboxWindow: public Focusable, public FbTk::Observer, - public FbTk::EventHandler { + public FbTk::EventHandler, + private FbTk::SignalTracker { public: /// Motif wm Hints enum {@@ -521,6 +524,8 @@ Time time);
static void ungrabPointer(Time time); void associateClient(WinClient &client); + /// Called when focused changed, and is attached when it is not in fullscreen mode + void focusedWindowChanged(BScreen &screen, FluxboxWindow *focused_win, WinClient* client); // state and hint signals WinSubject m_hintsig,
@@ -453,8 +453,10 @@
screen->initWindows(); // attach screen signals to this - screen->focusedWindowSig().attach(this); screen->workspaceAreaSig().attach(this); + + join(screen->focusedWindowSig(), + FbTk::MemFun(*this, &Fluxbox::focusedWindowChanged)); join(screen->clientListSig(), FbTk::MemFun(*this, &Fluxbox::clientListChanged));@@ -1105,15 +1107,7 @@ screen.removeClient(*client);
} else if (typeid(*changedsub) == typeid(BScreen::ScreenSubject)) { BScreen::ScreenSubject *subj = dynamic_cast<BScreen::ScreenSubject *>(changedsub); BScreen &screen = subj->screen(); - if ((&(screen.focusedWindowSig())) == changedsub) { - for (AtomHandlerContainerIt it= m_atomhandler.begin(); - it != m_atomhandler.end(); it++) { - (*it).first->updateFocusedWindow(screen, - (FocusControl::focusedWindow() ? - FocusControl::focusedWindow()->window() : - 0)); - } - } else if ((&(screen.workspaceAreaSig())) == changedsub) { + if ((&(screen.workspaceAreaSig())) == changedsub) { for (AtomHandlerContainerIt it= m_atomhandler.begin(); it != m_atomhandler.end(); ++it) { if ((*it).first->update())@@ -1537,3 +1531,12 @@ if ((*it).first->update())
(*it).first->updateClientList(screen); } } + +void Fluxbox::focusedWindowChanged(BScreen &screen, + FluxboxWindow* win, + WinClient* client) { + for (AtomHandlerContainerIt it= m_atomhandler.begin(); + it != m_atomhandler.end(); it++) { + (*it).first->updateFocusedWindow(screen, client ? client->window() : 0 ); + } +}
@@ -209,6 +209,10 @@ /// Called when workspace names changed
void workspaceNamesChanged(BScreen &screen); /// Called when the client list changed. void clientListChanged(BScreen &screen); + /// Called when the focused window changed on a screen + void focusedWindowChanged(BScreen &screen, + FluxboxWindow* win, + WinClient* client); std::auto_ptr<FbAtoms> m_fbatoms;