From 103b55e600aff58000ed09ff2b601daf97164167 Mon Sep 17 00:00:00 2001 From: markt Date: Sat, 30 Jun 2007 17:06:29 +0000 Subject: fix support for _NET_WM_STATE_MODAL --- src/Ewmh.cc | 17 ++++++++++++----- src/Ewmh.hh | 1 + src/WinClient.cc | 33 ++++++++++++++++++++++----------- src/WinClient.hh | 16 ++++++++++------ src/Window.cc | 5 ++++- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 99a8759..3ff4e76 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -622,7 +622,7 @@ 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().isModal()) + if (win.winClient().isStateModal()) state.push_back(m_net_wm_state_modal); FluxboxWindow::ClientList::iterator it = win.clientList().begin(); @@ -1004,12 +1004,16 @@ void Ewmh::createAtoms() { utf8_string = XInternAtom(disp, "UTF8_STRING", False); } -// wrapper for avoiding changing every AtomHandler to include an unnecessary -// parameter, although we need it for _NET_WM_STATE_DEMANDS_ATTENTION +// wrapper for real setState, since most operations don't need the client void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) { setState(win, state, value, win.winClient()); } +// wrapper for real toggleState, since most operations don't need the client +void Ewmh::toggleState(FluxboxWindow &win, Atom state) { + toggleState(win, state, win.winClient()); +} + // set window state void Ewmh::setState(FluxboxWindow &win, Atom state, bool value, WinClient &client) { @@ -1057,13 +1061,14 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value, Fluxbox::instance()->attentionHandler(). update(&client.focusSig()); } + } else if (state == m_net_wm_state_modal) { + client.setStateModal(value); } - // Note: state == net_wm_state_modal, We should not change it } // toggle window state -void Ewmh::toggleState(FluxboxWindow &win, Atom state) { +void Ewmh::toggleState(FluxboxWindow &win, Atom state, WinClient &client) { if (state == m_net_wm_state_sticky) { // sticky win.stick(); } else if (state == m_net_wm_state_shaded){ // shaded @@ -1092,6 +1097,8 @@ void Ewmh::toggleState(FluxboxWindow &win, Atom state) { win.moveToLayer(Layer::NORMAL); else win.moveToLayer(Layer::ABOVE_DOCK); + } else if (state == m_net_wm_state_modal) { // modal + client.setStateModal(!client.isStateModal()); } } diff --git a/src/Ewmh.hh b/src/Ewmh.hh index 8d5d986..cc33eff 100644 --- a/src/Ewmh.hh +++ b/src/Ewmh.hh @@ -69,6 +69,7 @@ private: void setState(FluxboxWindow &win, Atom state, bool value, WinClient &client); void toggleState(FluxboxWindow &win, Atom state); + void toggleState(FluxboxWindow &win, Atom state, WinClient &client); void createAtoms(); void updateStrut(WinClient &winclient); void updateActions(FluxboxWindow &win); diff --git a/src/WinClient.cc b/src/WinClient.cc index 3f048d0..b731c34 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -77,7 +77,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin): initial_state(0), normal_hint_flags(0), wm_hint_flags(0), - m_modal(0), + m_modal_count(0), + m_modal(false), send_focus_message(false), send_close_message(false), m_win_gravity(0), @@ -133,13 +134,14 @@ WinClient::~WinClient() { Fluxbox *fluxbox = Fluxbox::instance(); - // // clear transients and transient_for // if (transient_for != 0) { assert(transient_for != this); transient_for->transientList().remove(this); + if (m_modal) + transient_for->removeModal(); transient_for = 0; } @@ -276,6 +278,8 @@ void WinClient::updateTransientInfo() { // remove this from parent if (transientFor() != 0) { transientFor()->transientList().remove(this); + if (m_modal) + transientFor()->removeModal(); } transient_for = 0; @@ -337,6 +341,8 @@ void WinClient::updateTransientInfo() { // we need to add ourself to the right client in // the transientFor() window so we search client transient_for->transientList().push_back(this); + if (m_modal) + transient_for->addModal(); } } @@ -672,16 +678,21 @@ bool WinClient::hasGroupLeftWindow() const { return false; } -void WinClient::addModal() { - ++m_modal; - if (transient_for) - transient_for->addModal(); -} +void WinClient::setStateModal(bool state) { + if (state == m_modal) + return; + + m_modal = state; + if (transient_for) { + if (state) + transient_for->addModal(); + else + transient_for->removeModal(); + } -void WinClient::removeModal() { - --m_modal; - if (transient_for) - transient_for->removeModal(); + // TODO: we're not implementing the following part of EWMH spec: + // "if WM_TRANSIENT_FOR is not set or set to the root window the dialog is + // modal for its window group." } bool WinClient::validateClient() const { diff --git a/src/WinClient.hh b/src/WinClient.hh index 4395f63..d3555d1 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -58,9 +58,6 @@ public: // not aware of anything that makes this false at present inline bool isClosable() const { return true; } - void addModal(); // some transient of ours (or us) is modal - void removeModal(); // some transient (or us) is no longer modal - /// updates from wm class hints void updateWMClassHint(); void updateWMProtocols(); @@ -121,7 +118,9 @@ public: inline const TransientList &transientList() const { return transients; } inline bool isTransient() const { return transient_for != 0; } - inline bool isModal() const { return m_modal > 0; } + inline bool isModal() const { return m_modal_count > 0; } + inline bool isStateModal() const { return m_modal; } + void setStateModal(bool state); inline int gravity() const { return m_win_gravity; } @@ -163,9 +162,14 @@ private: /// removes client from any waiting list and clears empty waiting lists void removeTransientFromWaitingList(); + // some transient of ours (or us) is modal + void addModal() { ++m_modal_count; } + // some transient (or us) is no longer modal + void removeModal() { --m_modal_count; } + // number of transients which we are modal for - // or indicates that we are modal if don't have any transients - int m_modal; + int m_modal_count; + bool m_modal; bool send_focus_message, send_close_message; int m_win_gravity; diff --git a/src/Window.cc b/src/Window.cc index 8b92999..5c27c45 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1418,11 +1418,14 @@ bool FluxboxWindow::focus() { #ifdef DEBUG cerr<<__FUNCTION__<<": transient 0x"<<(*it)<isModal()) + if ((*it)->isStateModal()) return (*it)->focus(); } } + if (m_client->isModal()) + return false; + bool ret = false; if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || -- cgit v0.11.2