Changed title signal in Focusable to new signal system
This commit is contained in:
parent
9ad388c5bf
commit
dd8fcc8b7b
13 changed files with 156 additions and 75 deletions
|
@ -37,10 +37,13 @@ public:
|
|||
ClientMenuItem(Focusable &client, ClientMenu &menu):
|
||||
FbTk::MenuItem(client.title().c_str(), menu),
|
||||
m_client(client) {
|
||||
client.titleSig().attach(&menu);
|
||||
client.dieSig().attach(&menu);
|
||||
}
|
||||
~ClientMenuItem() { m_client.titleSig().detach(menu()); }
|
||||
m_signals.join(client.titleSig(),
|
||||
FbTk::MemFunSelectArg1(menu, &ClientMenu::titleChanged));
|
||||
client.dieSig().attach(&menu);
|
||||
}
|
||||
|
||||
~ClientMenuItem() {
|
||||
}
|
||||
|
||||
void click(int button, int time, unsigned int mods) {
|
||||
FluxboxWindow *fbwin = m_client.fbwindow();
|
||||
|
@ -75,6 +78,7 @@ public:
|
|||
|
||||
private:
|
||||
Focusable &m_client;
|
||||
FbTk::SignalTracker m_signals;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -118,30 +122,46 @@ void ClientMenu::refreshMenu() {
|
|||
updateMenu();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
ClientMenuItem* getMenuItem(ClientMenu& menu, Focusable& win) {
|
||||
// find the corresponding menuitem
|
||||
ClientMenuItem *cl_item = 0;
|
||||
for (size_t i = 0; i < menu.numberOfItems(); i++) {
|
||||
FbTk::MenuItem *item = menu.find(i);
|
||||
if (item && typeid(*item) == typeid(ClientMenuItem)) {
|
||||
cl_item = static_cast<ClientMenuItem *>(item);
|
||||
if (cl_item->client() == &win)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cl_item;
|
||||
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
void ClientMenu::titleChanged(Focusable& win) {
|
||||
// find correct menu item
|
||||
ClientMenuItem* cl_item = getMenuItem(*this, win);
|
||||
if (cl_item)
|
||||
FbTk::Menu::update(0);
|
||||
}
|
||||
|
||||
void ClientMenu::update(FbTk::Subject *subj) {
|
||||
if (subj && typeid(*subj) == typeid(Focusable::FocusSubject)) {
|
||||
|
||||
Focusable::FocusSubject *fsubj = static_cast<Focusable::FocusSubject *>(subj);
|
||||
Focusable &win = fsubj->win();
|
||||
|
||||
// find the corresponding menuitem
|
||||
ClientMenuItem *cl_item = 0;
|
||||
for (size_t i = 0; i < numberOfItems(); i++) {
|
||||
FbTk::MenuItem *item = find(i);
|
||||
if (item && typeid(*item) == typeid(ClientMenuItem)) {
|
||||
cl_item = static_cast<ClientMenuItem *>(item);
|
||||
if (cl_item->client() == &win)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// find correct menu item
|
||||
ClientMenuItem* cl_item = getMenuItem(*this, win);
|
||||
|
||||
// update accordingly
|
||||
if (cl_item && fsubj == &win.dieSig())
|
||||
if (cl_item && fsubj == &win.dieSig()) {
|
||||
remove(cl_item->getIndex());
|
||||
else if (cl_item && fsubj == &win.titleSig())
|
||||
// this could change the size of the menu, so do a full update
|
||||
FbTk::Menu::update(subj);
|
||||
|
||||
}
|
||||
} else
|
||||
FbTk::Menu::update(subj);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
class BScreen;
|
||||
class FluxboxWindow;
|
||||
class Focusable;
|
||||
|
||||
/**
|
||||
* A menu holding a set of client menus.
|
||||
* @see WorkspaceMenu
|
||||
|
@ -47,6 +49,10 @@ public:
|
|||
|
||||
/// refresh the entire menu
|
||||
void refreshMenu();
|
||||
|
||||
/// Called when window title changed.
|
||||
void titleChanged(Focusable& win);
|
||||
|
||||
private:
|
||||
|
||||
void updateClientList(BScreen& screen) {
|
||||
|
|
|
@ -164,7 +164,7 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
|
|||
if (width >= nr_icon_data) {
|
||||
|
||||
fbdbg << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON width ("
|
||||
<< width << ") for " << winclient.title() << "\n";
|
||||
<< width << ") for " << winclient.title() << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
|
|||
if (height >= nr_icon_data) {
|
||||
|
||||
fbdbg << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON height ("
|
||||
<< height << ") for " << winclient.title() << "\n";
|
||||
<< height << ") for " << winclient.title() << "\n";
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
|
|||
// strange values stored in the NETWM_ICON
|
||||
if (i + width * height > nr_icon_data) {
|
||||
fbdbg << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON dimensions ("
|
||||
<< width << "x" << height << ")for " << winclient.title() << "\n";
|
||||
<< width << "x" << height << ")for " << winclient.title() << "\n";
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1293,7 +1293,7 @@ bool Ewmh::propertyNotify(WinClient &winclient, Atom the_property) {
|
|||
if (!newtitle.empty())
|
||||
winclient.setTitle(newtitle);
|
||||
if (winclient.fbwindow())
|
||||
winclient.fbwindow()->titleSig().notify();
|
||||
winclient.fbwindow()->titleSig().emit(newtitle, *winclient.fbwindow());
|
||||
return true;
|
||||
} else if (the_property == m_net->wm_icon_name) {
|
||||
// we don't use icon title, since we don't show icons
|
||||
|
|
|
@ -42,9 +42,10 @@ public:
|
|||
m_screen(scr), m_fbwin(fbwin),
|
||||
m_instance_name("fluxbox"), m_class_name("fluxbox"),
|
||||
m_focused(false), m_attention_state(false),
|
||||
m_titlesig(*this), m_diesig(*this),
|
||||
m_diesig(*this),
|
||||
m_attentionsig(*this),
|
||||
m_focussig() { }
|
||||
m_focussig(),
|
||||
m_titlesig() { }
|
||||
virtual ~Focusable() { }
|
||||
|
||||
/**
|
||||
|
@ -116,10 +117,11 @@ public:
|
|||
@name signals
|
||||
@{
|
||||
*/
|
||||
// Used for both title and icon changes.
|
||||
FbTk::Subject &titleSig() { return m_titlesig; }
|
||||
// Used for both title and icon changes.
|
||||
const FbTk::Subject &titleSig() const { return m_titlesig; }
|
||||
typedef FbTk::Signal<void, const std::string&, Focusable&> TitleSignal;
|
||||
/// Used for both title and icon changes.
|
||||
TitleSignal &titleSig() { return m_titlesig; }
|
||||
/// Used for both title and icon changes.
|
||||
const TitleSignal &titleSig() const { return m_titlesig; }
|
||||
FbTk::Signal<void, Focusable&> &focusSig() { return m_focussig; }
|
||||
const FbTk::Signal<void, Focusable&> &focusSig() const { return m_focussig; }
|
||||
FbTk::Subject &dieSig() { return m_diesig; }
|
||||
|
@ -143,10 +145,11 @@ protected:
|
|||
FbTk::PixmapWithMask m_icon; //< icon pixmap with mask
|
||||
|
||||
// state and hint signals
|
||||
FocusSubject m_titlesig, m_diesig, m_attentionsig;
|
||||
FocusSubject m_diesig, m_attentionsig;
|
||||
|
||||
private:
|
||||
FbTk::Signal<void, Focusable&> m_focussig;
|
||||
TitleSignal m_titlesig;
|
||||
};
|
||||
|
||||
#endif // FOCUSABLE_HH
|
||||
|
|
|
@ -113,10 +113,9 @@ void FocusableList::update(FbTk::Subject *subj) {
|
|||
if (typeid(*subj) == typeid(Focusable::FocusSubject)) {
|
||||
Focusable::FocusSubject *fsubj =
|
||||
static_cast<Focusable::FocusSubject *>(subj);
|
||||
if (fsubj == &fsubj->win().dieSig())
|
||||
if (fsubj == &fsubj->win().dieSig()) {
|
||||
remove(fsubj->win());
|
||||
else if (fsubj == &fsubj->win().titleSig())
|
||||
checkUpdate(fsubj->win());
|
||||
}
|
||||
}
|
||||
if (typeid(*subj) == typeid(FluxboxWindow::WinSubject)) {
|
||||
FluxboxWindow::WinSubject *fsubj =
|
||||
|
@ -244,17 +243,27 @@ void FocusableList::remove(Focusable &win) {
|
|||
bool contained = contains(win);
|
||||
|
||||
detachSignals(win);
|
||||
if (!contained)
|
||||
if (!contained) {
|
||||
return;
|
||||
}
|
||||
m_list.remove(&win);
|
||||
m_removesig.notify(&win);
|
||||
}
|
||||
|
||||
void FocusableList::updateTitle(Focusable& win) {
|
||||
checkUpdate(win);
|
||||
}
|
||||
|
||||
void FocusableList::attachSignals(Focusable &win) {
|
||||
win.dieSig().attach(this);
|
||||
if (m_parent) {
|
||||
// attach various signals for matching
|
||||
win.titleSig().attach(this);
|
||||
if (m_signal_map.find(&win) == m_signal_map.end()) {
|
||||
m_signal_map[&win] = join(win.titleSig(),
|
||||
MemFunSelectArg1(*this,
|
||||
&FocusableList::updateTitle));
|
||||
}
|
||||
|
||||
FluxboxWindow *fbwin = win.fbwindow();
|
||||
if (!fbwin)
|
||||
return;
|
||||
|
@ -268,8 +277,14 @@ void FocusableList::attachSignals(Focusable &win) {
|
|||
void FocusableList::detachSignals(Focusable &win) {
|
||||
win.dieSig().detach(this);
|
||||
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
|
||||
win.titleSig().detach(this);
|
||||
FluxboxWindow *fbwin = win.fbwindow();
|
||||
if (!fbwin)
|
||||
return;
|
||||
|
|
|
@ -116,12 +116,18 @@ private:
|
|||
void attachChild(FocusableList &child) const;
|
||||
void workspaceChanged(BScreen &screen);
|
||||
void focusedWindowChanged(BScreen &screen, FluxboxWindow *win, WinClient *client);
|
||||
/// Title has changed for a window
|
||||
/// @param win The window that title changed for.
|
||||
void updateTitle(Focusable& win);
|
||||
|
||||
std::auto_ptr<ClientPattern> m_pat;
|
||||
const FocusableList *m_parent;
|
||||
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;
|
||||
SignalMap m_signal_map;
|
||||
};
|
||||
|
||||
#endif // FOCUSABLELIST_HH
|
||||
|
|
|
@ -59,15 +59,18 @@ IconButton::IconButton(const FbTk::FbWindow &parent,
|
|||
m_theme(win, focused_theme, unfocused_theme),
|
||||
m_pm(win.screen().imageControl()) {
|
||||
|
||||
m_win.titleSig().attach(this);
|
||||
m_signals.join(m_win.titleSig(),
|
||||
MemFunIgnoreArgs(*this, &IconButton::clientTitleChanged));
|
||||
|
||||
m_signals.join(m_win.focusSig(),
|
||||
MemFunIgnoreArgs(*this, &IconButton::reconfigAndClear));
|
||||
|
||||
m_win.attentionSig().attach(this);
|
||||
|
||||
FbTk::EventManager::instance()->add(*this, m_icon_window);
|
||||
|
||||
reconfigTheme();
|
||||
update(0);
|
||||
refreshEverything(false);
|
||||
}
|
||||
|
||||
IconButton::~IconButton() {
|
||||
|
@ -102,7 +105,7 @@ void IconButton::moveResize(int x, int y,
|
|||
if (m_icon_window.width() != FbTk::Button::width() ||
|
||||
m_icon_window.height() != FbTk::Button::height()) {
|
||||
reconfigTheme();
|
||||
update(0); // update icon window
|
||||
refreshEverything(false); // update icon window
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +114,7 @@ void IconButton::resize(unsigned int width, unsigned int height) {
|
|||
if (m_icon_window.width() != FbTk::Button::width() ||
|
||||
m_icon_window.height() != FbTk::Button::height()) {
|
||||
reconfigTheme();
|
||||
update(0); // update icon window
|
||||
refreshEverything(false); // update icon window
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +143,7 @@ void IconButton::clearArea(int x, int y,
|
|||
void IconButton::setPixmap(bool use) {
|
||||
if (m_use_pixmap != use) {
|
||||
m_use_pixmap = use;
|
||||
update(0);
|
||||
refreshEverything(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,16 +178,7 @@ void IconButton::reconfigAndClear() {
|
|||
clear();
|
||||
}
|
||||
|
||||
void IconButton::update(FbTk::Subject *subj) {
|
||||
// if the window's focus state changed, we need to update the background
|
||||
if (subj == &m_win.attentionSig()) {
|
||||
reconfigAndClear();
|
||||
return;
|
||||
}
|
||||
|
||||
// we got signal that either title or
|
||||
// icon pixmap was updated,
|
||||
// so we refresh everything
|
||||
void IconButton::refreshEverything(bool setup) {
|
||||
|
||||
Display *display = FbTk::App::instance()->display();
|
||||
int screen = m_win.screen().screenNumber();
|
||||
|
@ -242,17 +236,36 @@ void IconButton::update(FbTk::Subject *subj) {
|
|||
|
||||
#endif // SHAPE
|
||||
|
||||
if (subj != 0) {
|
||||
if (setup) {
|
||||
setupWindow();
|
||||
} else {
|
||||
m_icon_window.clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void IconButton::clientTitleChanged() {
|
||||
refreshEverything(true);
|
||||
|
||||
if (m_has_tooltip)
|
||||
showTooltip();
|
||||
}
|
||||
|
||||
void IconButton::update(FbTk::Subject *subj) {
|
||||
// if the window's focus state changed, we need to update the background
|
||||
if (subj == &m_win.attentionSig()) {
|
||||
reconfigAndClear();
|
||||
return;
|
||||
}
|
||||
|
||||
// we got signal that either title or
|
||||
// icon pixmap was updated,
|
||||
// so we refresh everything
|
||||
// if the title was changed AND the mouse is over *this,
|
||||
// update the tooltip
|
||||
if (subj == &m_win.titleSig() && m_has_tooltip)
|
||||
showTooltip();
|
||||
|
||||
refreshEverything(subj != 0);
|
||||
}
|
||||
|
||||
void IconButton::setupWindow() {
|
||||
|
|
|
@ -73,6 +73,12 @@ private:
|
|||
void setupWindow();
|
||||
void showTooltip();
|
||||
|
||||
/// Refresh all pixmaps and windows
|
||||
/// @param setup Wether to setup window again.
|
||||
void refreshEverything(bool setup);
|
||||
/// Called when client title changed.
|
||||
void clientTitleChanged();
|
||||
|
||||
Focusable &m_win;
|
||||
FbTk::FbWindow m_icon_window;
|
||||
FbTk::FbPixmap m_icon_pixmap;
|
||||
|
|
|
@ -278,8 +278,7 @@ void WinButton::clear() {
|
|||
FbTk::Button::clear();
|
||||
drawType();
|
||||
}
|
||||
|
||||
void WinButton::update(FbTk::Subject *subj) {
|
||||
void WinButton::updateAll() {
|
||||
|
||||
// update the menu icon
|
||||
if (m_type == MENUICON && !m_listen_to.empty()) {
|
||||
|
@ -316,3 +315,7 @@ void WinButton::update(FbTk::Subject *subj) {
|
|||
|
||||
clear();
|
||||
}
|
||||
|
||||
void WinButton::update(FbTk::Subject *subj) {
|
||||
updateAll();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "FbTk/Button.hh"
|
||||
#include "FbTk/Observer.hh"
|
||||
#include "FbTk/FbPixmap.hh"
|
||||
#include "FbTk/Signal.hh"
|
||||
|
||||
class FluxboxWindow;
|
||||
class WinButtonTheme;
|
||||
|
@ -35,7 +36,7 @@ template <class T> class ThemeProxy;
|
|||
}
|
||||
|
||||
/// draws and handles basic window button graphic
|
||||
class WinButton:public FbTk::Button, public FbTk::Observer {
|
||||
class WinButton:public FbTk::Button, public FbTk::Observer, public FbTk::SignalTracker {
|
||||
public:
|
||||
/// draw type for the button
|
||||
enum Type {MAXIMIZE, MINIMIZE, SHADE, STICK, CLOSE, MENUICON};
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
/// override for redrawing
|
||||
void clear();
|
||||
void update(FbTk::Subject *subj);
|
||||
void updateAll();
|
||||
private:
|
||||
void drawType();
|
||||
Type m_type; ///< the button type
|
||||
|
|
|
@ -341,13 +341,13 @@ void WinClient::updateTitle() {
|
|||
return;
|
||||
|
||||
m_title = string(Xutil::getWMName(window()), 0, 512);
|
||||
titleSig().notify();
|
||||
titleSig().emit(m_title, *this);
|
||||
}
|
||||
|
||||
void WinClient::setTitle(const FbTk::FbString &title) {
|
||||
m_title = title;
|
||||
m_title_override = true;
|
||||
titleSig().notify();
|
||||
titleSig().emit(m_title, *this);
|
||||
}
|
||||
|
||||
void WinClient::setIcon(const FbTk::PixmapWithMask& pm) {
|
||||
|
@ -355,7 +355,7 @@ void WinClient::setIcon(const FbTk::PixmapWithMask& pm) {
|
|||
m_icon.pixmap().copy(pm.pixmap());
|
||||
m_icon.mask().copy(pm.mask());
|
||||
m_icon_override = true;
|
||||
titleSig().notify();
|
||||
titleSig().emit(m_title, *this);
|
||||
}
|
||||
|
||||
void WinClient::setFluxboxWindow(FluxboxWindow *win) {
|
||||
|
|
|
@ -988,7 +988,7 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
|
|||
button<<endl;
|
||||
|
||||
if (old != &client) {
|
||||
titleSig().notify();
|
||||
titleSig().emit(title(), *this);
|
||||
frame().setFocusTitle(title());
|
||||
frame().setShapingClient(&client, false);
|
||||
}
|
||||
|
@ -2103,7 +2103,7 @@ void FluxboxWindow::propertyNotifyEvent(WinClient &client, Atom atom) {
|
|||
|
||||
case XA_WM_HINTS:
|
||||
client.updateWMHints();
|
||||
titleSig().notify();
|
||||
titleSig().emit(title(), *this);
|
||||
// nothing uses this yet
|
||||
// hintSig().notify(); // notify listeners
|
||||
break;
|
||||
|
@ -2707,18 +2707,19 @@ void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) {
|
|||
//installColormap(false);
|
||||
}
|
||||
|
||||
void FluxboxWindow::setTitle(const std::string& title, Focusable &client) {
|
||||
// only update focus title for current client
|
||||
if (&client != m_client) {
|
||||
return;
|
||||
}
|
||||
|
||||
frame().setFocusTitle(title);
|
||||
// relay title to others that display the focus title
|
||||
titleSig().emit(title, *this);
|
||||
}
|
||||
|
||||
void FluxboxWindow::update(FbTk::Subject *subj) {
|
||||
if (subj && typeid(*subj) == typeid(Focusable::FocusSubject)) {
|
||||
Focusable::FocusSubject &fsubj =
|
||||
static_cast<Focusable::FocusSubject &>(*subj);
|
||||
Focusable &win = fsubj.win();
|
||||
|
||||
if (&fsubj == &win.titleSig() && &win == m_client) {
|
||||
frame().setFocusTitle(win.title());
|
||||
titleSig().notify();
|
||||
}
|
||||
|
||||
} else if (subj == &m_theme.reconfigSig()) {
|
||||
if (subj == &m_theme.reconfigSig()) {
|
||||
frame().applyDecorations();
|
||||
sendConfigureNotify();
|
||||
} else if (m_initialized && subj == &m_frame.frameExtentSig()) {
|
||||
|
@ -3637,7 +3638,9 @@ void FluxboxWindow::updateButtons() {
|
|||
dir[i],
|
||||
frame().titlebar(),
|
||||
0, 0, 10, 10);
|
||||
titleSig().attach(winbtn);
|
||||
winbtn->join(titleSig(),
|
||||
FbTk::MemFunIgnoreArgs(*winbtn, &WinButton::updateAll));
|
||||
|
||||
winbtn->setOnClick(show_menu_cmd);
|
||||
break;
|
||||
}
|
||||
|
@ -3709,7 +3712,8 @@ void FluxboxWindow::associateClient(WinClient &client) {
|
|||
evm.add(*this, btn->window()); // we take care of button events for this
|
||||
evm.add(*this, client.window());
|
||||
client.setFluxboxWindow(this);
|
||||
client.titleSig().attach(this);
|
||||
join(client.titleSig(),
|
||||
FbTk::MemFun(*this, &FluxboxWindow::setTitle));
|
||||
}
|
||||
|
||||
FluxboxWindow::ReferenceCorner FluxboxWindow::getCorner(string str) {
|
||||
|
|
|
@ -474,6 +474,9 @@ public:
|
|||
bool oplock; ///< Used to help stop transient loops occurring by locking a window during certain operations
|
||||
|
||||
private:
|
||||
/// signal callback for title changes by clients
|
||||
void setTitle(const std::string &title, Focusable &client);
|
||||
|
||||
void setupWindow();
|
||||
void updateButtons();
|
||||
|
||||
|
|
Loading…
Reference in a new issue