From 0ae3ca9e8a2a3398cf07789e0d141887d40dcb6f Mon Sep 17 00:00:00 2001 From: Mark Tiefenbruck <mark@fluxbox.org> Date: Fri, 22 Aug 2008 05:52:23 -0700 Subject: move fullscreen and maximization handling to FbWinFrame --- src/FbWinFrame.cc | 72 +++++++++++++++++++++++++ src/FbWinFrame.hh | 23 +++++++- src/Remember.cc | 22 ++++---- src/Window.cc | 158 +++++++----------------------------------------------- src/Window.hh | 25 ++------- src/fluxbox.cc | 2 +- 6 files changed, 129 insertions(+), 173 deletions(-) diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index f050a6d..03f7420 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -529,8 +529,60 @@ void FbWinFrame::setFullscreen(bool newvalue) { if (newvalue == m_state.fullscreen) return; + saveGeometry(); m_state.fullscreen = newvalue; + applyState(); +} + +void FbWinFrame::setMaximized(int value) { + if (value == m_state.maximized) + return; + + saveGeometry(); + m_state.maximized = value; + applyState(); +} + +void FbWinFrame::saveGeometry() { + if (m_state.fullscreen || m_state.maximized) + return; + + m_state.x = x(); + m_state.y = y(); + m_state.width = width(); + m_state.height = height(); +} + +void FbWinFrame::applyState() { applyDecorations(); + + if (m_state.fullscreen) { + const int head = m_screen.getHead(window()); + moveResize(m_screen.getHeadX(head), m_screen.getHeadY(head), + m_screen.getHeadWidth(head), m_screen.getHeadHeight(head)); + } else if (m_state.maximized) { + const int head = m_screen.getHead(window()); + int new_x = m_state.x, new_y = m_state.y; + unsigned int new_w = m_state.width, new_h = m_state.height; + if (m_state.maximized & MAX_VERT) { + new_y = m_screen.maxTop(head); + new_h = m_screen.maxBottom(head) - new_y - 2*window().borderWidth(); + } + if (m_state.maximized & MAX_HORZ) { + new_x = m_screen.maxLeft(head); + new_w = m_screen.maxRight(head) - new_x - 2*window().borderWidth(); + } + if (!m_screen.getMaxOverTabs()) { + new_y += yOffset(); + new_h -= heightOffset(); + new_x += xOffset(); + new_w -= widthOffset(); + } + moveResize(new_x, new_y, new_w, new_h); + } else + moveResize(m_state.x, m_state.y, m_state.width, m_state.height); + + frameExtentSig().notify(); } void FbWinFrame::setAlpha(bool focused, unsigned char alpha) { @@ -1662,7 +1714,27 @@ void FbWinFrame::gravityTranslate(int &x, int &y, } } +int FbWinFrame::normalX() const { + if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen) + return m_state.x; + return x(); +} + +int FbWinFrame::normalY() const { + if ((m_state.maximized & MAX_VERT) || m_state.fullscreen) + return m_state.y; + return y(); +} + +unsigned int FbWinFrame::normalWidth() const { + if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen) + return m_state.width; + return width(); +} + unsigned int FbWinFrame::normalHeight() const { + if ((m_state.maximized & MAX_VERT) || m_state.fullscreen) + return m_state.height; if (m_state.shaded) return m_height_before_shade; return height(); diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh index 5756c8e..d2f7a1f 100644 --- a/src/FbWinFrame.hh +++ b/src/FbWinFrame.hh @@ -69,6 +69,16 @@ public: }; /** + * Types of maximization + */ + enum MaximizeMode { + MAX_NONE = 0, ///< normal state + MAX_HORZ = 1, ///< maximize horizontal + MAX_VERT = 2, ///< maximize vertical + MAX_FULL = 3 ///< maximize full + }; + + /** This enumeration represents individual decoration attributes, they can be OR-d together to get a mask. Useful for saving. @@ -126,12 +136,15 @@ public: size_hints(), deco_mask(DECOR_NORMAL), focused(false), - shaded(false), fullscreen(false), maximized(0) { } + shaded(false), fullscreen(false), maximized(0), + x(0), y(0), width(1), height(1) { } SizeHints size_hints; unsigned int deco_mask; bool focused, shaded, fullscreen; int maximized; + int x, y; + unsigned int width, height; }; /// create a top level window @@ -182,7 +195,7 @@ public: /// set focus/unfocus style void setFocus(bool newvalue); void setFullscreen(bool value); - void setMaximized(int value) { m_state.maximized = value; } + void setMaximized(int value); void setFocusTitle(const std::string &str) { m_label.setText(str); } bool setTabMode(TabMode tabmode); @@ -237,6 +250,8 @@ public: static int getDecoMaskFromString(const std::string &str); void setDecorationMask(unsigned int mask) { m_state.deco_mask = mask; } void applyDecorations(); + void applyState(); + void saveGeometry(); /// determine if the given decoration should be shown in current state bool useBorder() const; @@ -271,6 +286,10 @@ public: int y() const { return m_window.y(); } unsigned int width() const { return m_window.width(); } unsigned int height() const { return m_window.height(); } + + int normalX() const; + int normalY() const; + unsigned int normalWidth() const; unsigned int normalHeight() const; // extra bits for tabs diff --git a/src/Remember.cc b/src/Remember.cc index a1f5d62..1df5045 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -535,13 +535,13 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) { app.rememberMinimizedstate((strcasecmp(str_label.c_str(), "yes") == 0)); } else if (str_key == "maximized") { if (strcasecmp(str_label.c_str(), "yes") == 0) - app.rememberMaximizedstate(FluxboxWindow::MAX_FULL); + app.rememberMaximizedstate(FbWinFrame::MAX_FULL); else if (strcasecmp(str_label.c_str(), "horz") == 0) - app.rememberMaximizedstate(FluxboxWindow::MAX_HORZ); + app.rememberMaximizedstate(FbWinFrame::MAX_HORZ); else if (strcasecmp(str_label.c_str(), "vert") == 0) - app.rememberMaximizedstate(FluxboxWindow::MAX_VERT); + app.rememberMaximizedstate(FbWinFrame::MAX_VERT); else - app.rememberMaximizedstate(FluxboxWindow::MAX_NONE); + app.rememberMaximizedstate(FbWinFrame::MAX_NONE); } else if (str_key == "fullscreen") { app.rememberFullscreenstate((strcasecmp(str_label.c_str(), "yes") == 0)); } else if (str_key == "jump") { @@ -999,16 +999,16 @@ void Remember::save() { if (a.maximizedstate_remember) { apps_file << " [Maximized]\t{"; switch (a.maximizedstate) { - case FluxboxWindow::MAX_FULL: + case FbWinFrame::MAX_FULL: apps_file << "yes" << "}" << endl; break; - case FluxboxWindow::MAX_HORZ: + case FbWinFrame::MAX_HORZ: apps_file << "horz" << "}" << endl; break; - case FluxboxWindow::MAX_VERT: + case FbWinFrame::MAX_VERT: apps_file << "vert" << "}" << endl; break; - case FluxboxWindow::MAX_NONE: + case FbWinFrame::MAX_NONE: default: apps_file << "no" << "}" << endl; break; @@ -1115,13 +1115,15 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) { app->rememberHead(win->screen().getHead(win->fbWindow())); break; case REM_DIMENSIONS: - app->rememberDimensions(win->normalWidth(), win->normalHeight()); + app->rememberDimensions(win->frame().normalWidth(), + win->frame().normalHeight()); break; case REM_POSITION: { int head = win->screen().getHead(win->fbWindow()); int head_x = win->screen().maxLeft(head); int head_y = win->screen().maxTop(head); - app->rememberPosition(win->normalX() - head_x, win->normalY() - head_y); + app->rememberPosition(win->frame().normalX() - head_x, + win->frame().normalY() - head_y); break; } case REM_FOCUSHIDDENSTATE: diff --git a/src/Window.cc b/src/Window.cc index 79419d0..c91e875 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -271,7 +271,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer): m_creation_time(0), moving(false), resizing(false), shaded(false), iconic(false), stuck(false), m_initialized(false), fullscreen(false), - maximized(MAX_NONE), + maximized(FbWinFrame::MAX_NONE), m_attaching_tab(0), display(FbTk::App::instance()->display()), m_button_grab_x(0), m_button_grab_y(0), @@ -287,8 +287,6 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer): m_focus_new(BoolAcc(screen().focusControl(), &FocusControl::focusNew)), m_mouse_focus(BoolAcc(screen().focusControl(), &FocusControl::isMouseFocus)), m_click_focus(true), - m_old_pos_x(0), m_old_pos_y(0), - m_old_width(1), m_old_height(1), m_last_button_x(0), m_last_button_y(0), m_button_theme(*this, screen().focusedWinButtonTheme(), screen().unfocusedWinButtonTheme()), @@ -561,7 +559,7 @@ void FluxboxWindow::init() { if (maximized) { int tmp = maximized; - maximized = MAX_NONE; + maximized = FbWinFrame::MAX_NONE; setMaximizedState(tmp); } @@ -1444,35 +1442,16 @@ void FluxboxWindow::setFullscreen(bool flag) { return; } - const int head = screen().getHead(fbWindow()); - if (flag && !isFullscreen()) { if (isShaded()) shade(); m_old_layernum = layerNum(); - if (!maximized) { - m_old_pos_x = frame().x(); - m_old_pos_y = frame().y(); - m_old_width = frame().width(); - m_old_height = frame().height(); - } - fullscreen = true; frame().setFullscreen(true); - // dont call Window::moveResize here, it might ignore the - // resize if win state is not resizable; - // instead we call frame resize directly - // (see tests/fullscreentest.cc) - - // be xinerama aware - frame().moveResize(screen().getHeadX(head), screen().getHeadY(head), - screen().getHeadWidth(head), screen().getHeadHeight(head)); - sendConfigureNotify(); - - setFullscreenLayer(); + setFullscreenLayer(); // calls stateSig().notify() if (!isFocused()) screen().focusedWindowSig().attach(this); @@ -1481,21 +1460,8 @@ void FluxboxWindow::setFullscreen(bool flag) { fullscreen = false; frame().setFullscreen(false); - // ensure we apply the sizehints here, otherwise some - // apps (eg xterm) end up a little bit .. crappy (visually) - frame().applySizeHints(m_old_width, m_old_height); - - moveResize(m_old_pos_x, m_old_pos_y, m_old_width, m_old_height); moveToLayer(m_old_layernum); - - m_old_layernum = ::Layer::NORMAL; - - if (maximized) { - int tmp = maximized; - maximized = MAX_NONE; - setMaximizedState(tmp); - } else - stateSig().notify(); + stateSig().notify(); } } @@ -1507,8 +1473,7 @@ void FluxboxWindow::setFullscreenLayer() { getOnHead() != foc->getOnHead()) { moveToLayer(::Layer::ABOVE_DOCK); } else { - moveToLayer(m_old_layernum); - lower(); + moveToLayer(::Layer::DESKTOP); } stateSig().notify(); @@ -1520,7 +1485,7 @@ void FluxboxWindow::setFullscreenLayer() { void FluxboxWindow::maximize(int type) { // nothing to do - if (type == MAX_NONE) + if (type == FbWinFrame::MAX_NONE) return; int new_max = maximized; @@ -1529,19 +1494,21 @@ void FluxboxWindow::maximize(int type) { // when _don't_ we want to toggle? // - type is horizontal maximise, or // - type is full and we are not maximised horz but already vertically - if (type != MAX_HORZ && !(type == MAX_FULL && maximized == MAX_VERT)) - new_max ^= MAX_VERT; + if (type != FbWinFrame::MAX_HORZ && + (type != FbWinFrame::MAX_FULL || maximized != FbWinFrame::MAX_VERT)) + new_max ^= FbWinFrame::MAX_VERT; // maximize horizontally? - if (type != MAX_VERT && !(type == MAX_FULL && maximized == MAX_HORZ)) - new_max ^= MAX_HORZ; + if (type != FbWinFrame::MAX_VERT && + (type != FbWinFrame::MAX_FULL || maximized != FbWinFrame::MAX_HORZ)) + new_max ^= FbWinFrame::MAX_HORZ; setMaximizedState(new_max); } void FluxboxWindow::setMaximizedState(int type) { - if (!m_initialized || isFullscreen() || type == maximized) { + if (!m_initialized || type == maximized) { // this will interfere with window placement, so we delay it maximized = type; return; @@ -1553,69 +1520,8 @@ void FluxboxWindow::setMaximizedState(int type) { if (isResizing()) stopResizing(); - int head = screen().getHead(frame().window()); - int new_x = frame().x(), new_y = frame().y(); - unsigned int new_w = frame().width(), new_h = frame().height(); - - // These evaluate whether we need to TOGGLE the value for that field - // Why? If maximize is only set to zero outside this, - // and we only EVER toggle them, then: - // 1) We will never loose the old_ values - // 2) It shouldn't get confused - - // Worst case being that some action will toggle the wrong way, but - // we still won't lose the state in that case. - - // toggle maximize vertically? - if ((maximized ^ type) & MAX_VERT) { - // already maximized in that direction? - if (maximized & MAX_VERT) { - new_y = m_old_pos_y; - new_h = m_old_height; - } else { - m_old_pos_y = new_y; - m_old_height = new_h; - new_y = screen().maxTop(head); - new_h = screen().maxBottom(head) - new_y - 2*frame().window().borderWidth(); - if (!screen().getMaxOverTabs()) { - new_y += yOffset(); - new_h -= heightOffset(); - } - } - maximized ^= MAX_VERT; - } - - // toggle maximize horizontally? - if ((maximized ^ type) & MAX_HORZ) { - // already maximized in that direction? - if (maximized & MAX_HORZ) { - new_x = m_old_pos_x; - new_w = m_old_width; - } else { - // only save if we weren't already maximized - m_old_pos_x = new_x; - m_old_width = new_w; - new_x = screen().maxLeft(head); - new_w = screen().maxRight(head) - new_x - 2*frame().window().borderWidth(); - if (!screen().getMaxOverTabs()) { - new_x += xOffset(); - new_w -= widthOffset(); - } - } - maximized ^= MAX_HORZ; - } - - frame().setMaximized(maximized); - // ensure we apply the sizehints here, otherwise some - // apps (eg xterm) end up a little bit .. crappy (visually) - - // frankly, that xterm bug was pretty obscure, and it's really annoying not - // being able to maximize my terminals, so we make an option - // but we do fix size hints when restoring the window to normal size - if (!screen().getMaxIgnoreIncrement() || !maximized) - frame().applySizeHints(new_w, new_h, maximized ? true : false); - - moveResize(new_x, new_y, new_w, new_h); + maximized = type; + frame().setMaximized(type); // notify listeners that we changed state stateSig().notify(); @@ -1625,21 +1531,21 @@ void FluxboxWindow::setMaximizedState(int type) { * Maximize window horizontal */ void FluxboxWindow::maximizeHorizontal() { - maximize(MAX_HORZ); + maximize(FbWinFrame::MAX_HORZ); } /** * Maximize window vertical */ void FluxboxWindow::maximizeVertical() { - maximize(MAX_VERT); + maximize(FbWinFrame::MAX_VERT); } /** * Maximize window fully */ void FluxboxWindow::maximizeFull() { - maximize(MAX_FULL); + maximize(FbWinFrame::MAX_FULL); } void FluxboxWindow::setWorkspace(int n) { @@ -3248,7 +3154,7 @@ void FluxboxWindow::startResizing(int x, int y, ReferenceCorner dir) { m_resize_corner = dir; resizing = true; - maximized = MAX_NONE; + maximized = FbWinFrame::MAX_NONE; frame().setMaximized(maximized); const Cursor& cursor = (m_resize_corner == LEFTTOP) ? frame().theme()->upperLeftAngleCursor() : @@ -3541,32 +3447,6 @@ bool FluxboxWindow::isTransient() const { return (m_client && m_client->isTransient()); } -int FluxboxWindow::normalX() const { - if (maximized & MAX_HORZ || fullscreen) - return m_old_pos_x; - return x(); -} - -int FluxboxWindow::normalY() const { - if (maximized & MAX_VERT || fullscreen) - return m_old_pos_y; - return y(); -} - -unsigned int FluxboxWindow::normalWidth() const { - if (maximized & MAX_HORZ || fullscreen) - return m_old_width; - return width(); -} - -unsigned int FluxboxWindow::normalHeight() const { - if (maximized & MAX_VERT || fullscreen) - return m_old_height; - if (shaded) - return frame().normalHeight(); - return height(); -} - int FluxboxWindow::initialState() const { return m_client->initial_state; } void FluxboxWindow::fixsize() { diff --git a/src/Window.hh b/src/Window.hh index 5cf755e..16d5bc9 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -87,16 +87,6 @@ public: MwmDecorMaximize = (1l << 6) /// maximize }; - /** - * Types of maximization - */ - enum MaximizeMode { - MAX_NONE = 0, ///< normal state - MAX_HORZ = 1, ///< maximize horizontal - MAX_VERT = 2, ///< maximize vertical - MAX_FULL = 3 ///< maximize full - }; - /// Different resize modes when resizing a window enum ResizeModel { QUADRANTRESIZE, ///< resizes from one quadrant @@ -222,7 +212,7 @@ public: /// set fullscreen void setFullscreen(bool flag); /// toggle maximize - void maximize(int type = MAX_FULL); + void maximize(int type = FbWinFrame::MAX_FULL); /// sets the maximized state void setMaximizedState(int type); /// maximizes the window horizontal @@ -383,9 +373,9 @@ public: bool isIconic() const { return iconic; } bool isShaded() const { return shaded; } bool isFullscreen() const { return fullscreen; } - bool isMaximized() const { return maximized == MAX_FULL; } - bool isMaximizedVert() const { return (bool)(maximized & MAX_VERT); } - bool isMaximizedHorz() const { return (bool)(maximized & MAX_HORZ); } + bool isMaximized() const { return maximized == FbWinFrame::MAX_FULL; } + bool isMaximizedVert() const { return (bool)(maximized & FbWinFrame::MAX_VERT); } + bool isMaximizedHorz() const { return (bool)(maximized & FbWinFrame::MAX_HORZ); } int maximizedState() const { return maximized; } bool isIconifiable() const { return functions.iconify; } bool isMaximizable() const { return functions.maximize; } @@ -435,11 +425,6 @@ public: unsigned int width() const { return frame().width(); } unsigned int height() const { return frame().height(); } - int normalX() const; - int normalY() const; - unsigned int normalWidth() const; - unsigned int normalHeight() const; - int xOffset() const { return frame().xOffset(); } int yOffset() const { return frame().yOffset(); } int widthOffset() const { return frame().widthOffset(); } @@ -587,8 +572,6 @@ private: /// if the window is focused with EnterNotify FbTk::DefaultValue<bool, BoolAcc> m_mouse_focus; bool m_click_focus; ///< if the window is focused by clicking - int m_old_pos_x, m_old_pos_y; ///< old position so we can restore from maximized - unsigned int m_old_width, m_old_height; ///< old size so we can restore from maximized state int m_last_button_x, ///< last known x position of the mouse button m_last_button_y; ///< last known y position of the mouse button diff --git a/src/fluxbox.cc b/src/fluxbox.cc index d9deea7..5056624 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -263,7 +263,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile m_reconfig_timer.setCommand(reconfig_cmd); m_reconfig_timer.fireOnce(true); - // XSynchronize(disp, True); + XSynchronize(disp, True); s_singleton = this; m_have_shape = false; -- cgit v0.11.2