From 0f9f19344466cf25170750f768815daf3bdfd2ae Mon Sep 17 00:00:00 2001 From: markt Date: Sat, 30 Jun 2007 16:54:05 +0000 Subject: fixed implementation of _NET_WM_STATE_MODAL --- ChangeLog | 2 ++ src/Ewmh.cc | 17 ++++++++++++----- src/Ewmh.hh | 1 + src/WinClient.cc | 33 ++++++++++++++++++++++----------- src/WinClient.hh | 16 ++++++++++------ src/Window.cc | 5 ++++- 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ea1318..71bd0c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ (Format: Year/Month/Day) Changes for 1.0.0: *07/06/30: + * Fixed implementation of _NET_WM_STATE_MODAL (Mark) + Ewmh.cc/hh WinClient.cc/hh Window.cc * Fixed the groups file, even though it's deprecated (Mark) Workspace.cc Screen.cc * Fix _NET_WM_STATE_DEMANDS_ATTENTION with tabbed windows, #1732392 (Mark) diff --git a/src/Ewmh.cc b/src/Ewmh.cc index b4e831d..ef2fc09 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -629,7 +629,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(); @@ -1031,12 +1031,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) { @@ -1084,13 +1088,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 @@ -1119,6 +1124,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 c1a6868..00979a1 100644 --- a/src/Ewmh.hh +++ b/src/Ewmh.hh @@ -70,6 +70,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 250a0b8..fd1944b 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -76,7 +76,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb normal_hint_flags(0), wm_hint_flags(0), m_win(fbwin), - m_modal(0), + m_modal_count(0), + m_modal(false), send_focus_message(false), send_close_message(false), m_win_gravity(0), @@ -136,13 +137,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(); } } @@ -663,16 +669,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 40daa8e..01517c2 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -57,9 +57,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(); @@ -127,7 +124,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); const FbTk::FbPixmap &iconPixmap() const { return m_icon_pixmap; } const FbTk::FbPixmap &iconMask() const { return m_icon_mask; } @@ -188,11 +187,16 @@ 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; } + FluxboxWindow *m_win; // 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 1c839f6..b44f9f7 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1372,11 +1372,14 @@ bool FluxboxWindow::setInputFocus() { #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