all repos — fluxbox @ a23ad6719725a0290d01ac4bba0ce1905b2069d7

custom fork of the fluxbox windowmanager

Make Urgency Hint flash the correct WinClient's tab.
markt markt
commit

a23ad6719725a0290d01ac4bba0ce1905b2069d7

parent

0b730c76b10babe20738067ae7aec5a102d451fe

M ChangeLogChangeLog

@@ -1,6 +1,9 @@

(Format: Year/Month/Day) Changes for 1.0rc2: *06/06/24: + * Make Urgency Hint flash the correct tab in a group (Mark) + Ewmh.cc Window.cc/hh WinClient.cc/hh FbWinFrame.cc/hh IconbarTool.cc + AttentionNoticeHandler.cc/hh * Fix some more X-errors (Simon) - window was resized, triggering background re-render, but background is invalid sometimes (during reconfiguring)
M src/AttentionNoticeHandler.ccsrc/AttentionNoticeHandler.cc

@@ -23,7 +23,7 @@ // $Id$

#include "AttentionNoticeHandler.hh" -#include "Window.hh" +#include "WinClient.hh" #include "Screen.hh" #include "STLUtil.hh"

@@ -34,14 +34,16 @@

namespace { class ToggleFrameFocusCmd: public FbTk::Command { public: - ToggleFrameFocusCmd(FluxboxWindow &win): - m_win(win) {} + ToggleFrameFocusCmd(WinClient &client): + m_client(client) {} void execute() { - m_win.frame().setFocus( ! m_win.frame().focused() ); - m_win.attentionSig().notify(); + m_state ^= true; + m_client.fbwindow()->setLabelButtonFocus(m_client, m_state); + m_client.fbwindow()->setAttentionState(m_state); } private: - FluxboxWindow& m_win; + WinClient& m_client; + bool m_state; }; } // end anonymous namespace

@@ -51,27 +53,27 @@ AttentionNoticeHandler::~AttentionNoticeHandler() {

STLUtil::destroyAndClearSecond(m_attentions); } -void AttentionNoticeHandler::addAttention(FluxboxWindow &win) { - // no need to add already focused window - if (win.isFocused()) +void AttentionNoticeHandler::addAttention(WinClient &client) { + // no need to add already active client + if (client.fbwindow()->isFocused() && &client.fbwindow()->winClient() == &client) return; // Already have a notice for it? - NoticeMap::iterator it = m_attentions.find(&win); + NoticeMap::iterator it = m_attentions.find(&client); if (it != m_attentions.end()) { return; } using namespace FbTk; - ResourceManager &res = win.screen().resourceManager(); - std::string res_name = win.screen().name() + ".demandsAttentionTimeout"; - std::string res_alt_name = win.screen().name() + ".DemandsAttentionTimeout"; + ResourceManager &res = client.screen().resourceManager(); + std::string res_name = client.screen().name() + ".demandsAttentionTimeout"; + std::string res_alt_name = client.screen().name() + ".DemandsAttentionTimeout"; Resource<int> *timeout_res = dynamic_cast<Resource<int>* >(res.findResource(res_name)); if (timeout_res == 0) { // no resource, create one and add it to managed resources timeout_res = new FbTk::Resource<int>(res, 500, res_name, res_alt_name); - win.screen().addManagedResource(timeout_res); + client.screen().addManagedResource(timeout_res); } // disable if timeout is zero if (**timeout_res == 0)

@@ -82,25 +84,25 @@ // setup timer

timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = **timeout_res * 1000; - RefCount<Command> cmd(new ToggleFrameFocusCmd(win)); + RefCount<Command> cmd(new ToggleFrameFocusCmd(client)); timer->setCommand(cmd); timer->setTimeout(timeout); timer->fireOnce(false); // will repeat until window has focus timer->start(); - m_attentions[&win] = timer; + m_attentions[&client] = timer; // attach signals that will make notice go away - win.dieSig().attach(this); - win.focusSig().attach(this); + client.dieSig().attach(this); + client.focusSig().attach(this); } void AttentionNoticeHandler::update(FbTk::Subject *subj) { // all signals results in destruction of the notice - FluxboxWindow::WinSubject *winsubj = - static_cast<FluxboxWindow::WinSubject*>(subj); - delete m_attentions[&winsubj->win()]; - m_attentions.erase(&winsubj->win()); + WinClient::WinClientSubj *winsubj = + static_cast<WinClient::WinClientSubj *>(subj); + delete m_attentions[&winsubj->winClient()]; + m_attentions.erase(&winsubj->winClient()); }
M src/AttentionNoticeHandler.hhsrc/AttentionNoticeHandler.hh

@@ -27,7 +27,7 @@ #include "FbTk/Observer.hh"

#include <map> -class FluxboxWindow; +class WinClient; namespace FbTk { class Timer;

@@ -41,11 +41,11 @@ class AttentionNoticeHandler: public FbTk::Observer {

public: ~AttentionNoticeHandler(); - typedef std::map<FluxboxWindow*, FbTk::Timer*> NoticeMap; - /// Adds a window that requires attention, - /// will fail if the window is already focused - void addAttention(FluxboxWindow &win); - /// removes the window from the attention map + typedef std::map<WinClient*, FbTk::Timer*> NoticeMap; + /// Adds a client that requires attention, + /// will fail if the client is already active + void addAttention(WinClient &client); + /// removes the client from the attention map void update(FbTk::Subject *subj); private:
M src/Ewmh.ccsrc/Ewmh.cc

@@ -1084,10 +1084,10 @@ else

win.moveToLayer(Layer::NORMAL); } else if (state == m_net_wm_state_demands_attention) { if (value) { // if add attention - Fluxbox::instance()->attentionHandler().addAttention(win); + Fluxbox::instance()->attentionHandler().addAttention(win.winClient()); } else { // erase it Fluxbox::instance()->attentionHandler(). - update(&win.attentionSig()); + update(&win.winClient().focusSig()); } }
M src/FbWinFrame.ccsrc/FbWinFrame.cc

@@ -650,6 +650,18 @@ else

applyActiveLabel(*m_current_label); } +void FbWinFrame::setLabelButtonFocus(FbTk::TextButton &btn, bool value) { + if (btn.parent() != &m_tab_container) + return; + + if (value) + applyFocusLabel(btn); + else + applyUnfocusLabel(btn); + + btn.clear(); +} + void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { win.setBorderWidth(0);
M src/FbWinFrame.hhsrc/FbWinFrame.hh

@@ -150,6 +150,8 @@ //move the first label button to the right of the second

void moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); /// which button is to be rendered focused void setLabelButtonFocus(FbTk::TextButton &btn); + /// specify focus state of button + void setLabelButtonFocus(FbTk::TextButton &btn, bool value); /// attach a client window for client area void setClientWindow(FbTk::FbWindow &win); /// remove attached client window
M src/IconbarTool.ccsrc/IconbarTool.cc

@@ -601,7 +601,7 @@ // render with titlebar focus, on attention

IconButton *button = findButton(winsubj->win()); if (button) { renderButton(*button, true, - winsubj->win().frame().focused() ? 1 : 0); + winsubj->win().getAttentionState()); } return; } else {
M src/WinClient.ccsrc/WinClient.cc

@@ -74,7 +74,8 @@ m_icon_title_override(false),

m_blackbox_hint(0), m_mwm_hint(0), m_focus_mode(F_PASSIVE), - m_diesig(*this), m_screen(screen), + m_diesig(*this), m_focussig(*this), + m_screen(screen), m_strut(0) { updateWMProtocols(); updateBlackboxHints();

@@ -516,10 +517,10 @@ m_icon_mask = 0;

if (m_win && m_win->isInitialized()) { if (wmhint->flags & XUrgencyHint) { - Fluxbox::instance()->attentionHandler().addAttention(*m_win); + Fluxbox::instance()->attentionHandler().addAttention(*this); } else { Fluxbox::instance()->attentionHandler(). - update(&(m_win->attentionSig())); + update(&m_focussig); } }
M src/WinClient.hhsrc/WinClient.hh

@@ -117,6 +117,8 @@ BScreen &screen() { return m_screen; }

const BScreen &screen() const { return m_screen; } /// notifies when this client dies FbTk::Subject &dieSig() { return m_diesig; } + /// notifies when this client becomes focused + FbTk::Subject &focusSig() { return m_focussig; } inline WinClient *transientFor() { return transient_for; } inline const WinClient *transientFor() const { return transient_for; }

@@ -211,6 +213,7 @@

int m_focus_mode; WinClientSubj m_diesig; + WinClientSubj m_focussig; BScreen &m_screen; Strut *m_strut;
M src/Window.ccsrc/Window.cc

@@ -1065,6 +1065,7 @@ return false;

m_client = &client; m_client->raise(); + m_client->focusSig().notify(); titleSig().notify(); #ifdef DEBUG

@@ -1079,6 +1080,19 @@ return true;

} return false; +} + +void FluxboxWindow::setLabelButtonFocus(WinClient &client, bool value) { + // make sure it's in our list + if (client.fbwindow() != this) + return; + + frame().setLabelButtonFocus(*m_labelbuttons[&client], value); +} + +void FluxboxWindow::setAttentionState(bool value) { + m_attention_state = value; + m_attentionsig.notify(); } bool FluxboxWindow::isGroupable() const {

@@ -2095,8 +2109,11 @@ m_timer.stop();

} // did focus change? notify listeners - if (was_focused != focus) + if (was_focused != focus) { m_focussig.notify(); + if (m_client) + m_client->focusSig().notify(); + } }
M src/Window.hhsrc/Window.hh

@@ -178,6 +178,9 @@ /// remove client from client list

bool removeClient(WinClient &client); /// set new current client and raise it bool setCurrentClient(WinClient &client, bool setinput = true); + void setLabelButtonFocus(WinClient &client, bool value = true); + void setAttentionState(bool value); + bool getAttentionState() { return m_attention_state; } WinClient *findClient(Window win); void nextClient(); void prevClient();

@@ -500,6 +503,7 @@ int maximized;

WinClient *m_attaching_tab; + bool m_attention_state; BScreen &m_screen; /// screen on which this window exist FbTk::Timer m_timer; Display *display; /// display connection