fixed implementation of _NET_WM_STATE_MODAL
This commit is contained in:
parent
8e75ace959
commit
0f9f193444
6 changed files with 51 additions and 23 deletions
|
@ -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)
|
||||
|
|
17
src/Ewmh.cc
17
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ||
|
||||
|
|
Loading…
Reference in a new issue