all repos — openbox @ 12108e16e166034cd1840627502280d9a1ab0b9e

openbox fork - make it a bit more like ryudo

keep track of struts for each desktop
Dana Jansens danakj@orodu.net
commit

12108e16e166034cd1840627502280d9a1ab0b9e

parent

a5ea4b0480c9daeb860bf3adbfc755c84d2e082d

M scripts/motion.pyscripts/motion.py

@@ -106,7 +106,7 @@ fs = _client.frame.size()

w = _client.area().width() + fs.left + fs.right h = _client.area().height() + fs.top + fs.bottom # use the area based on the struts - area = ob.openbox.screen(_screen).area() + area = ob.openbox.screen(_screen).area(_client.desktop()) l = area.left() r = area.right() - w + 1 t = area.top()
M scripts/windowplacement.pyscripts/windowplacement.py

@@ -25,7 +25,7 @@ if not data.client: return

if data.client.positionRequested(): return client_area = data.client.area() frame_size = data.client.frame.size() - screen_area = ob.openbox.screen(data.screen).area() + screen_area = ob.openbox.screen(data.screen).area(data.client.desktop()) width = screen_area.width() - (client_area.width() + frame_size.left + frame_size.right) height = screen_area.height() - (client_area.height() +

@@ -44,7 +44,7 @@ if not data.client: return

if data.client.positionRequested(): return client_area = data.client.area() frame_size = data.client.frame.size() - screen_area = ob.openbox.screen(data.screen).area() + screen_area = ob.openbox.screen(data.screen).area(data.client.desktop()) width = screen_area.width() - (client_area.width() + frame_size.left + frame_size.right) height = screen_area.height() - (client_area.height() +
M src/actions.ccsrc/actions.cc

@@ -42,6 +42,7 @@ for (int i = BUTTONS-1; i > 0; --i) {

_posqueue[i] = _posqueue[i-1]; } _posqueue[0] = a; + a->win = e.window; a->button = e.button; a->pos = otk::Point(e.x_root, e.y_root);

@@ -274,6 +275,8 @@ otk::EventHandler::motionHandler(e);

if (!e.same_screen) return; // this just gets stupid + if (e.window != _posqueue[0]->win) return; + MouseContext::MC context; EventHandler *h = openbox->findHandler(e.window); Frame *f = dynamic_cast<Frame*>(h);

@@ -287,7 +290,7 @@ else

return; // not a valid mouse context int x_root = e.x_root, y_root = e.y_root; - + // compress changes to a window into a single change XEvent ce; while (XCheckTypedWindowEvent(**otk::display, e.window, e.type, &ce)) {
M src/actions.hhsrc/actions.hh

@@ -35,6 +35,7 @@ ButtonReleaseAction() { win = 0; button = 0; time = 0; }

}; struct ButtonPressAction { + Window win; unsigned int button; otk::Point pos; otk::Rect clientarea;
M src/client.ccsrc/client.cc

@@ -45,7 +45,7 @@ _urgent = false;

_positioned = false; _disabled_decorations = 0; _group = None; - _desktop = 0; + _desktop = _old_desktop = 0; getArea(); getDesktop();

@@ -638,7 +638,7 @@

// updating here is pointless while we're being mapped cuz we're not in // the screen's client list yet if (frame) - openbox->screen(_screen)->updateStrut(); + openbox->screen(_screen)->updateStruts(); } delete [] data;

@@ -748,7 +748,8 @@

if (!(target >= 0 || target == (signed)0xffffffff || target == ICONIC_DESKTOP)) return; - + + _old_desktop = _desktop; _desktop = target; // set the desktop hint, but not if we're iconifying

@@ -781,8 +782,10 @@ XMapWindow(**otk::display, _window);

} changeState(); } - + + changeAllowedActions(); frame->adjustState(); + openbox->screen(_screen)->updateStruts(); }

@@ -1301,6 +1304,7 @@

void Client::remaximize() { + printf("REMAXIMIZE!!!!!!!!!!!!!!!!!!!\n"); int dir; if (_max_horz && _max_vert) dir = 0;

@@ -1391,7 +1395,8 @@ if (dir == 1 && !_max_horz) return;

if (dir == 2 && !_max_vert) return; } - const otk::Rect &a = openbox->screen(_screen)->area(); + const otk::Rect &a = openbox->screen(_screen)->area(_iconic ? + _old_desktop : _desktop); int x = frame->area().x(), y = frame->area().y(), w = _area.width(), h = _area.height();

@@ -1536,7 +1541,9 @@ }

delete dimensions; } else { // pick some fallbacks... - const otk::Rect &a = openbox->screen(_screen)->area(); + const otk::Rect &a = openbox->screen(_screen)->area(_iconic ? + _old_desktop : + _desktop); x = a.x() + a.width() / 4; y = a.y() + a.height() / 4; w = a.width() / 2;
M src/client.hhsrc/client.hh

@@ -190,6 +190,10 @@

//! The desktop on which the window resides (0xffffffff for all desktops) long _desktop; + //! The last desktop to which the window belonged, mostly useful when the + //! window is iconified, to see where it used to be. + long _old_desktop; + //! Normal window title otk::ustring _title; //! Window title when iconifiged
M src/screen.ccsrc/screen.cc

@@ -122,7 +122,6 @@

// these may be further updated if any pre-existing windows are found in // the manageExising() function changeClientList(); // initialize the client lists, which will be empty - calcArea(); // initialize the available working area // register this class as the event handler for the root window openbox->registerHandler(_info->rootWindow(), this);

@@ -200,26 +199,48 @@ XFree(children);

} -void Screen::updateStrut() +void Screen::updateStruts() { - _strut.left = _strut.right = _strut.top = _strut.bottom = 0; + struct ApplyStrut { + void operator()(otk::Strut &self, const otk::Strut &other) { + self.left = std::max(self.left, other.left); + self.right = std::max(self.right, other.right); + self.top = std::max(self.top, other.top); + self.bottom = std::max(self.bottom, other.bottom); + } + } apply; - ClientList::iterator it, end = clients.end(); + StrutList::iterator sit, send = _struts.end(); + // reset them all + for (sit = _struts.begin(); sit != send; ++sit) + sit->left = sit->right = sit->top = sit->bottom = 0; + + ClientList::const_iterator it, end = clients.end(); for (it = clients.begin(); it != end; ++it) { + long desk = (*it)->desktop(); const otk::Strut &s = (*it)->strut(); - _strut.left = std::max(_strut.left, s.left); - _strut.right = std::max(_strut.right, s.right); - _strut.top = std::max(_strut.top, s.top); - _strut.bottom = std::max(_strut.bottom, s.bottom); + + if (desk == (signed) 0xffffffff) + for (unsigned int i = 0, e = _struts.size(); i < e; ++i) + apply(_struts[i], s); + else if ((unsigned)desk < _struts.size()) + apply(_struts[desk], s); + else if (desk == Client::ICONIC_DESKTOP) + continue; // skip for the 'all desktops' strut + else + assert(false); // invalid desktop otherwise.. + // apply to the 'all desktops' strut + apply(_struts.back(), s); } - calcArea(); + changeWorkArea(); } -void Screen::calcArea() +void Screen::changeWorkArea() { - otk::Rect old_area = _area; - + unsigned long *dims = new unsigned long[4 * _num_desktops]; + for (long i = 0; i < _num_desktops + 1; ++i) { + otk::Rect old_area = _area[i]; /* #ifdef XINERAMA // reset to the full areas

@@ -228,10 +249,12 @@ xineramaUsableArea = getXineramaAreas();

#endif // XINERAMA */ - _area = otk::Rect(_strut.left, _strut.top, - _info->size().width() - (_strut.left + _strut.right), - _info->size().height() - (_strut.top + _strut.bottom)); - + _area[i] = otk::Rect(_struts[i].left, _struts[i].top, + _info->size().width() - (_struts[i].left + + _struts[i].right), + _info->size().height() - (_struts[i].top + + _struts[i].bottom)); + /* #ifdef XINERAMA if (isXineramaActive()) {

@@ -254,15 +277,31 @@ }

} #endif // XINERAMA */ - - if (old_area != _area) { - // the area has changed, adjust all the maximized windows - ClientList::iterator it, end = clients.end(); - for (it = clients.begin(); it != end; ++it) - (*it)->remaximize(); - } + if (old_area != _area[i]) { + // the area has changed, adjust all the maximized windows + ClientList::iterator it, end = clients.end(); + for (it = clients.begin(); it != end; ++it) + if (i < _num_desktops) { + if ((*it)->desktop() == i) + (*it)->remaximize(); + } else { + // the 'all desktops' size + if ((*it)->desktop() == (signed) 0xffffffff) + (*it)->remaximize(); + } + } - changeWorkArea(); + // don't set these for the 'all desktops' area + if (i < _num_desktops) { + dims[(i * 4) + 0] = _area[i].x(); + dims[(i * 4) + 1] = _area[i].y(); + dims[(i * 4) + 2] = _area[i].width(); + dims[(i * 4) + 3] = _area[i].height(); + } + } + otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_workarea, + otk::Property::atoms.cardinal, dims, 4 * _num_desktops); + delete [] dims; }

@@ -411,20 +450,6 @@ delete [] windows;

} -void Screen::changeWorkArea() { - unsigned long *dims = new unsigned long[4 * _num_desktops]; - for (long i = 0; i < _num_desktops; ++i) { - dims[(i * 4) + 0] = _area.x(); - dims[(i * 4) + 1] = _area.y(); - dims[(i * 4) + 2] = _area.width(); - dims[(i * 4) + 3] = _area.height(); - } - otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_workarea, - otk::Property::atoms.cardinal, dims, 4 * _num_desktops); - delete [] dims; -} - - void Screen::manageWindow(Window window) { Client *client = 0;

@@ -526,7 +551,7 @@ // add to the screen's list

clients.push_back(client); // once the client is in the list, update our strut to include the new // client's (it is good that this happens after window placement!) - updateStrut(); + updateStruts(); // this puts into the stacking order, then raises it _stacking.push_back(client); raiseWindow(client);

@@ -592,7 +617,7 @@ clients.remove(client);

// once the client is out of the list, update our strut to remove it's // influence - updateStrut(); + updateStruts(); // unset modal before dropping our focus client->_modal = false;

@@ -750,12 +775,14 @@ otk::Property::atoms.cardinal,

viewport, _num_desktops * 2); delete [] viewport; - // update the work area hint - changeWorkArea(); + // change our struts/area to match + _area.resize(_num_desktops + 1); + _struts.resize(_num_desktops + 1); + updateStruts(); // change our desktop if we're on one that no longer exists! - if (_desktop >= num) - changeDesktop(num - 1); + if (_desktop >= _num_desktops) + changeDesktop(_num_desktops - 1); }

@@ -785,6 +812,15 @@ otk::Property::atoms.net_desktop_names,

otk::Property::utf8, newnames); } + +const otk::Rect& Screen::area(long desktop) const { + assert(desktop >= 0 || desktop == (signed) 0xffffffff); + assert(desktop < _num_desktops || desktop == (signed) 0xffffffff); + if (desktop >= 0 && desktop < _num_desktops) + return _area[desktop]; + else + return _area[_num_desktops]; +} void Screen::installColormap(bool install) const {
M src/screen.hhsrc/screen.hh

@@ -30,7 +30,9 @@ */

class Screen : public otk::EventHandler { public: //! Holds a list of otk::Strut objects - typedef std::list<otk::Strut*> StrutList; + typedef std::vector<otk::Strut> StrutList; + //! Holds a list of otk::Rect objects + typedef std::vector<otk::Rect> RectList; static const unsigned long event_mask = ColormapChangeMask | EnterWindowMask |

@@ -59,11 +61,13 @@

//! Is the root colormap currently installed? bool _root_cmap_installed; - //! Area usable for placement etc (total - struts) - otk::Rect _area; + //! Area usable for placement etc (total - struts), one per desktop, + //! plus one extra for windows on all desktops + RectList _area; - //! Combined strut from all of the clients' struts - otk::Strut _strut; + //! Combined strut from all of the clients' struts, one per desktop, + //! plus one extra for windows on all desktops + StrutList _struts; //! An offscreen window which gets focus when nothing else has it Window _focuswindow;

@@ -139,8 +143,6 @@ If this is false, then the screen should be deleted and should NOT be

used. */ inline bool managed() const { return _managed; } - //! Returns the area of the screen not reserved by applications' Struts - inline const otk::Rect &area() const { return _area; } //! An offscreen window which gets focus when nothing else has it inline Window focuswindow() const { return _focuswindow; } //! Returns the desktop being displayed

@@ -148,11 +150,19 @@ inline long desktop() const { return _desktop; }

//! Returns the number of desktops inline long numDesktops() const { return _num_desktops; } + //! Returns the area of the screen not reserved by applications' Struts + /*! + @param desktop The desktop number of the area to retrieve for. A value of + 0xffffffff will return an area that combines all struts + on all desktops. + */ + const otk::Rect& area(long desktop) const; + //! Update's the screen's combined strut of all the clients. /*! Clients should call this whenever they change their strut. */ - void updateStrut(); + void updateStruts(); //! Manage any pre-existing windows on the screen void manageExisting();