keep track of struts for each desktop
This commit is contained in:
parent
a5ea4b0480
commit
12108e16e1
8 changed files with 123 additions and 62 deletions
|
@ -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()
|
||||||
|
|
|
@ -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() +
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
118
src/screen.cc
118
src/screen.cc
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue