add support for desktop layouts specified by pagers
This commit is contained in:
parent
29bd1c97a2
commit
81c164bbf9
4 changed files with 154 additions and 6 deletions
|
@ -209,7 +209,71 @@ def prev_desktop(data, no_wrap=0):
|
||||||
d = n - 1
|
d = n - 1
|
||||||
change_desktop(data, d)
|
change_desktop(data, d)
|
||||||
|
|
||||||
def send_to_desktop(data, num):
|
def up_desktop(data, num=1):
|
||||||
|
"""Switches to the desktop vertically above the current one. This is based
|
||||||
|
on the desktop layout chosen by an EWMH compliant pager. Optionally, num
|
||||||
|
can be specified to move more than one row at a time."""
|
||||||
|
screen = ob.openbox.screen(data.screen)
|
||||||
|
d = screen.desktop()
|
||||||
|
n = screen.numDesktops()
|
||||||
|
l = screen.desktopLayout()
|
||||||
|
|
||||||
|
target = d - num * l.columns
|
||||||
|
if target < 0:
|
||||||
|
target += l.rows * l.columns
|
||||||
|
while target >= n:
|
||||||
|
target -= l.columns
|
||||||
|
change_desktop(data, target)
|
||||||
|
|
||||||
|
def down_desktop(data, num=1):
|
||||||
|
"""Switches to the desktop vertically below the current one. This is based
|
||||||
|
on the desktop layout chosen by an EWMH compliant pager. Optionally, num
|
||||||
|
can be specified to move more than one row at a time."""
|
||||||
|
screen = ob.openbox.screen(data.screen)
|
||||||
|
d = screen.desktop()
|
||||||
|
n = screen.numDesktops()
|
||||||
|
l = screen.desktopLayout()
|
||||||
|
|
||||||
|
target = d + num * l.columns
|
||||||
|
if target >= n:
|
||||||
|
target -= l.rows * l.columns
|
||||||
|
while target < 0:
|
||||||
|
target += l.columns
|
||||||
|
change_desktop(data, target)
|
||||||
|
|
||||||
|
def left_desktop(data, num=1):
|
||||||
|
"""Switches to the desktop horizotally left of the current one. This is
|
||||||
|
based on the desktop layout chosen by an EWMH compliant pager.
|
||||||
|
Optionally, num can be specified to move more than one column at a
|
||||||
|
time."""
|
||||||
|
screen = ob.openbox.screen(data.screen)
|
||||||
|
d = screen.desktop()
|
||||||
|
n = screen.numDesktops()
|
||||||
|
l = screen.desktopLayout()
|
||||||
|
|
||||||
|
rowstart = d - d % l.columns
|
||||||
|
target = d - num
|
||||||
|
while target < rowstart:
|
||||||
|
target += l.columns
|
||||||
|
change_desktop(data, target)
|
||||||
|
|
||||||
|
def right_desktop(data, num=1):
|
||||||
|
"""Switches to the desktop horizotally right of the current one. This is
|
||||||
|
based on the desktop layout chosen by an EWMH compliant pager.
|
||||||
|
Optionally, num can be specified to move more than one column at a
|
||||||
|
time."""
|
||||||
|
screen = ob.openbox.screen(data.screen)
|
||||||
|
d = screen.desktop()
|
||||||
|
n = screen.numDesktops()
|
||||||
|
l = screen.desktopLayout()
|
||||||
|
|
||||||
|
rowstart = d - d % l.columns
|
||||||
|
target = d + num
|
||||||
|
while target >= rowstart + l.columns:
|
||||||
|
target -= l.columns
|
||||||
|
change_desktop(data, target)
|
||||||
|
|
||||||
|
def send_to_desktop(data, num=1):
|
||||||
"""Sends a client to a specified desktop"""
|
"""Sends a client to a specified desktop"""
|
||||||
if not data.client: return
|
if not data.client: return
|
||||||
ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
|
ob.send_client_msg(otk.display.screenInfo(data.screen).rootWindow(),
|
||||||
|
|
|
@ -53,9 +53,13 @@ ob.kbind(["C-2"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 1))
|
||||||
ob.kbind(["C-3"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 2))
|
ob.kbind(["C-3"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 2))
|
||||||
ob.kbind(["C-4"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 3))
|
ob.kbind(["C-4"], ob.KeyContext.All, lambda(d): callbacks.change_desktop(d, 3))
|
||||||
ob.kbind(["C-A-Right"], ob.KeyContext.All,
|
ob.kbind(["C-A-Right"], ob.KeyContext.All,
|
||||||
lambda(d): callbacks.next_desktop(d))
|
lambda(d): callbacks.right_desktop(d))
|
||||||
ob.kbind(["C-A-Left"], ob.KeyContext.All,
|
ob.kbind(["C-A-Left"], ob.KeyContext.All,
|
||||||
lambda(d): callbacks.prev_desktop(d))
|
lambda(d): callbacks.left_desktop(d))
|
||||||
|
ob.kbind(["C-A-Up"], ob.KeyContext.All,
|
||||||
|
lambda(d): callbacks.up_desktop(d))
|
||||||
|
ob.kbind(["C-A-Down"], ob.KeyContext.All,
|
||||||
|
lambda(d): callbacks.down_desktop(d))
|
||||||
|
|
||||||
ob.kbind(["C-S-A-Right"], ob.KeyContext.All,
|
ob.kbind(["C-S-A-Right"], ob.KeyContext.All,
|
||||||
lambda(d): callbacks.send_to_next_desktop(d))
|
lambda(d): callbacks.send_to_next_desktop(d))
|
||||||
|
|
|
@ -123,6 +123,8 @@ Screen::Screen(int screen)
|
||||||
// the manageExising() function
|
// the manageExising() function
|
||||||
changeClientList(); // initialize the client lists, which will be empty
|
changeClientList(); // initialize the client lists, which will be empty
|
||||||
|
|
||||||
|
updateDesktopLayout();
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
|
@ -198,6 +200,65 @@ void Screen::manageExisting()
|
||||||
XFree(children);
|
XFree(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::updateDesktopLayout()
|
||||||
|
{
|
||||||
|
//const unsigned long _NET_WM_ORIENTATION_HORZ = 0;
|
||||||
|
const unsigned long _NET_WM_ORIENTATION_VERT = 1;
|
||||||
|
//const unsigned long _NET_WM_TOPLEFT = 0;
|
||||||
|
const unsigned long _NET_WM_TOPRIGHT = 1;
|
||||||
|
const unsigned long _NET_WM_BOTTOMRIGHT = 2;
|
||||||
|
const unsigned long _NET_WM_BOTTOMLEFT = 3;
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
_layout.orientation = DesktopLayout::Horizontal;
|
||||||
|
_layout.start_corner = DesktopLayout::TopLeft;
|
||||||
|
_layout.rows = 1;
|
||||||
|
_layout.columns = _num_desktops;
|
||||||
|
|
||||||
|
unsigned long *data, num = 4;
|
||||||
|
if (otk::Property::get(_info->rootWindow(),
|
||||||
|
otk::Property::atoms.net_desktop_layout,
|
||||||
|
otk::Property::atoms.cardinal,
|
||||||
|
&num, &data)) {
|
||||||
|
if (num >= 4) {
|
||||||
|
if (data[0] == _NET_WM_ORIENTATION_VERT)
|
||||||
|
_layout.orientation = DesktopLayout::Vertical;
|
||||||
|
if (data[3] == _NET_WM_TOPRIGHT)
|
||||||
|
_layout.start_corner = DesktopLayout::TopRight;
|
||||||
|
else if (data[3] == _NET_WM_BOTTOMRIGHT)
|
||||||
|
_layout.start_corner = DesktopLayout::BottomRight;
|
||||||
|
else if (data[3] == _NET_WM_BOTTOMLEFT)
|
||||||
|
_layout.start_corner = DesktopLayout::BottomLeft;
|
||||||
|
|
||||||
|
// fill in a zero rows/columns
|
||||||
|
if (!(data[1] == 0 && data[2] == 0)) { // both 0's is bad data..
|
||||||
|
if (data[1] == 0) {
|
||||||
|
data[1] = (_num_desktops + _num_desktops % data[2]) / data[2];
|
||||||
|
} else if (data[2] == 0) {
|
||||||
|
data[2] = (_num_desktops + _num_desktops % data[1]) / data[1];
|
||||||
|
}
|
||||||
|
_layout.columns = data[1];
|
||||||
|
_layout.rows = data[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// bounds checking
|
||||||
|
if (_layout.orientation == DesktopLayout::Horizontal) {
|
||||||
|
if (_layout.rows > _num_desktops) _layout.rows = _num_desktops;
|
||||||
|
if (_layout.columns > (_num_desktops + _num_desktops % _layout.rows) /
|
||||||
|
_layout.rows)
|
||||||
|
_layout.columns = (_num_desktops + _num_desktops % _layout.rows) /
|
||||||
|
_layout.rows;
|
||||||
|
} else {
|
||||||
|
if (_layout.columns > _num_desktops) _layout.columns = _num_desktops;
|
||||||
|
if (_layout.rows > (_num_desktops + _num_desktops % _layout.columns) /
|
||||||
|
_layout.columns)
|
||||||
|
_layout.rows = (_num_desktops + _num_desktops % _layout.columns) /
|
||||||
|
_layout.columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Screen::updateStruts()
|
void Screen::updateStruts()
|
||||||
{
|
{
|
||||||
|
@ -770,6 +831,9 @@ void Screen::changeNumDesktops(unsigned int num)
|
||||||
_struts.resize(_num_desktops + 1);
|
_struts.resize(_num_desktops + 1);
|
||||||
updateStruts();
|
updateStruts();
|
||||||
|
|
||||||
|
// the number of rows/columns will differ
|
||||||
|
updateDesktopLayout();
|
||||||
|
|
||||||
// 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_desktops)
|
if (_desktop >= _num_desktops)
|
||||||
changeDesktop(_num_desktops - 1);
|
changeDesktop(_num_desktops - 1);
|
||||||
|
@ -836,6 +900,8 @@ void Screen::propertyHandler(const XPropertyEvent &e)
|
||||||
|
|
||||||
if (e.atom == otk::Property::atoms.net_desktop_names)
|
if (e.atom == otk::Property::atoms.net_desktop_names)
|
||||||
updateDesktopNames();
|
updateDesktopNames();
|
||||||
|
else if (e.atom == otk::Property::atoms.net_desktop_layout)
|
||||||
|
updateDesktopLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,16 @@ namespace ob {
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
|
struct DesktopLayout {
|
||||||
|
enum Corner { TopLeft, TopRight, BottomRight, BottomLeft };
|
||||||
|
enum Direction { Horizontal, Vertical };
|
||||||
|
|
||||||
|
Direction orientation;
|
||||||
|
Corner start_corner;
|
||||||
|
unsigned int rows;
|
||||||
|
unsigned int columns;
|
||||||
|
};
|
||||||
|
|
||||||
//! Manages a single screen
|
//! Manages a single screen
|
||||||
/*!
|
/*!
|
||||||
*/
|
*/
|
||||||
|
@ -58,9 +68,6 @@ private:
|
||||||
//! Information about this screen
|
//! Information about this screen
|
||||||
const otk::ScreenInfo *_info;
|
const otk::ScreenInfo *_info;
|
||||||
|
|
||||||
//! Is the root colormap currently installed?
|
|
||||||
bool _root_cmap_installed;
|
|
||||||
|
|
||||||
//! Area usable for placement etc (total - struts), one per desktop,
|
//! Area usable for placement etc (total - struts), one per desktop,
|
||||||
//! plus one extra for windows on all desktops
|
//! plus one extra for windows on all desktops
|
||||||
RectList _area;
|
RectList _area;
|
||||||
|
@ -88,6 +95,8 @@ private:
|
||||||
//! The names of all desktops
|
//! The names of all desktops
|
||||||
otk::Property::StringVect _desktop_names;
|
otk::Property::StringVect _desktop_names;
|
||||||
|
|
||||||
|
DesktopLayout _layout;
|
||||||
|
|
||||||
//! Calculate the Screen::_area member
|
//! Calculate the Screen::_area member
|
||||||
void calcArea();
|
void calcArea();
|
||||||
//! Set the list of supported NETWM atoms on the root window
|
//! Set the list of supported NETWM atoms on the root window
|
||||||
|
@ -112,6 +121,9 @@ private:
|
||||||
//! Get desktop names from the root window property
|
//! Get desktop names from the root window property
|
||||||
void updateDesktopNames();
|
void updateDesktopNames();
|
||||||
|
|
||||||
|
//! Gets the layout of the desktops from the root window property
|
||||||
|
void updateDesktopLayout();
|
||||||
|
|
||||||
//! Changes to the specified desktop, displaying windows on it and hiding
|
//! Changes to the specified desktop, displaying windows on it and hiding
|
||||||
//! windows on the others.
|
//! windows on the others.
|
||||||
/*!
|
/*!
|
||||||
|
@ -158,6 +170,8 @@ public:
|
||||||
*/
|
*/
|
||||||
const otk::Rect& area(unsigned int desktop) const;
|
const otk::Rect& area(unsigned int desktop) const;
|
||||||
|
|
||||||
|
const DesktopLayout& desktopLayout() const { return _layout; }
|
||||||
|
|
||||||
//! 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.
|
||||||
|
|
Loading…
Reference in a new issue