From 7783a8c84e57c4a58d270b9722800a031f50ed62 Mon Sep 17 00:00:00 2001 From: markt Date: Sun, 1 Jul 2007 17:59:57 +0000 Subject: more fixes for _NET_WM_STATE_MODAL and _NET_WM_STATE_DEMANDS_ATTENTION --- ChangeLog | 5 +++++ src/AttentionNoticeHandler.cc | 16 ++++++++++++++++ src/AttentionNoticeHandler.hh | 2 ++ src/Ewmh.cc | 12 ++++++++---- src/WinButtonTheme.cc | 3 ++- src/WinClient.cc | 17 +++++++++-------- src/Window.cc | 9 +++++++-- 7 files changed, 49 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71bd0c2..fa6044b 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 a80934a..10a087c 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 836a023..ed38d20 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 ef2fc09..8fede5e 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 22e86fc..ac6d5f7 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 fd1944b..d4e3e72 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 b44f9f7..2434d31 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]<