fixed implementation of _NET_WM_STATE_MODAL

This commit is contained in:
markt 2007-06-30 16:54:05 +00:00
parent 8e75ace959
commit 0f9f193444
6 changed files with 51 additions and 23 deletions

View file

@ -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)

View file

@ -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());
}
}

View file

@ -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);

View file

@ -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;
void WinClient::removeModal() {
--m_modal;
if (transient_for)
transient_for->removeModal();
m_modal = state;
if (transient_for) {
if (state)
transient_for->addModal();
else
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 {

View file

@ -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;

View file

@ -1372,11 +1372,14 @@ bool FluxboxWindow::setInputFocus() {
#ifdef DEBUG
cerr<<__FUNCTION__<<": transient 0x"<<(*it)<<endl;
#endif // DEBUG
if ((*it)->isModal())
if ((*it)->isStateModal())
return (*it)->focus();
}
}
if (m_client->isModal())
return false;
bool ret = false;
if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE ||