Convert Focusable::dieSig to FbTk::Signal

This commit is contained in:
Pavel Labath 2011-05-03 23:48:24 +02:00
parent 0775350fee
commit 129bac1e0f
12 changed files with 82 additions and 107 deletions

View file

@ -88,9 +88,8 @@ void AttentionNoticeHandler::addAttention(Focusable &client) {
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())
@ -104,16 +103,6 @@ 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) {
// all signals results in destruction of the notice

View file

@ -22,10 +22,10 @@
#ifndef ATTENTIONNOTICEHANDLER_HH
#define ATTENTIONNOTICEHANDLER_HH
#include "FbTk/Observer.hh"
#include <map>
#include "FbTk/Signal.hh"
class Focusable;
namespace FbTk {
@ -36,7 +36,7 @@ class Timer;
* 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 @@ public:
/// 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);

View file

@ -40,10 +40,7 @@ public:
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 @@ void ClientMenu::titleChanged(Focusable& win) {
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());
}

View file

@ -25,7 +25,6 @@
#include "FbMenu.hh"
#include "FbTk/Signal.hh"
#include "FbTk/Observer.hh"
class BScreen;
class FluxboxWindow;
@ -35,7 +34,7 @@ class Focusable;
* 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,15 +53,15 @@ public:
/// 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
};

View file

@ -635,18 +635,18 @@ void ChangeLayerCmd::real_execute() {
}
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());
}
// only attached signal is window destruction
void update(FbTk::Subject *subj) { delete this; }
private:
// only attached signal is window destruction
void windowDied() { delete this; }
void exec(const std::string &text) {
window.winClient().setTitle(text);
}

View file

@ -41,9 +41,9 @@ public:
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 @@ public:
/// 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 @@ protected:
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;
};

View file

@ -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::remove(Focusable &win) {
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::attachSignals(Focusable &win) {
}
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)

View file

@ -24,6 +24,7 @@
#include "FbTk/NotCopyable.hh"
#include "FbTk/Observer.hh"
#include "FbTk/RefCount.hh"
#include "FbTk/Subject.hh"
#include "FbTk/Signal.hh"
@ -126,7 +127,7 @@ private:
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;
};

View file

@ -155,7 +155,7 @@ WinClient::~WinClient() {
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

View file

@ -350,7 +350,7 @@ FluxboxWindow::~FluxboxWindow() {
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

View file

@ -943,7 +943,6 @@ void Fluxbox::handleSignal(int signum) {
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 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
} 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,55 +978,63 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
} 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));
BScreen &screen = client->screen();
// 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
// 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::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);
}
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));
BScreen &screen = client.screen();
// 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
// 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) {
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));
}

View file

@ -217,6 +217,10 @@ private:
/// 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;