all repos — openbox @ 6595476d81f01cee9001bbc90dda5b37915e5821

openbox fork - make it a bit more like ryudo

keep track of window dimentions
use them for window moving
Dana Jansens danakj@orodu.net
commit

6595476d81f01cee9001bbc90dda5b37915e5821

parent

54dfa44cbecdb31cecb035e6ef8287007617b00c

3 files changed, 146 insertions(+), 106 deletions(-)

jump to
M util/epist/screen.ccutil/epist/screen.cc

@@ -246,19 +246,27 @@ window->sendTo(0xffffffff);

return; case Action::moveWindowUp: - window->move(0, -it->number()); + window->move(window->x(), window->y() - it->number()); return; case Action::moveWindowDown: - window->move(0, it->number()); + window->move(window->x(), window->y() + it->number()); return; case Action::moveWindowLeft: - window->move(-it->number(), 0); + window->move(window->x() - it->number(), window->y()); return; case Action::moveWindowRight: - window->move(it->number(), 0); + window->move(window->x() + it->number(), window->y()); + return; + + case Action::resizeWindowWidth: + window->resize(window->width() + it->number(), window->height()); + return; + + case Action::resizeWindowHeight: + window->resize(window->width(), window->height() + it->number()); return; case Action::toggleshade:
M util/epist/window.ccutil/epist/window.cc

@@ -43,6 +43,9 @@ _unmapped = false;

XSelectInput(_epist->getXDisplay(), _window, PropertyChangeMask | StructureNotifyMask); + + updateDimentions(); + updateGravity(); updateState(); updateDesktop(); updateTitle();

@@ -59,6 +62,33 @@ _epist->removeWindow(this);

} +void XWindow::updateDimentions() { + Window root, child; + int x, y; + unsigned int w, h, b, d; + + if (XGetGeometry(_epist->getXDisplay(), _window, &root, &x, &y, &w, &h, + &b, &d) && + XTranslateCoordinates(_epist->getXDisplay(), _window, root, x, y, + &x, &y, &child)) + _rect.setRect(x, y, w, h); + else + _rect.setRect(0, 0, 1, 1); +} + + +void XWindow::updateGravity() { + XSizeHints size; + long ret; + + if (XGetWMNormalHints(_epist->getXDisplay(), _window, &size, &ret) && + (size.flags & PWinGravity)) + _gravity = size.win_gravity; + else + _gravity = NorthWestGravity; +} + + void XWindow::updateState() { // set the defaults _shaded = _iconic = _max_vert = _max_horz = false;

@@ -123,9 +153,13 @@ void XWindow::processEvent(const XEvent &e) {

assert(e.xany.window == _window); switch (e.type) { + case ConfigureNotify: + updateDimentions(); + break; case PropertyNotify: - // a client window - if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_state)) + if (e.xproperty.atom == XA_WM_NORMAL_HINTS) + updateGravity(); + else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_state)) updateState(); else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_desktop)) updateDesktop();

@@ -143,26 +177,56 @@ }

} -void XWindow::findFramePosition(int &x, int &y) const { +void XWindow::shade(const bool sh) const { + _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state, + _window, (sh ? 1 : 0), + _xatom->getAtom(XAtom::net_wm_state_shaded)); +} + + +void XWindow::close() const { + _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_close_window, + _window); +} + + +void XWindow::raise() const { + XRaiseWindow(_epist->getXDisplay(), _window); +} + + +void XWindow::lower() const { + XLowerWindow(_epist->getXDisplay(), _window); +} + + +void XWindow::iconify() const { + _xatom->sendClientMessage(_screen->rootWindow(), XAtom::wm_change_state, + _window, IconicState); +} + + +void XWindow::focus() const { + // this will also unshade the window.. + _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_active_window, + _window); +} + + +void XWindow::sendTo(unsigned int dest) const { + _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_wm_desktop, + _window, dest); +} + + +void XWindow::move(int x, int y) const { + // get the window's decoration sizes (margins) + Strut margins; Window win = _window, parent, root, last = None; Window *children = 0; unsigned int nchildren; - int gravity, top, bottom, left, right; XWindowAttributes wattr; - XSizeHints size; - long ret; - unsigned int cwidth, cheight; - // get the location, size and gravity of the client window - if (! XGetWindowAttributes(_epist->getXDisplay(), _window, &wattr)) return; - cwidth = wattr.width; - cheight = wattr.height; - if (! XGetWMNormalHints(_epist->getXDisplay(), _window, &size, &ret)) return; - if (size.flags & PWinGravity) - gravity = size.win_gravity; - else - gravity = NorthWestGravity; - while (XQueryTree(_epist->getXDisplay(), win, &root, &parent, &children, &nchildren)) { if (children && nchildren > 0)

@@ -180,114 +244,70 @@ win = parent;

} if (! (XTranslateCoordinates(_epist->getXDisplay(), last, win, 0, 0, - &left, &top, &parent) && + (int *) &margins.left, + (int *) &margins.top, + &parent) && XGetWindowAttributes(_epist->getXDisplay(), win, &wattr))) return; - right = wattr.width - cwidth - left; - bottom = wattr.height - cheight - top; - - left += wattr.border_width; - right += wattr.border_width; - top += wattr.border_width; - bottom += wattr.border_width; + margins.right = wattr.width - _rect.width() - margins.left; + margins.bottom = wattr.height - _rect.height() - margins.top; - // find the client's location - x = wattr.x + left; - y = wattr.y + top; + margins.left += wattr.border_width; + margins.right += wattr.border_width; + margins.top += wattr.border_width; + margins.bottom += wattr.border_width; // this makes things work. why? i don't know. but you need them. - right -= 2; - bottom -= 2; - + margins.right -= 2; + margins.bottom -= 2; + // find the frame's reference position based on the window's gravity - switch (gravity) { + switch (_gravity) { case NorthWestGravity: - x -= left; - y -= top; + x -= margins.left; + y -= margins.top; break; case NorthGravity: - x += (left + right) / 2; - y -= top; + x += (margins.left + margins.right) / 2; + y -= margins.top; break; case NorthEastGravity: - x += right; - y -= top; + x += margins.right; + y -= margins.top; case WestGravity: - x -= left; - y += (top + bottom) / 2; + x -= margins.left; + y += (margins.top + margins.bottom) / 2; break; case CenterGravity: - x += (left + right) / 2; - y += (top + bottom) / 2; + x += (margins.left + margins.right) / 2; + y += (margins.top + margins.bottom) / 2; break; case EastGravity: - x += right; - y += (top + bottom) / 2; + x += margins.right; + y += (margins.top + margins.bottom) / 2; case SouthWestGravity: - x -= left; - y += bottom; + x -= margins.left; + y += margins.bottom; break; case SouthGravity: - x += (left + right) / 2; - y += bottom; + x += (margins.left + margins.right) / 2; + y += margins.bottom; break; case SouthEastGravity: - x += right; - y += bottom; + x += margins.right; + y += margins.bottom; break; default: break; } -} - - -void XWindow::shade(const bool sh) const { - _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state, - _window, (sh ? 1 : 0), - _xatom->getAtom(XAtom::net_wm_state_shaded)); + + XMoveWindow(_epist->getXDisplay(), _window, x, y); } -void XWindow::close() const { - _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_close_window, - _window); -} - - -void XWindow::raise() const { - XRaiseWindow(_epist->getXDisplay(), _window); -} - - -void XWindow::lower() const { - XLowerWindow(_epist->getXDisplay(), _window); -} - - -void XWindow::iconify() const { - _xatom->sendClientMessage(_screen->rootWindow(), XAtom::wm_change_state, - _window, IconicState); -} - - -void XWindow::focus() const { - // this will also unshade the window.. - _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_active_window, - _window); -} - - -void XWindow::sendTo(unsigned int dest) const { - _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_wm_desktop, - _window, dest); -} - - -void XWindow::move(int x, int y) const { - int fx, fy; - findFramePosition(fx, fy); - XMoveWindow(_epist->getXDisplay(), _window, fx + x, fy + y); +void XWindow::resize(unsigned int width, unsigned int height) const { + XResizeWindow(_epist->getXDisplay(), _window, width, height); }
M util/epist/window.hhutil/epist/window.hh

@@ -30,12 +30,11 @@

#include <list> #include <string> +#include "../../src/Util.hh" + class epist; class screen; -class XWindow; class XAtom; - -typedef std::list<XWindow *> WindowList; class XWindow { public:

@@ -47,15 +46,18 @@ Max_Full

}; private: - epist *_epist; + epist *_epist; screen *_screen; - XAtom *_xatom; + XAtom *_xatom; + Window _window; - + unsigned int _desktop; std::string _title; std::string _app_name; std::string _app_class; + Rect _rect; + int _gravity; // states bool _shaded;

@@ -65,6 +67,8 @@ bool _max_horz;

bool _unmapped; + void updateDimentions(); + void updateGravity(); void updateState(); void updateDesktop(); void updateTitle();

@@ -87,6 +91,11 @@ inline bool shaded() const { return _shaded; }

inline bool iconic() const { return _iconic; } inline bool maxVert() const { return _max_vert; } inline bool maxHorz() const { return _max_horz; } + inline const Rect &area() const { return _rect; } + inline unsigned int x() const { return _rect.x(); } + inline unsigned int y() const { return _rect.y(); } + inline unsigned int width() const { return _rect.width(); } + inline unsigned int height() const { return _rect.height(); } void processEvent(const XEvent &e);

@@ -98,11 +107,14 @@ void iconify() const;

void focus() const; void sendTo(unsigned int dest) const; void move(int x, int y) const; + void resize(unsigned int width, unsigned int height) const; void toggleMaximize(Max max) const; // i hate toggle functions void maximize(Max max) const; bool operator == (const XWindow &w) const { return w._window == _window; } bool operator == (const Window &w) const { return w == _window; } }; + +typedef std::list<XWindow *> WindowList; #endif // __window_hh