keep track of struts for each desktop

This commit is contained in:
Dana Jansens 2003-02-10 06:50:19 +00:00
parent a5ea4b0480
commit 12108e16e1
8 changed files with 123 additions and 62 deletions

View file

@ -106,7 +106,7 @@ def _do_move():
w = _client.area().width() + fs.left + fs.right w = _client.area().width() + fs.left + fs.right
h = _client.area().height() + fs.top + fs.bottom h = _client.area().height() + fs.top + fs.bottom
# use the area based on the struts # use the area based on the struts
area = ob.openbox.screen(_screen).area() area = ob.openbox.screen(_screen).area(_client.desktop())
l = area.left() l = area.left()
r = area.right() - w + 1 r = area.right() - w + 1
t = area.top() t = area.top()

View file

@ -25,7 +25,7 @@ def random(data):
if data.client.positionRequested(): return if data.client.positionRequested(): return
client_area = data.client.area() client_area = data.client.area()
frame_size = data.client.frame.size() 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() + width = screen_area.width() - (client_area.width() +
frame_size.left + frame_size.right) frame_size.left + frame_size.right)
height = screen_area.height() - (client_area.height() + height = screen_area.height() - (client_area.height() +
@ -44,7 +44,7 @@ def cascade(data):
if data.client.positionRequested(): return if data.client.positionRequested(): return
client_area = data.client.area() client_area = data.client.area()
frame_size = data.client.frame.size() 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() + width = screen_area.width() - (client_area.width() +
frame_size.left + frame_size.right) frame_size.left + frame_size.right)
height = screen_area.height() - (client_area.height() + height = screen_area.height() - (client_area.height() +

View file

@ -42,6 +42,7 @@ void Actions::insertPress(const XButtonEvent &e)
_posqueue[i] = _posqueue[i-1]; _posqueue[i] = _posqueue[i-1];
} }
_posqueue[0] = a; _posqueue[0] = a;
a->win = e.window;
a->button = e.button; a->button = e.button;
a->pos = otk::Point(e.x_root, e.y_root); a->pos = otk::Point(e.x_root, e.y_root);
@ -274,6 +275,8 @@ void Actions::motionHandler(const XMotionEvent &e)
if (!e.same_screen) return; // this just gets stupid if (!e.same_screen) return; // this just gets stupid
if (e.window != _posqueue[0]->win) return;
MouseContext::MC context; MouseContext::MC context;
EventHandler *h = openbox->findHandler(e.window); EventHandler *h = openbox->findHandler(e.window);
Frame *f = dynamic_cast<Frame*>(h); Frame *f = dynamic_cast<Frame*>(h);

View file

@ -35,6 +35,7 @@ public:
}; };
struct ButtonPressAction { struct ButtonPressAction {
Window win;
unsigned int button; unsigned int button;
otk::Point pos; otk::Point pos;
otk::Rect clientarea; otk::Rect clientarea;

View file

@ -45,7 +45,7 @@ Client::Client(int screen, Window window)
_positioned = false; _positioned = false;
_disabled_decorations = 0; _disabled_decorations = 0;
_group = None; _group = None;
_desktop = 0; _desktop = _old_desktop = 0;
getArea(); getArea();
getDesktop(); getDesktop();
@ -638,7 +638,7 @@ void Client::updateStrut()
// updating here is pointless while we're being mapped cuz we're not in // updating here is pointless while we're being mapped cuz we're not in
// the screen's client list yet // the screen's client list yet
if (frame) if (frame)
openbox->screen(_screen)->updateStrut(); openbox->screen(_screen)->updateStruts();
} }
delete [] data; delete [] data;
@ -749,6 +749,7 @@ void Client::setDesktop(long target)
target == ICONIC_DESKTOP)) target == ICONIC_DESKTOP))
return; return;
_old_desktop = _desktop;
_desktop = target; _desktop = target;
// set the desktop hint, but not if we're iconifying // set the desktop hint, but not if we're iconifying
@ -782,7 +783,9 @@ void Client::setDesktop(long target)
changeState(); changeState();
} }
changeAllowedActions();
frame->adjustState(); frame->adjustState();
openbox->screen(_screen)->updateStruts();
} }
@ -1301,6 +1304,7 @@ void Client::changeAllowedActions(void)
void Client::remaximize() void Client::remaximize()
{ {
printf("REMAXIMIZE!!!!!!!!!!!!!!!!!!!\n");
int dir; int dir;
if (_max_horz && _max_vert) if (_max_horz && _max_vert)
dir = 0; dir = 0;
@ -1391,7 +1395,8 @@ void Client::maximize(bool max, int dir, bool savearea)
if (dir == 2 && !_max_vert) 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(), int x = frame->area().x(), y = frame->area().y(),
w = _area.width(), h = _area.height(); w = _area.width(), h = _area.height();
@ -1536,7 +1541,9 @@ void Client::fullscreen(bool fs, bool savearea)
delete dimensions; delete dimensions;
} else { } else {
// pick some fallbacks... // 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; x = a.x() + a.width() / 4;
y = a.y() + a.height() / 4; y = a.y() + a.height() / 4;
w = a.width() / 2; w = a.width() / 2;

View file

@ -190,6 +190,10 @@ private:
//! The desktop on which the window resides (0xffffffff for all desktops) //! The desktop on which the window resides (0xffffffff for all desktops)
long _desktop; 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 //! Normal window title
otk::ustring _title; otk::ustring _title;
//! Window title when iconifiged //! Window title when iconifiged

View file

@ -122,7 +122,6 @@ Screen::Screen(int screen)
// these may be further updated if any pre-existing windows are found in // these may be further updated if any pre-existing windows are found in
// the manageExising() function // the manageExising() function
changeClientList(); // initialize the client lists, which will be empty 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 // register this class as the event handler for the root window
openbox->registerHandler(_info->rootWindow(), this); openbox->registerHandler(_info->rootWindow(), this);
@ -200,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) {
ClientList::iterator it, end = clients.end(); self.left = std::max(self.left, other.left);
for (it = clients.begin(); it != end; ++it) { self.right = std::max(self.right, other.right);
const otk::Strut &s = (*it)->strut(); self.top = std::max(self.top, other.top);
_strut.left = std::max(_strut.left, s.left); self.bottom = std::max(self.bottom, other.bottom);
_strut.right = std::max(_strut.right, s.right);
_strut.top = std::max(_strut.top, s.top);
_strut.bottom = std::max(_strut.bottom, s.bottom);
} }
calcArea(); } apply;
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();
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);
}
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 #ifdef XINERAMA
// reset to the full areas // reset to the full areas
@ -228,9 +249,11 @@ void Screen::calcArea()
#endif // XINERAMA #endif // XINERAMA
*/ */
_area = otk::Rect(_strut.left, _strut.top, _area[i] = otk::Rect(_struts[i].left, _struts[i].top,
_info->size().width() - (_strut.left + _strut.right), _info->size().width() - (_struts[i].left +
_info->size().height() - (_strut.top + _strut.bottom)); _struts[i].right),
_info->size().height() - (_struts[i].top +
_struts[i].bottom));
/* /*
#ifdef XINERAMA #ifdef XINERAMA
@ -254,15 +277,31 @@ void Screen::calcArea()
} }
#endif // XINERAMA #endif // XINERAMA
*/ */
if (old_area != _area[i]) {
if (old_area != _area) {
// the area has changed, adjust all the maximized windows // the area has changed, adjust all the maximized windows
ClientList::iterator it, end = clients.end(); ClientList::iterator it, end = clients.end();
for (it = clients.begin(); it != end; ++it) 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(); (*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 @@ 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) void Screen::manageWindow(Window window)
{ {
Client *client = 0; Client *client = 0;
@ -526,7 +551,7 @@ void Screen::manageWindow(Window window)
clients.push_back(client); clients.push_back(client);
// once the client is in the list, update our strut to include the new // 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!) // client's (it is good that this happens after window placement!)
updateStrut(); updateStruts();
// this puts into the stacking order, then raises it // this puts into the stacking order, then raises it
_stacking.push_back(client); _stacking.push_back(client);
raiseWindow(client); raiseWindow(client);
@ -592,7 +617,7 @@ void Screen::unmanageWindow(Client *client)
// once the client is out of the list, update our strut to remove it's // once the client is out of the list, update our strut to remove it's
// influence // influence
updateStrut(); updateStruts();
// unset modal before dropping our focus // unset modal before dropping our focus
client->_modal = false; client->_modal = false;
@ -750,12 +775,14 @@ void Screen::changeNumDesktops(long num)
viewport, _num_desktops * 2); viewport, _num_desktops * 2);
delete [] viewport; delete [] viewport;
// update the work area hint // change our struts/area to match
changeWorkArea(); _area.resize(_num_desktops + 1);
_struts.resize(_num_desktops + 1);
updateStruts();
// change our desktop if we're on one that no longer exists! // change our desktop if we're on one that no longer exists!
if (_desktop >= num) if (_desktop >= _num_desktops)
changeDesktop(num - 1); changeDesktop(_num_desktops - 1);
} }
@ -786,6 +813,15 @@ void Screen::setDesktopName(long i, const otk::ustring &name)
} }
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 void Screen::installColormap(bool install) const
{ {
if (install) if (install)

View file

@ -30,7 +30,9 @@ class Client;
class Screen : public otk::EventHandler { class Screen : public otk::EventHandler {
public: public:
//! Holds a list of otk::Strut objects //! 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 | static const unsigned long event_mask = ColormapChangeMask |
EnterWindowMask | EnterWindowMask |
@ -59,11 +61,13 @@ private:
//! Is the root colormap currently installed? //! Is the root colormap currently installed?
bool _root_cmap_installed; bool _root_cmap_installed;
//! Area usable for placement etc (total - struts) //! Area usable for placement etc (total - struts), one per desktop,
otk::Rect _area; //! plus one extra for windows on all desktops
RectList _area;
//! Combined strut from all of the clients' struts //! Combined strut from all of the clients' struts, one per desktop,
otk::Strut _strut; //! plus one extra for windows on all desktops
StrutList _struts;
//! An offscreen window which gets focus when nothing else has it //! An offscreen window which gets focus when nothing else has it
Window _focuswindow; Window _focuswindow;
@ -139,8 +143,6 @@ public:
used. used.
*/ */
inline bool managed() const { return _managed; } 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 //! An offscreen window which gets focus when nothing else has it
inline Window focuswindow() const { return _focuswindow; } inline Window focuswindow() const { return _focuswindow; }
//! Returns the desktop being displayed //! Returns the desktop being displayed
@ -148,11 +150,19 @@ public:
//! Returns the number of desktops //! Returns the number of desktops
inline long numDesktops() const { return _num_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. //! Update's the screen's combined strut of all the clients.
/*! /*!
Clients should call this whenever they change their strut. Clients should call this whenever they change their strut.
*/ */
void updateStrut(); void updateStruts();
//! Manage any pre-existing windows on the screen //! Manage any pre-existing windows on the screen
void manageExisting(); void manageExisting();