diff --git a/ChangeLog b/ChangeLog index 71bd0c27..fa6044be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ (Format: Year/Month/Day) Changes for 1.0.0: +*07/07/01: + * More fixes for _NET_WM_STATE_MODAL and _NET_WM_STATE_DEMANDS_ATTENTION, + plus a minor fix for pixmap styles (Mark) + Ewmh.cc Window.cc AttentionNoticeHandler.cc/hh WinClient.cc + WinButtonTheme.cc *07/06/30: * Fixed implementation of _NET_WM_STATE_MODAL (Mark) Ewmh.cc/hh WinClient.cc/hh Window.cc diff --git a/src/AttentionNoticeHandler.cc b/src/AttentionNoticeHandler.cc index a80934a7..10a087c7 100644 --- a/src/AttentionNoticeHandler.cc +++ b/src/AttentionNoticeHandler.cc @@ -95,15 +95,31 @@ void AttentionNoticeHandler::addAttention(WinClient &client) { // attach signals that will make notice go away client.dieSig().attach(this); client.focusSig().attach(this); + + // update _NET_WM_STATE atom + if (client.fbwindow()) + client.fbwindow()->stateSig().notify(); } void AttentionNoticeHandler::update(FbTk::Subject *subj) { + // we need to be able to get the window + if (typeid(*subj) != typeid(WinClient::WinClientSubj)) + return; + // all signals results in destruction of the notice WinClient::WinClientSubj *winsubj = static_cast(subj); delete m_attentions[&winsubj->winClient()]; m_attentions.erase(&winsubj->winClient()); + + // update _NET_WM_STATE atom + FluxboxWindow *fbwin = winsubj->winClient().fbwindow(); + if (fbwin && winsubj != &winsubj->winClient().dieSig()) + fbwin->stateSig().notify(); } +bool AttentionNoticeHandler::isDemandingAttention(WinClient &client) { + return m_attentions.find(&client) != m_attentions.end(); +} diff --git a/src/AttentionNoticeHandler.hh b/src/AttentionNoticeHandler.hh index 836a023e..ed38d205 100644 --- a/src/AttentionNoticeHandler.hh +++ b/src/AttentionNoticeHandler.hh @@ -47,6 +47,8 @@ public: void addAttention(WinClient &client); /// removes the client from the attention map void update(FbTk::Subject *subj); + + bool isDemandingAttention(WinClient &client); private: NoticeMap m_attentions; diff --git a/src/Ewmh.cc b/src/Ewmh.cc index ef2fc096..8fede5e1 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -629,21 +629,25 @@ void Ewmh::updateState(FluxboxWindow &win) { state.push_back(m_net_wm_state_skip_taskbar); if (win.isFullscreen()) state.push_back(m_net_wm_state_fullscreen); - if (win.winClient().isStateModal()) - state.push_back(m_net_wm_state_modal); FluxboxWindow::ClientList::iterator it = win.clientList().begin(); FluxboxWindow::ClientList::iterator it_end = win.clientList().end(); for (; it != it_end; ++it) { - // search the old states for _NET_WM_STATE_SKIP_PAGER and append it - // to the current state, so it wont get deleted by us. StateVec client_state(state); Atom ret_type; int fmt; unsigned long nitems, bytes_after; unsigned char *data = 0; + // set client-specific state + if ((*it)->isStateModal()) + client_state.push_back(m_net_wm_state_modal); + if (Fluxbox::instance()->attentionHandler().isDemandingAttention(**it)) + client_state.push_back(m_net_wm_state_demands_attention); + + // search the old states for _NET_WM_STATE_SKIP_PAGER and append it + // to the current state, so it wont get deleted by us. (*it)->property(m_net_wm_state, 0, 0x7fffffff, False, XA_ATOM, &ret_type, &fmt, &nitems, &bytes_after, &data); diff --git a/src/WinButtonTheme.cc b/src/WinButtonTheme.cc index 22e86fcd..ac6d5f76 100644 --- a/src/WinButtonTheme.cc +++ b/src/WinButtonTheme.cc @@ -67,7 +67,8 @@ WinButtonTheme::~WinButtonTheme() { void WinButtonTheme::reconfigTheme() { // rescale the pixmaps to match frame theme height - unsigned int size = m_frame_theme.titleHeight(); + unsigned int size = m_frame_theme.titleHeight() + - 2 * m_frame_theme.bevelWidth(); if (m_frame_theme.titleHeight() == 0) { // calculate height from font and border width to scale pixmaps size = m_frame_theme.font().height() + 2; diff --git a/src/WinClient.cc b/src/WinClient.cc index fd1944be..d4e3e727 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -129,14 +129,6 @@ WinClient::~WinClient() { clearStrut(); - if (m_win != 0) - m_win->removeClient(*this); - - // this takes care of any focus issues - m_diesig.notify(); - - Fluxbox *fluxbox = Fluxbox::instance(); - // // clear transients and transient_for // @@ -152,6 +144,15 @@ WinClient::~WinClient() { transients.back()->transient_for = 0; transients.pop_back(); } + + if (m_win != 0) + m_win->removeClient(*this); + + // this takes care of any focus issues + m_diesig.notify(); + + Fluxbox *fluxbox = Fluxbox::instance(); + // This fixes issue 1 (see WinClient.hh): // If transients die before the transient_for is created removeTransientFromWaitingList(); diff --git a/src/Window.cc b/src/Window.cc index b44f9f78..2434d312 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -978,6 +978,11 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { if (client.fbwindow() != this) return false; + FbTk::TextButton *button = m_labelbuttons[&client]; + // in case the window is being destroyed, but this should never happen + if (!button) + return false; + if (&client != m_client) m_screen.focusControl().setScreenFocusedWindow(client); m_client = &client; @@ -987,10 +992,10 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { #ifdef DEBUG cerr<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<< - m_labelbuttons[m_client]<