From 75d289be65e12ac8c1b36a21ee9db8fee7cf1897 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Sun, 23 Apr 2006 17:00:33 +0000 Subject: added support for _NET_WM_ALLOWED_ACTIONS and all the _NET_WM_ACTION_*. Added _NET_WM_STATE_MODAL and _NET_WM_WINDOW_TYPE_SPLASH --- src/Ewmh.cc | 149 +++++++++++++++++++++++++++++++++++++++++---------- src/Ewmh.hh | 4 ++ src/Makefile.am | 1 + src/WinClientUtil.cc | 32 +++++++++++ src/WinClientUtil.hh | 19 +++++++ src/Window.hh | 1 + 6 files changed, 178 insertions(+), 28 deletions(-) create mode 100644 src/WinClientUtil.cc create mode 100644 src/WinClientUtil.hh diff --git a/src/Ewmh.cc b/src/Ewmh.cc index fc762e7..6f12ab7 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -28,6 +28,8 @@ #include "WinClient.hh" #include "Workspace.hh" #include "Layer.hh" +#include "WinClientUtil.hh" + #include "FbTk/App.hh" #include "FbTk/FbWindow.hh" #include "FbTk/I18n.hh" @@ -109,11 +111,28 @@ void Ewmh::initForScreen(BScreen &screen) { m_net_wm_state_fullscreen, m_net_wm_state_hidden, m_net_wm_state_skip_taskbar, - + m_net_wm_state_modal, + m_net_wm_state_below, + m_net_wm_state_above, + // window type m_net_wm_window_type, m_net_wm_window_type_dock, m_net_wm_window_type_desktop, + m_net_wm_window_type_splash, + + // window actions + m_net_wm_allowed_actions, + m_net_wm_action_move, + m_net_wm_action_resize, + m_net_wm_action_minimize, + m_net_wm_action_shade, + m_net_wm_action_stick, + m_net_wm_action_maximize_horz, + m_net_wm_action_maximize_vert, + m_net_wm_action_fullscreen, + m_net_wm_action_change_desktop, + m_net_wm_action_close, // root properties m_net_client_list, @@ -223,6 +242,15 @@ void Ewmh::setupFrame(FluxboxWindow &win) { win.setMovable(false); win.setResizable(false); win.stick(); + + } else if (atoms[l] == m_net_wm_window_type_splash) { + /* + * _NET_WM_WINDOW_TYPE_SPLASH indicates that the + * window is a splash screen displayed as an application + * is starting up. + */ + win.setDecoration(FluxboxWindow::DECOR_NONE); + win.setMovable(false); } } @@ -297,7 +325,8 @@ void Ewmh::updateClientList(BScreen &screen) { Window *wl = FB_new_nothrow Window[num]; if (wl == 0) { _FB_USES_NLS; - cerr<<_FBTEXT(Ewmh, OutOfMemoryClientList, "Fatal: Out of memory, can't allocate for EWMH client list", "")< StateVec; @@ -542,14 +571,13 @@ void Ewmh::updateState(FluxboxWindow &win) { state.push_back(m_net_wm_state_hidden); if (win.isIconHidden()) state.push_back(m_net_wm_state_skip_taskbar); - if (win.isFullscreen()) { + if (win.isFullscreen()) state.push_back(m_net_wm_state_fullscreen); - } + if (win.winClient().isModal()) + state.push_back(m_net_wm_state_modal); FluxboxWindow::ClientList::iterator it = win.clientList().begin(); FluxboxWindow::ClientList::iterator it_end = win.clientList().end(); - - it = win.clientList().begin(); for (; it != it_end; ++it) { // search the old states for _NET_WM_STATE_SKIP_PAGER and append it @@ -565,18 +593,19 @@ void Ewmh::updateState(FluxboxWindow &win) { &data); if (data) { Atom *old_states = (Atom *)data; - for (unsigned long i=0; i < nitems; ++i) + for (unsigned long i=0; i < nitems; ++i) { if (old_states[i] == m_net_wm_state_skip_pager) { client_state.push_back(m_net_wm_state_skip_pager); } + } XFree(data); } - if (!client_state.empty()) + if (!client_state.empty()) { (*it)->changeProperty(m_net_wm_state, XA_ATOM, 32, PropModeReplace, reinterpret_cast(&client_state.front()), client_state.size()); - else + } else (*it)->deleteProperty(m_net_wm_state); } } @@ -750,9 +779,6 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, bool Ewmh::propertyNotify(WinClient &winclient, Atom the_property) { if (the_property == m_net_wm_strut) { -#ifdef DEBUG - cerr<<"_NET_WM_STRUT"< ActionsVector; + ActionsVector actions; + actions.reserve(10); + // all windows can change desktop, + // be shaded or be sticky + actions.push_back(m_net_wm_action_change_desktop); + actions.push_back(m_net_wm_action_shade); + actions.push_back(m_net_wm_action_stick); + + if (win.isResizable()) + actions.push_back(m_net_wm_action_resize); + if (win.isMoveable()) + actions.push_back(m_net_wm_action_move); + if (win.isClosable()) + actions.push_back(m_net_wm_action_close); + if (win.isIconifiable()) + actions.push_back(m_net_wm_action_minimize); + + unsigned int max_width, max_height; + WinClientUtil::maxSize(win.clientList(), max_width, max_height); + + // if unlimited max width we can maximize horizontal + if (max_width == 0) { + actions.push_back(m_net_wm_action_maximize_horz); + } + // if unlimited max height we can maxmize vert + if (max_height == 0) { + actions.push_back(m_net_wm_action_maximize_vert); + } + + // if we have unlimited size in all directions we can have this window + // in fullscreen mode + if (max_height == 0 && max_width == 0) { + actions.push_back(m_net_wm_action_fullscreen); + } + + + + FluxboxWindow::ClientList::iterator it = win.clientList().begin(); + FluxboxWindow::ClientList::iterator it_end = win.clientList().end(); + for (; it != it_end; ++it) { + (*it)->changeProperty(m_net_wm_allowed_actions, XA_ATOM, 32, PropModeReplace, + reinterpret_cast(&actions.front()), + actions.size()); + } + +} + void Ewmh::setupState(FluxboxWindow &win) { /* From Extended Window Manager Hints, draft 1.3: * diff --git a/src/Ewmh.hh b/src/Ewmh.hh index 59c9877..b1f5d39 100644 --- a/src/Ewmh.hh +++ b/src/Ewmh.hh @@ -77,6 +77,8 @@ private: void toggleState(FluxboxWindow &win, Atom state); void createAtoms(); void updateStrut(WinClient &winclient); + void updateActions(FluxboxWindow &win); + void setupState(FluxboxWindow &win); // root window properties @@ -94,6 +96,7 @@ private: m_net_wm_window_type, m_net_wm_window_type_dock, m_net_wm_window_type_desktop, + m_net_wm_window_type_splash, // states m_net_wm_state, m_net_wm_state_sticky, m_net_wm_state_shaded, @@ -104,6 +107,7 @@ private: m_net_wm_state_skip_pager, m_net_wm_state_below, m_net_wm_state_above, + m_net_wm_state_modal, // allowed actions m_net_wm_allowed_actions, diff --git a/src/Makefile.am b/src/Makefile.am index 38a3b39..890c06c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,6 +135,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ RowSmartPlacement.hh RowSmartPlacement.cc \ ScreenPlacement.hh ScreenPlacement.cc \ UnderMousePlacement.hh UnderMousePlacement.cc \ + WinClientUtil.hh WinClientUtil.cc \ ${newwmspec_SOURCE} ${gnome_SOURCE} \ ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE} diff --git a/src/WinClientUtil.cc b/src/WinClientUtil.cc new file mode 100644 index 0000000..112360d --- /dev/null +++ b/src/WinClientUtil.cc @@ -0,0 +1,32 @@ +#include "WinClientUtil.hh" +#include "WinClient.hh" + +#include + +namespace WinClientUtil { + +void maxSize(const FluxboxWindow::ClientList &clients, + unsigned int &max_width, unsigned int &max_height) { + FluxboxWindow::ClientList::const_iterator it = clients.begin(); + FluxboxWindow::ClientList::const_iterator it_end = clients.end(); + max_width = ~0; // unlimited + max_height = ~0; // unlimited + for (; it != it_end; ++it) { + // special case for max height/width == 0 + // 0 indicates unlimited size, so we skip them + // and set max size to 0 if max size == ~0 after the loop + if ((*it)->maxHeight() != 0) + max_height = std::min( (*it)->maxHeight(), max_height ); + if ((*it)->maxWidth() != 0) + max_width = std::min( (*it)->maxWidth(), max_width ); + } + + if (max_width == ~0) + max_width = 0; + if (max_height == ~0) + max_height = 0; +} + +} + + diff --git a/src/WinClientUtil.hh b/src/WinClientUtil.hh new file mode 100644 index 0000000..8ad0a03 --- /dev/null +++ b/src/WinClientUtil.hh @@ -0,0 +1,19 @@ +#ifndef WINCLIENTUTIL_H +#define WINCLIENTUTIL_H + +#include "Window.hh" + +/// window client utilities +namespace WinClientUtil { + +/** + * Calculates the min of all maximum width/heights of all clients + * @param clients the client list + * @param width the return value of minimum of all max width of all clients + * @param height the return value of mimimum of all max heights of all clients + */ +void maxSize(const FluxboxWindow::ClientList &clients, + unsigned int &width, unsigned int &height); +} + +#endif // WINCLIENTUTIL_H diff --git a/src/Window.hh b/src/Window.hh index 9508d5c..10491ff 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -302,6 +302,7 @@ public: inline bool isMaximizable() const { return functions.maximize; } inline bool isResizable() const { return functions.resize; } inline bool isClosable() const { return functions.close; } + inline bool isMoveable() const { return functions.move; } inline bool isStuck() const { return stuck; } inline bool hasTitlebar() const { return decorations.titlebar; } inline bool isMoving() const { return moving; } -- cgit v0.11.2