all repos — fluxbox @ 129bac1e0f0979c80902edc8e092596b81fe14f6

custom fork of the fluxbox windowmanager

Convert Focusable::dieSig to FbTk::Signal
Pavel Labath pavelo@centrum.sk
commit

129bac1e0f0979c80902edc8e092596b81fe14f6

parent

0775350fee345e37fb59835dda4d85664346b606

M src/AttentionNoticeHandler.ccsrc/AttentionNoticeHandler.cc

@@ -88,9 +88,8 @@ timer->start();

m_attentions[&client] = timer; // attach signals that will make notice go away - client.dieSig().attach(this); - - client.focusSig().connect(MemFun(*this, &AttentionNoticeHandler::windowFocusChanged)); + join(client.dieSig(), MemFun(*this, &AttentionNoticeHandler::removeWindow)); + join(client.focusSig(), MemFun(*this, &AttentionNoticeHandler::windowFocusChanged)); // update _NET_WM_STATE atom if (client.fbwindow())

@@ -102,16 +101,6 @@ updateWindow(win, false);

} void AttentionNoticeHandler::removeWindow(Focusable& win) { updateWindow(win, true); -} - -void AttentionNoticeHandler::update(FbTk::Subject* subj) { - // we need to be able to get the window - if (!subj || typeid(*subj) != typeid(Focusable::FocusSubject)) - return; - Focusable::FocusSubject *winsubj = - static_cast<Focusable::FocusSubject *>(subj); - - removeWindow(winsubj->win()); } void AttentionNoticeHandler::updateWindow(Focusable& win, bool died) {
M src/AttentionNoticeHandler.hhsrc/AttentionNoticeHandler.hh

@@ -22,9 +22,9 @@

#ifndef ATTENTIONNOTICEHANDLER_HH #define ATTENTIONNOTICEHANDLER_HH -#include "FbTk/Observer.hh" - #include <map> + +#include "FbTk/Signal.hh" class Focusable;

@@ -36,7 +36,7 @@ * Handles demands attention signals.

* Makes the title and iconbutton flash when the window * demands attention. */ -class AttentionNoticeHandler: public FbTk::Observer { +class AttentionNoticeHandler: private FbTk::SignalTracker { public: ~AttentionNoticeHandler();

@@ -44,8 +44,6 @@ typedef std::map<Focusable*, FbTk::Timer*> NoticeMap;

/// Adds a client that requires attention, /// will fail if the client is already active void addAttention(Focusable &client); - /// removes the client from the attention map - void update(FbTk::Subject *subj); bool isDemandingAttention(const Focusable &client);
M src/ClientMenu.ccsrc/ClientMenu.cc

@@ -40,10 +40,7 @@ FbTk::MenuItem(client.title(), menu),

m_client(client) { m_signals.join(client.titleSig(), FbTk::MemFunSelectArg1(menu, &ClientMenu::titleChanged)); - client.dieSig().attach(&menu); - } - - ~ClientMenuItem() { + m_signals.join(client.dieSig(), FbTk::MemFun(menu, &ClientMenu::clientDied)); } void click(int button, int time, unsigned int mods) {

@@ -156,16 +153,11 @@ if (cl_item)

themeReconfigured(); } -void ClientMenu::update(FbTk::Subject *subj) { - if (Focusable::FocusSubject *fsubj = dynamic_cast<Focusable::FocusSubject *>(subj)) { - Focusable &win = fsubj->win(); +void ClientMenu::clientDied(Focusable &win) { + // find correct menu item + ClientMenuItem* cl_item = getMenuItem(*this, win); - // find correct menu item - ClientMenuItem* cl_item = getMenuItem(*this, win); - - // update accordingly - if (cl_item && fsubj == &win.dieSig()) { - remove(cl_item->getIndex()); - } - } + // update accordingly + if (cl_item) + remove(cl_item->getIndex()); }
M src/ClientMenu.hhsrc/ClientMenu.hh

@@ -25,7 +25,6 @@

#include "FbMenu.hh" #include "FbTk/Signal.hh" -#include "FbTk/Observer.hh" class BScreen; class FluxboxWindow;

@@ -35,7 +34,7 @@ /**

* A menu holding a set of client menus. * @see WorkspaceMenu */ -class ClientMenu: public FbMenu, public FbTk::Observer { +class ClientMenu: public FbMenu { public: typedef std::list<FluxboxWindow *> Focusables;

@@ -54,14 +53,14 @@

/// Called when window title changed. void titleChanged(Focusable& win); + /// Called when a client dies. Removes the corresponding menu item + void clientDied(Focusable& win); + private: void updateClientList(BScreen& screen) { refreshMenu(); } - - /// called when receiving a subject signal - void update(FbTk::Subject *subj); Focusables &m_list; ///< clients in the menu FbTk::SignalTracker m_slots; ///< track all the slots
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -635,18 +635,18 @@ fbwindow().changeLayer(m_diff);

} namespace { -class SetTitleDialog: public TextDialog, public FbTk::Observer { +class SetTitleDialog: public TextDialog, private FbTk::SignalTracker { public: SetTitleDialog(FluxboxWindow &win, const string &title): TextDialog(win.screen(), title), window(win) { - win.dieSig().attach(this); + join(win.dieSig(), FbTk::MemFunIgnoreArgs(*this, &SetTitleDialog::windowDied)); setText(win.title()); } +private: // only attached signal is window destruction - void update(FbTk::Subject *subj) { delete this; } + void windowDied() { delete this; } -private: void exec(const std::string &text) { window.winClient().setTitle(text); }
M src/Focusable.hhsrc/Focusable.hh

@@ -41,9 +41,9 @@ Focusable(BScreen &scr, FluxboxWindow *fbwin = 0):

m_screen(scr), m_fbwin(fbwin), m_instance_name("fluxbox"), m_class_name("fluxbox"), m_focused(false), m_attention_state(false), - m_diesig(*this), m_attentionsig(*this), m_focussig(), + m_diesig(), m_titlesig() { } virtual ~Focusable() { }

@@ -125,9 +125,7 @@ TitleSignal &titleSig() { return m_titlesig; }

/// Used for both title and icon changes. const TitleSignal &titleSig() const { return m_titlesig; } FbTk::Signal<Focusable&> &focusSig() { return m_focussig; } - const FbTk::Signal<Focusable&> &focusSig() const { return m_focussig; } - FbTk::Subject &dieSig() { return m_diesig; } - const FbTk::Subject &dieSig() const { return m_diesig; } + FbTk::Signal<Focusable&> &dieSig() { return m_diesig; } FbTk::Subject &attentionSig() { return m_attentionsig; } const FbTk::Subject &attentionSig() const { return m_attentionsig; } /** @} */ // end group signals

@@ -150,10 +148,11 @@ bool m_attention_state; //< state of icon button while demanding attention

FbTk::PixmapWithMask m_icon; //< icon pixmap with mask // state and hint signals - FocusSubject m_diesig, m_attentionsig; + FocusSubject m_attentionsig; private: FbTk::Signal<Focusable&> m_focussig; + FbTk::Signal<Focusable&> m_diesig; TitleSignal m_titlesig; };
M src/FocusableList.ccsrc/FocusableList.cc

@@ -111,13 +111,6 @@ void FocusableList::update(FbTk::Subject *subj) {

if (subj == 0 || m_screen.isShuttingdown()) return; - if (typeid(*subj) == typeid(Focusable::FocusSubject)) { - Focusable::FocusSubject *fsubj = - static_cast<Focusable::FocusSubject *>(subj); - if (fsubj == &fsubj->win().dieSig()) { - remove(fsubj->win()); - } - } if (typeid(*subj) == typeid(FluxboxWindow::WinSubject)) { FluxboxWindow::WinSubject *fsubj = static_cast<FluxboxWindow::WinSubject *>(subj);

@@ -254,15 +247,17 @@

void FocusableList::updateTitle(Focusable& win) { checkUpdate(win); } +#include "Debug.hh" void FocusableList::attachSignals(Focusable &win) { - win.dieSig().attach(this); if (m_parent) { // attach various signals for matching - if (m_signal_map.find(&win) == m_signal_map.end()) { - m_signal_map[&win] = join(win.titleSig(), - MemFunSelectArg1(*this, - &FocusableList::updateTitle)); + FbTk::RefCount<FbTk::SignalTracker> &tracker = m_signal_map[&win]; + if (! tracker) { + // we have not attached to this window yet + tracker = new SignalTracker; + tracker->join(win.titleSig(), MemFunSelectArg1(*this, &FocusableList::updateTitle)); + tracker->join(win.dieSig(), MemFun(*this, &FocusableList::remove)); } FluxboxWindow *fbwin = win.fbwindow();

@@ -276,15 +271,8 @@ }

} void FocusableList::detachSignals(Focusable &win) { - win.dieSig().detach(this); + m_signal_map.erase(&win); if (m_parent) { - // disconnect client - SignalMap::iterator sigIt = m_signal_map.find(&win); - if (sigIt != m_signal_map.end()) { - leave(sigIt->second); - m_signal_map.erase(sigIt); - } - // detach various signals for matching FluxboxWindow *fbwin = win.fbwindow(); if (!fbwin)
M src/FocusableList.hhsrc/FocusableList.hh

@@ -24,6 +24,7 @@ #define FOCUSABLELIST_HH

#include "FbTk/NotCopyable.hh" #include "FbTk/Observer.hh" +#include "FbTk/RefCount.hh" #include "FbTk/Subject.hh" #include "FbTk/Signal.hh"

@@ -126,7 +127,7 @@ BScreen &m_screen;

std::list<Focusable *> m_list; mutable FocusableListSubject m_ordersig, m_addsig, m_removesig, m_resetsig; - typedef std::map<Focusable*, FbTk::SignalTracker::TrackID> SignalMap; + typedef std::map<Focusable*, FbTk::RefCount<FbTk::SignalTracker> > SignalMap; SignalMap m_signal_map; };
M src/WinClient.ccsrc/WinClient.cc

@@ -155,7 +155,7 @@ if (fbwindow() != 0)

fbwindow()->removeClient(*this); // this takes care of any focus issues - m_diesig.notify(); + dieSig().emit(*this); // This fixes issue 1 (see WinClient.hh): // If transients die before the transient_for is created
M src/Window.ccsrc/Window.cc

@@ -350,7 +350,7 @@

m_timer.stop(); // notify die - m_diesig.notify(); + dieSig().emit(*this); if (m_client != 0 && !m_screen.isShuttingdown()) delete m_client; // this also removes client from our list
M src/fluxbox.ccsrc/fluxbox.cc

@@ -943,7 +943,6 @@

void Fluxbox::update(FbTk::Subject *changedsub) { //TODO: fix signaling, this does not look good FluxboxWindow *fbwin = 0; - WinClient *client = 0; if (typeid(*changedsub) == typeid(FluxboxWindow::WinSubject)) { FluxboxWindow::WinSubject *winsub = dynamic_cast<FluxboxWindow::WinSubject *>(changedsub);

@@ -951,8 +950,6 @@ fbwin = &winsub->win();

} else if (typeid(*changedsub) == typeid(Focusable::FocusSubject)) { Focusable::FocusSubject *winsub = dynamic_cast<Focusable::FocusSubject *>(changedsub); fbwin = winsub->win().fbwindow(); - if (typeid(winsub->win()) == typeid(WinClient)) - client = dynamic_cast<WinClient *>(&winsub->win()); } if (fbwin && &fbwin->stateSig() == changedsub) { // state signal

@@ -981,41 +978,49 @@ }

} else if (fbwin && &fbwin->layerSig() == changedsub) { // layer signal STLUtil::forAllIf(m_atomhandler, mem_fun(&AtomHandler::update), CallMemFunWithRefArg<AtomHandler, FluxboxWindow&, void>(&AtomHandler::updateLayer, *fbwin)); - } else if (fbwin && &fbwin->dieSig() == changedsub) { // window death signal - STLUtil::forAllIf(m_atomhandler, mem_fun(&AtomHandler::update), - CallMemFunWithRefArg<AtomHandler, FluxboxWindow&, void>(&AtomHandler::updateFrameClose, *fbwin)); - - // make sure each workspace get this - BScreen &scr = fbwin->screen(); - scr.removeWindow(fbwin); - if (FocusControl::focusedFbWindow() == fbwin) - FocusControl::setFocusedFbWindow(0); } else if (fbwin && &fbwin->workspaceSig() == changedsub) { // workspace signal STLUtil::forAllIf(m_atomhandler, mem_fun(&AtomHandler::update), CallMemFunWithRefArg<AtomHandler, FluxboxWindow&, void>(&AtomHandler::updateWorkspace, *fbwin)); - } else if (client && &client->dieSig() == changedsub) { // client death - STLUtil::forAllIf(m_atomhandler, mem_fun(&AtomHandler::update), - CallMemFunWithRefArg<AtomHandler, WinClient&, void>(&AtomHandler::updateClientClose, *client)); + } +} + +void Fluxbox::windowDied(Focusable &focusable) { + FluxboxWindow *fbwin = focusable.fbwindow(); + + STLUtil::forAllIf(m_atomhandler, mem_fun(&AtomHandler::update), + CallMemFunWithRefArg<AtomHandler, FluxboxWindow&, void>(&AtomHandler::updateFrameClose, *focusable.fbwindow())); + + // make sure each workspace get this + BScreen &scr = focusable.screen(); + scr.removeWindow(fbwin); + if (FocusControl::focusedFbWindow() == fbwin) + FocusControl::setFocusedFbWindow(0); +} - BScreen &screen = client->screen(); +void Fluxbox::clientDied(Focusable &focusable) { + WinClient &client = dynamic_cast<WinClient &>(focusable); + + STLUtil::forAllIf(m_atomhandler, mem_fun(&AtomHandler::update), + CallMemFunWithRefArg<AtomHandler, WinClient&, void>(&AtomHandler::updateClientClose, client)); - // At this point, we trust that this client is no longer in the - // client list of its frame (but it still has reference to the frame) - // We also assume that any remaining active one is the last focused one + BScreen &screen = client.screen(); - // This is where we revert focus on window close - // NOWHERE ELSE!!! - if (FocusControl::focusedWindow() == client) { - FocusControl::unfocusWindow(*client); - // make sure nothing else uses this window before focus reverts - FocusControl::setFocusedWindow(0); - } else if (FocusControl::expectingFocus() == client) { - FocusControl::setExpectingFocus(0); - revertFocus(); - } + // At this point, we trust that this client is no longer in the + // client list of its frame (but it still has reference to the frame) + // We also assume that any remaining active one is the last focused one - screen.removeClient(*client); + // This is where we revert focus on window close + // NOWHERE ELSE!!! + if (FocusControl::focusedWindow() == &client) { + FocusControl::unfocusWindow(client); + // make sure nothing else uses this window before focus reverts + FocusControl::setFocusedWindow(0); + } else if (FocusControl::expectingFocus() == &client) { + FocusControl::setExpectingFocus(0); + revertFocus(); } + + screen.removeClient(client); } void Fluxbox::attachSignals(FluxboxWindow &win) {

@@ -1023,13 +1028,13 @@ win.hintSig().attach(this);

win.stateSig().attach(this); win.workspaceSig().attach(this); win.layerSig().attach(this); - win.dieSig().attach(this); + join(win.dieSig(), FbTk::MemFun(*this, &Fluxbox::windowDied)); STLUtil::forAll(m_atomhandler, CallMemFunWithRefArg<AtomHandler, FluxboxWindow&, void>(&AtomHandler::setupFrame, win)); } void Fluxbox::attachSignals(WinClient &winclient) { - winclient.dieSig().attach(this); + join(winclient.dieSig(), FbTk::MemFun(*this, &Fluxbox::clientDied)); STLUtil::forAll(m_atomhandler, CallMemFunWithRefArg<AtomHandler, WinClient&, void>(&AtomHandler::setupClient, winclient)); }
M src/fluxbox.hhsrc/fluxbox.hh

@@ -217,6 +217,10 @@ WinClient* client);

/// Called when the workspace area changed. void workspaceAreaChanged(BScreen &screen); + /// Called when a window (FluxboxWindow) dies + void windowDied(Focusable &focusable); + /// Called when a client (WinClient) dies + void clientDied(Focusable &focusable); std::auto_ptr<FbAtoms> m_fbatoms;