all repos — fluxbox @ dd8fcc8b7b4c2bccf90edf9b0acfa52e21f5d1ce

custom fork of the fluxbox windowmanager

Changed title signal in Focusable to new signal system
Henrik Kinnunen fluxgen@fluxbox.org
commit

dd8fcc8b7b4c2bccf90edf9b0acfa52e21f5d1ce

parent

9ad388c5bf160c8a6c90d76065286540274685fd

M src/ClientMenu.ccsrc/ClientMenu.cc

@@ -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 @@ Focusable *client() { return &m_client; }

private: Focusable &m_client; + FbTk::SignalTracker m_signals; }; } // end anonymous namespace

@@ -118,30 +122,46 @@

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); }
M src/ClientMenu.hhsrc/ClientMenu.hh

@@ -28,6 +28,8 @@ #include "FbTk/Signal.hh"

class BScreen; class FluxboxWindow; +class Focusable; + /** * A menu holding a set of client menus. * @see WorkspaceMenu

@@ -47,6 +49,10 @@ Focusables &clients, bool listen_for_iconlist_changes);

/// refresh the entire menu void refreshMenu(); + + /// Called when window title changed. + void titleChanged(Focusable& win); + private: void updateClientList(BScreen& screen) {
M src/Ewmh.ccsrc/Ewmh.cc

@@ -164,7 +164,7 @@ width = raw_data[i++];

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 @@ height = raw_data[i++];

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 @@

// 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 @@ FbTk::FbString newtitle = winclient.textProperty(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
M src/Focusable.hhsrc/Focusable.hh

@@ -42,9 +42,10 @@ 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_titlesig(*this), m_diesig(*this), + m_diesig(*this), m_attentionsig(*this), - m_focussig() { } + m_focussig(), + m_titlesig() { } virtual ~Focusable() { } /**

@@ -116,10 +117,11 @@ /**

@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 @@ 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_titlesig, m_diesig, m_attentionsig; + FocusSubject m_diesig, m_attentionsig; private: FbTk::Signal<void, Focusable&> m_focussig; + TitleSignal m_titlesig; }; #endif // FOCUSABLE_HH
M src/FocusableList.ccsrc/FocusableList.cc

@@ -113,10 +113,9 @@

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 @@ // if the window isn't already in this list, we could send a bad signal

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::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;
M src/FocusableList.hhsrc/FocusableList.hh

@@ -116,12 +116,18 @@ void reset();

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
M src/IconButton.ccsrc/IconButton.cc

@@ -59,15 +59,18 @@ m_has_tooltip(false),

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 @@

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 @@ FbTk::TextButton::resize(width, 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::setPixmap(bool use) { if (m_use_pixmap != use) { m_use_pixmap = use; - update(0); + refreshEverything(false); } }

@@ -175,16 +178,7 @@ reconfigTheme();

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 @@ ShapeSet);

#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() {
M src/IconButton.hhsrc/IconButton.hh

@@ -73,6 +73,12 @@ void reconfigAndClear();

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;
M src/WinButton.ccsrc/WinButton.cc

@@ -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 @@ }

clear(); } + +void WinButton::update(FbTk::Subject *subj) { + updateAll(); +}
M src/WinButton.hhsrc/WinButton.hh

@@ -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 @@ Pixmap getPressedPixmap() const;

/// override for redrawing void clear(); void update(FbTk::Subject *subj); + void updateAll(); private: void drawType(); Type m_type; ///< the button type
M src/WinClient.ccsrc/WinClient.cc

@@ -341,13 +341,13 @@ if (m_title_override)

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 @@

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) {
M src/Window.ccsrc/Window.cc

@@ -988,7 +988,7 @@ fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<

button<<endl; if (old != &client) { - titleSig().notify(); + titleSig().emit(title(), *this); frame().setFocusTitle(title()); frame().setShapingClient(&client, false); }

@@ -2103,7 +2103,7 @@ } break;

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 @@ //if (ev.window == frame().window())

//installColormap(false); } -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(); +void FluxboxWindow::setTitle(const std::string& title, Focusable &client) { + // only update focus title for current client + if (&client != m_client) { + return; + } - if (&fsubj == &win.titleSig() && &win == m_client) { - frame().setFocusTitle(win.title()); - titleSig().notify(); - } + frame().setFocusTitle(title); + // relay title to others that display the focus title + titleSig().emit(title, *this); +} - } else if (subj == &m_theme.reconfigSig()) { +void FluxboxWindow::update(FbTk::Subject *subj) { + if (subj == &m_theme.reconfigSig()) { frame().applyDecorations(); sendConfigureNotify(); } else if (m_initialized && subj == &m_frame.frameExtentSig()) {

@@ -3637,7 +3638,9 @@ screen().pressedWinButtonTheme(),

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 @@

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) {
M src/Window.hhsrc/Window.hh

@@ -474,6 +474,9 @@

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();