X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fscreen.cc;h=a2514276d8cdb805081849e297cf835ba9f80282;hb=4ef15148365c223b8e810611a10dc27dc5fba355;hp=4878d7b658296e8c4871dce71019792191764d92;hpb=9e05db9518c528ac0d2d44311cde267d9886b36a;p=chaz%2Fopenbox diff --git a/src/screen.cc b/src/screen.cc index 4878d7b6..a2514276 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -1,18 +1,8 @@ // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif +#include "config.h" extern "C" { -#ifdef HAVE_STDIO_H -# include -#endif // HAVE_STDIO_H - -#ifdef HAVE_STRING_H -# include -#endif // HAVE_STRING_H - #ifdef HAVE_UNISTD_H # include # include @@ -33,6 +23,8 @@ extern "C" { #include #include +#include +#include static bool running; static int anotherWMRunning(Display *display, XErrorEvent *) { @@ -113,7 +105,7 @@ Screen::Screen(int screen) _desktop = 0; - if (!python_get_long("NUMBER_OF_DESKTOPS", &_num_desktops)) + if (!python_get_long("NUMBER_OF_DESKTOPS", (long*)&_num_desktops)) _num_desktops = 1; changeNumDesktops(_num_desktops); // set the hint @@ -130,7 +122,6 @@ Screen::Screen(int screen) // 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); @@ -208,26 +199,48 @@ void Screen::manageExisting() } -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) { + if ((*it)->iconic()) continue; // these dont count in the strut + + unsigned int 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 == 0xffffffff) + for (unsigned int i = 0, e = _struts.size(); i < e; ++i) + apply(_struts[i], s); + else if (desk < _struts.size()) + apply(_struts[desk], s); + 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 (unsigned int i = 0; i < _num_desktops + 1; ++i) { + otk::Rect old_area = _area[i]; /* #ifdef XINERAMA // reset to the full areas @@ -236,10 +249,12 @@ void Screen::calcArea() #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()) { @@ -262,15 +277,31 @@ void Screen::calcArea() } #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() == 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; } @@ -419,20 +450,6 @@ void Screen::changeStackingList() } -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; @@ -520,11 +537,7 @@ void Screen::manageWindow(Window window) EventData ddata(_number, client, EventAction::DisplayingWindow, 0); openbox->bindings()->fireEvent(&ddata); - // if on the current desktop.. (or all desktops) - if (client->desktop() == _desktop || - client->desktop() == (signed)0xffffffff) { - client->frame->show(); - } + client->showhide(); client->applyStartupState(); @@ -534,7 +547,7 @@ void Screen::manageWindow(Window window) 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); @@ -600,10 +613,10 @@ void Screen::unmanageWindow(Client *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->setModal(false); + client->_modal = false; // unfocus the client (calls the focus callbacks) client->unfocus(); @@ -660,6 +673,10 @@ void Screen::raiseWindow(Client *client) assert(!_stacking.empty()); // this would be bad + Client *m = client->findModalChild(); + // if we have a modal child, raise it instead, we'll go along tho later + if (m) raiseWindow(m); + // remove the client before looking so we can't run into ourselves _stacking.remove(client); @@ -667,7 +684,10 @@ void Screen::raiseWindow(Client *client) const ClientList::iterator end = _stacking.end(); // the stacking list is from highest to lowest - for (; it != end && (*it)->layer() > client->layer(); ++it); +// for (;it != end, ++it) { +// if ((*it)->layer() <= client->layer() && m != *it) break; +// } + for (; it != end && ((*it)->layer() > client->layer() || m == *it); ++it); /* if our new position is the top, we want to stack under the _focuswindow @@ -681,20 +701,16 @@ void Screen::raiseWindow(Client *client) XRestackWindows(**otk::display, wins, 2); - // if the window has a modal child, then raise it after us to put it on top - if (client->modalChild()) - raiseWindow(client->modalChild()); - else - changeStackingList(); // no need to do this twice! + changeStackingList(); } -void Screen::changeDesktop(long desktop) +void Screen::changeDesktop(unsigned int desktop) { - if (!(desktop >= 0 && desktop < _num_desktops)) return; + if (desktop >= _num_desktops) return; - printf("Moving to desktop %ld\n", desktop); + printf("Moving to desktop %u\n", desktop); - long old = _desktop; + unsigned int old = _desktop; _desktop = desktop; otk::Property::set(_info->rootWindow(), @@ -704,20 +720,15 @@ void Screen::changeDesktop(long desktop) if (old == _desktop) return; ClientList::iterator it, end = clients.end(); - for (it = clients.begin(); it != end; ++it) { - if ((*it)->desktop() == old) { - (*it)->frame->hide(); - } else if ((*it)->desktop() == _desktop) { - (*it)->frame->show(); - } - } + for (it = clients.begin(); it != end; ++it) + (*it)->showhide(); // force the callbacks to fire if (!openbox->focusedClient()) openbox->setFocusedClient(0); } -void Screen::changeNumDesktops(long num) +void Screen::changeNumDesktops(unsigned int num) { assert(num > 0); @@ -726,9 +737,8 @@ void Screen::changeNumDesktops(long num) // move windows on desktops that will no longer exist! ClientList::iterator it, end = clients.end(); for (it = clients.begin(); it != end; ++it) { - int d = (*it)->desktop(); - if (d >= num && !(d == (signed) 0xffffffff || - d == Client::ICONIC_DESKTOP)) { + unsigned int d = (*it)->desktop(); + if (d >= num && d != 0xffffffff) { XEvent ce; ce.xclient.type = ClientMessage; ce.xclient.message_type = otk::Property::atoms.net_wm_desktop; @@ -755,12 +765,14 @@ void Screen::changeNumDesktops(long num) 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); } @@ -772,15 +784,13 @@ void Screen::updateDesktopNames() otk::Property::atoms.net_desktop_names, otk::Property::utf8, &num, &_desktop_names)) _desktop_names.clear(); - while ((long)_desktop_names.size() < _num_desktops) + while (_desktop_names.size() < _num_desktops) _desktop_names.push_back("Unnamed"); } -void Screen::setDesktopName(long i, const otk::ustring &name) +void Screen::setDesktopName(unsigned int i, const otk::ustring &name) { - assert(i >= 0); - if (i >= _num_desktops) return; otk::Property::StringVect newnames = _desktop_names; @@ -791,6 +801,14 @@ void Screen::setDesktopName(long i, const otk::ustring &name) } +const otk::Rect& Screen::area(unsigned int desktop) const { + assert(desktop < _num_desktops || desktop == 0xffffffff); + if (desktop < _num_desktops) + return _area[desktop]; + else + return _area[_num_desktops]; +} + void Screen::installColormap(bool install) const { if (install)