From a4c41f621b97084516299a322d62750f2e86b6a9 Mon Sep 17 00:00:00 2001 From: rathnor Date: Tue, 23 Sep 2003 13:52:05 +0000 Subject: add support for _NET_WM_STATE_FULLSCREEN --- ChangeLog | 4 +++ src/Ewmh.cc | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/Ewmh.hh | 30 +++++++++++++++---- src/Window.cc | 12 +++++--- src/Window.hh | 6 ++-- 5 files changed, 125 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07a1131..035fbae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ (Format: Year/Month/Day) Changes for 0.9.6: +*03/09/23: + * Add support for _NET_WM_STATE_FULLSCREEN (Simon) + - fixes mozilla/firebird fullscreen + Ewmh.hh/cc Window.hh/cc *03/09/22: * Fix invisible minimize button for non-pixmap themes (Simon) WinButton.cc diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 6b38e86..5924203 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Ewmh.cc,v 1.32 2003/08/27 21:06:04 fluxgen Exp $ +// $Id: Ewmh.cc,v 1.33 2003/09/23 13:52:05 rathnor Exp $ #include "Ewmh.hh" @@ -76,9 +76,10 @@ void Ewmh::initForScreen(BScreen &screen) { m_net_wm_state_shaded, m_net_wm_state_maximized_horz, m_net_wm_state_maximized_vert, - + m_net_wm_state_fullscreen, + m_net_wm_desktop, - + // root properties m_net_client_list, m_net_number_of_desktops, @@ -132,6 +133,10 @@ void Ewmh::setupFrame(FluxboxWindow &win) { } +void Ewmh::updateFrameClose(FluxboxWindow &win) { + clearState(win); +} + void Ewmh::updateClientList(BScreen &screen) { size_t num=0; @@ -411,6 +416,7 @@ void Ewmh::createAtoms() { m_net_wm_state_shaded = XInternAtom(disp, "_NET_WM_STATE_SHADED", False); m_net_wm_state_maximized_horz = XInternAtom(disp, "_NET_WM_STATE_MAXIMIZED_HORZ", False); m_net_wm_state_maximized_vert = XInternAtom(disp, "_NET_WM_STATE_MAXIMIZED_VERT", False); + m_net_wm_state_fullscreen = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); m_net_wm_strut = XInternAtom(disp, "_NET_WM_STRUT", False); m_net_wm_icon_geometry = XInternAtom(disp, "_NET_WM_ICON_GEOMETRY", False); @@ -421,8 +427,44 @@ void Ewmh::createAtoms() { m_net_wm_ping = XInternAtom(disp, "_NET_WM_PING", False); } + +void Ewmh::setFullscreen(FluxboxWindow &win, bool value) { + // fullscreen implies maximised, above dock layer, + // and no decorations (or decorations offscreen) + WindowState *saved_state = getState(win); + if (value) { + // fullscreen on + if (!saved_state) { // not already fullscreen + saved_state = new WindowState(win.x(), win.y(), win.width(), + win.height(), win.layerNum(), win.decorationMask()); + saveState(win, saved_state); + + // actually make it fullscreen + + // clear decorations + win.setDecorationMask(0); + + // be xinerama aware + BScreen &screen = win.screen(); + int head = screen.getHead(win.fbWindow()); + win.moveResize(screen.getHeadX(head), screen.getHeadY(head), + screen.getHeadWidth(head), screen.getHeadHeight(head)); + win.moveToLayer(Fluxbox::instance()->getAboveDockLayer()); + } + } else { // turn off fullscreen + if (saved_state) { // no saved state, can't restore it + win.setDecorationMask(saved_state->decor); + win.moveResize(saved_state->x, saved_state->y, + saved_state->width, saved_state->height); + win.moveToLayer(saved_state->layer); + clearState(win); + saved_state = 0; + } + } +} + // set window state -void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) const { +void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) { if (state == m_net_wm_state_sticky) { // STICKY if (value && !win.isStuck() || @@ -440,13 +482,13 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) const { if ((value && !win.isMaximized()) || (!value && win.isMaximized())) win.maximizeVertical(); + } else if (state == m_net_wm_state_fullscreen) { // fullscreen + setFullscreen(win, value); } - - } // toggle window state -void Ewmh::toggleState(FluxboxWindow &win, Atom state) const { +void Ewmh::toggleState(FluxboxWindow &win, Atom state) { if (state == m_net_wm_state_sticky) { win.stick(); } else if (state == m_net_wm_state_shaded){ @@ -455,8 +497,9 @@ void Ewmh::toggleState(FluxboxWindow &win, Atom state) const { win.maximizeHorizontal(); } else if (state == m_net_wm_state_maximized_vert) { // maximized Vertical win.maximizeVertical(); + } else if (state == m_net_wm_state_fullscreen) { // fullscreen + setFullscreen(win, getState(win) == 0); // toggle current state } - } @@ -477,3 +520,38 @@ void Ewmh::updateStrut(WinClient &winclient) { winclient.screen().updateAvailableWorkspaceArea(); } } + +Ewmh::WindowState::WindowState(int t_x, int t_y, + unsigned int t_width, + unsigned int t_height, + int t_layer, unsigned int t_decor) : + x(t_x), y(t_y), + layer(t_layer), + width(t_width), + height(t_height), + decor(t_decor) +{} + +Ewmh::WindowState *Ewmh::getState(FluxboxWindow &win) { + SavedState::iterator it = m_savedstate.find(&win); + if (it == m_savedstate.end()) + return 0; + else + return it->second; +} + +void Ewmh::clearState(FluxboxWindow &win) { + WindowState *state = 0; + SavedState::iterator it = m_savedstate.find(&win); + if (it == m_savedstate.end()) + return; + + state = it->second; + + m_savedstate.erase(it); + delete state; +} + +void Ewmh::saveState(FluxboxWindow &win, WindowState *state) { + m_savedstate[&win] = state; +} diff --git a/src/Ewmh.hh b/src/Ewmh.hh index 08de6cf..c4419ba 100644 --- a/src/Ewmh.hh +++ b/src/Ewmh.hh @@ -19,12 +19,13 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Ewmh.hh,v 1.11 2003/08/27 21:06:04 fluxgen Exp $ +// $Id: Ewmh.hh,v 1.12 2003/09/23 13:52:05 rathnor Exp $ #include "AtomHandler.hh" #include #include +#include class Ewmh:public AtomHandler { public: @@ -50,16 +51,25 @@ public: BScreen * screen, WinClient * const winclient); bool propertyNotify(WinClient &winclient, Atom the_property); - //ignore these ones - void updateFrameClose(FluxboxWindow &win) {} + void updateFrameClose(FluxboxWindow &win); + + //ignore this one void updateClientClose(WinClient &winclient) {} + void setFullscreen(FluxboxWindow &win, bool value); + private: + typedef struct WindowState { + WindowState(int x, int y, unsigned int width, unsigned int height, int layer, unsigned int decor); + int x, y, layer; + unsigned int width, height, decor; + } WindowState; + enum { STATE_REMOVE = 0, STATE_ADD = 1, STATE_TOGGLE = 2}; - - void setState(FluxboxWindow &win, Atom state, bool value) const; - void toggleState(FluxboxWindow &win, Atom state) const; + + void setState(FluxboxWindow &win, Atom state, bool value); + void toggleState(FluxboxWindow &win, Atom state); void createAtoms(); void updateStrut(WinClient &winclient); @@ -76,6 +86,7 @@ private: Atom m_net_properties, m_net_wm_name, m_net_wm_desktop, m_net_wm_window_type, m_net_wm_state, m_net_wm_state_sticky, m_net_wm_state_shaded, m_net_wm_state_maximized_horz, m_net_wm_state_maximized_vert, + m_net_wm_state_fullscreen, m_net_wm_strut, m_net_wm_icon_geometry, m_net_wm_icon, m_net_wm_pid, m_net_wm_handled_icons; @@ -83,4 +94,11 @@ private: Atom m_net_wm_ping; std::vector m_windows; + typedef std::map SavedState; + SavedState m_savedstate; + + WindowState *getState(FluxboxWindow &win); + void clearState(FluxboxWindow &win); + void saveState(FluxboxWindow &win, WindowState *state); + }; diff --git a/src/Window.cc b/src/Window.cc index 38fe3f5..7c331c1 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.231 2003/09/16 13:11:42 rathnor Exp $ +// $Id: Window.cc,v 1.232 2003/09/23 13:52:05 rathnor Exp $ #include "Window.hh" @@ -1084,8 +1084,8 @@ void FluxboxWindow::getBlackboxHints() { } } -void FluxboxWindow::move(int x, int y) { - moveResize(x, y, frame().width(), frame().height()); +void FluxboxWindow::move(int x, int y, int gravity) { + moveResize(x, y, frame().width(), frame().height(), gravity); } void FluxboxWindow::resize(unsigned int width, unsigned int height) { @@ -1093,7 +1093,11 @@ void FluxboxWindow::resize(unsigned int width, unsigned int height) { } void FluxboxWindow::moveResize(int new_x, int new_y, - unsigned int new_width, unsigned int new_height) { + unsigned int new_width, unsigned int new_height, int gravity) { + + if (gravity != ForgetGravity) { + frame().gravityTranslate(new_x, new_y, gravity, false); + } bool send_event = (frame().x() != new_x || frame().y() != new_y); diff --git a/src/Window.hh b/src/Window.hh index ee0b35e..a07bf66 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.hh,v 1.93 2003/09/12 16:30:21 fluxgen Exp $ +// $Id: Window.hh,v 1.94 2003/09/23 13:52:05 rathnor Exp $ #ifndef WINDOW_HH #define WINDOW_HH @@ -206,11 +206,11 @@ public: void restore(WinClient *client, bool remap); void restore(bool remap); /// move frame to x, y - void move(int x, int y); + void move(int x, int y, int gravity = ForgetGravity); /// resize frame to width, height void resize(unsigned int width, unsigned int height); /// move and resize frame to pox x,y and size width, height - void moveResize(int x, int y, unsigned int width, unsigned int height); + void moveResize(int x, int y, unsigned int width, unsigned int height, int gravity = ForgetGravity); void setWorkspace(int n); void changeBlackboxHints(const BlackboxHints &bh); -- cgit v0.11.2