Convert Focusable::dieSig to FbTk::Signal
This commit is contained in:
parent
0775350fee
commit
129bac1e0f
12 changed files with 82 additions and 107 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue