{ SWIG_PY_INT, (char *)"OBProperty_net_wm_action_change_desktop", (long) otk::OBProperty::net_wm_action_change_desktop, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_action_close", (long) otk::OBProperty::net_wm_action_close, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_modal", (long) otk::OBProperty::net_wm_state_modal, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_sticky", (long) otk::OBProperty::net_wm_state_sticky, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_maximized_vert", (long) otk::OBProperty::net_wm_state_maximized_vert, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_maximized_horz", (long) otk::OBProperty::net_wm_state_maximized_horz, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_shaded", (long) otk::OBProperty::net_wm_state_shaded, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_skip_pager", (long) otk::OBProperty::net_wm_state_skip_pager, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_hidden", (long) otk::OBProperty::net_wm_state_hidden, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_fullscreen", (long) otk::OBProperty::net_wm_state_fullscreen, 0, 0, 0},
-{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_floating", (long) otk::OBProperty::net_wm_state_floating, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_above", (long) otk::OBProperty::net_wm_state_above, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBProperty_net_wm_state_below", (long) otk::OBProperty::net_wm_state_below, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_kde_net_system_tray_windows", (long) otk::OBProperty::kde_net_system_tray_windows, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_kde_net_wm_system_tray_window_for", (long) otk::OBProperty::kde_net_wm_system_tray_window_for, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBProperty_kde_net_wm_window_type_override", (long) otk::OBProperty::kde_net_wm_window_type_override, 0, 0, 0},
_atoms[net_wm_action_close] = create("_NET_WM_ACTION_CLOSE");
_atoms[net_wm_state_modal] = create("_NET_WM_STATE_MODAL");
+ _atoms[net_wm_state_sticky] = create("_NET_WM_STATE_STICKY");
_atoms[net_wm_state_maximized_vert] = create("_NET_WM_STATE_MAXIMIZED_VERT");
_atoms[net_wm_state_maximized_horz] = create("_NET_WM_STATE_MAXIMIZED_HORZ");
_atoms[net_wm_state_shaded] = create("_NET_WM_STATE_SHADED");
_atoms[net_wm_state_skip_pager] = create("_NET_WM_STATE_SKIP_PAGER");
_atoms[net_wm_state_hidden] = create("_NET_WM_STATE_HIDDEN");
_atoms[net_wm_state_fullscreen] = create("_NET_WM_STATE_FULLSCREEN");
- _atoms[net_wm_state_floating] = create("_NET_WM_STATE_FLOATING");
+ _atoms[net_wm_state_above] = create("_NET_WM_STATE_ABOVE");
+ _atoms[net_wm_state_below] = create("_NET_WM_STATE_BELOW");
_atoms[kde_net_system_tray_windows] = create("_KDE_NET_SYSTEM_TRAY_WINDOWS");
_atoms[kde_net_wm_system_tray_window_for] =
net_wm_action_close,
net_wm_state_modal,
+ net_wm_state_sticky,
net_wm_state_maximized_vert,
net_wm_state_maximized_horz,
net_wm_state_shaded,
net_wm_state_skip_pager,
net_wm_state_hidden,
net_wm_state_fullscreen,
- net_wm_state_floating,
+ net_wm_state_above,
+ net_wm_state_below,
kde_net_system_tray_windows,
kde_net_wm_system_tray_window_for,
def execute(bin, screen = 0):
Openbox_execute(openbox, screen, bin)
+
+def toggle_shade(data):
+ print "toggle_shade"
+
+def raise_win(data):
+ client = Openbox_findClient(openbox, data.window())
+ if not client: return
+ screen = Openbox_screen(openbox, OBClient_screen(client))
+ OBScreen_raise(screen, client)
+
+def lower_win(data):
+ client = Openbox_findClient(openbox, data.window())
+ if not client: return
+ screen = Openbox_screen(openbox, OBClient_screen(client))
+ OBScreen_lower(screen, client)
// update EVERYTHING the first time!!
// the state is kinda assumed to be normal. is this right? XXX
- _wmstate = NormalState;
+ _wmstate = NormalState; _iconic = false;
// no default decors or functions, each has to be enabled
_decorations = _functions = 0;
// start unfocused
updateIconTitle();
updateClass();
-/*
-#ifdef DEBUG
- printf("Mapped window: 0x%lx\n"
- " title: \t%s\t icon title: \t%s\n"
- " app name: \t%s\t\t class: \t%s\n"
- " position: \t%d, %d\t\t size: \t%d, %d\n"
- " desktop: \t%lu\t\t group: \t0x%lx\n"
- " type: \t%d\t\t min size \t%d, %d\n"
- " base size \t%d, %d\t\t max size \t%d, %d\n"
- " size incr \t%d, %d\t\t gravity \t%d\n"
- " wm state \t%ld\t\t can be focused:\t%s\n"
- " notify focus: \t%s\t\t urgent: \t%s\n"
- " shaped: \t%s\t\t modal: \t%s\n"
- " shaded: \t%s\t\t iconic: \t%s\n"
- " vert maximized:\t%s\t\t horz maximized:\t%s\n"
- " fullscreen: \t%s\t\t floating: \t%s\n"
- " requested pos: \t%s\n",
- _window,
- _title.c_str(),
- _icon_title.c_str(),
- _app_name.c_str(),
- _app_class.c_str(),
- _area.x(), _area.y(),
- _area.width(), _area.height(),
- _desktop,
- _group,
- _type,
- _min_x, _min_y,
- _base_x, _base_y,
- _max_x, _max_y,
- _inc_x, _inc_y,
- _gravity,
- _wmstate,
- _can_focus ? "yes" : "no",
- _focus_notify ? "yes" : "no",
- _urgent ? "yes" : "no",
- _shaped ? "yes" : "no",
- _modal ? "yes" : "no",
- _shaded ? "yes" : "no",
- _iconic ? "yes" : "no",
- _max_vert ? "yes" : "no",
- _max_horz ? "yes" : "no",
- _fullscreen ? "yes" : "no",
- _floating ? "yes" : "no",
- _positioned ? "yes" : "no");
-#endif
-*/
+ calcLayer();
}
{
const otk::OBProperty *property = Openbox::instance->property();
- _modal = _shaded = _max_horz = _max_vert = _fullscreen = _floating = false;
+ _modal = _shaded = _max_horz = _max_vert = _fullscreen = _above = _below =
+ false;
unsigned long *state;
unsigned long num = (unsigned) -1;
else if (state[i] ==
property->atom(otk::OBProperty::net_wm_state_maximized_horz))
_max_horz = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_above))
+ _above = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_below))
+ _below = true;
}
delete [] state;
}
+void OBClient::calcLayer() {
+ if (_iconic) _layer = OBScreen::Layer_Icon;
+ else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop;
+ else if (_type == Type_Dock) _layer = OBScreen::Layer_Top;
+ else if (_fullscreen) _layer = OBScreen::Layer_Fullscreen;
+ else if (_above) _layer = OBScreen::Layer_Above;
+ else if (_below) _layer = OBScreen::Layer_Below;
+ else _layer = OBScreen::Layer_Normal;
+}
+
+
void OBClient::updateProtocols()
{
const otk::OBProperty *property = Openbox::instance->property();
else if (state ==
property->atom(otk::OBProperty::net_wm_state_fullscreen))
action = _fullscreen ? State_Remove : State_Add;
- else if (state == property->atom(otk::OBProperty::net_wm_state_floating))
- action = _floating ? State_Remove : State_Add;
+ else if (state == property->atom(otk::OBProperty::net_wm_state_above))
+ action = _above ? State_Remove : State_Add;
+ else if (state == property->atom(otk::OBProperty::net_wm_state_below))
+ action = _below ? State_Remove : State_Add;
}
if (action == State_Add) {
_fullscreen = true;
// XXX: raise the window n shit
} else if (state ==
- property->atom(otk::OBProperty::net_wm_state_floating)) {
- if (_floating) continue;
- _floating = true;
+ property->atom(otk::OBProperty::net_wm_state_above)) {
+ if (_above) continue;
+ _above = true;
// XXX: raise the window n shit
+ } else if (state ==
+ property->atom(otk::OBProperty::net_wm_state_below)) {
+ if (_below) continue;
+ _below = true;
+ // XXX: lower the window n shit
}
} else { // action == State_Remove
_fullscreen = false;
// XXX: lower the window to its proper layer
} else if (state ==
- property->atom(otk::OBProperty::net_wm_state_floating)) {
- if (!_floating) continue;
- _floating = false;
+ property->atom(otk::OBProperty::net_wm_state_above)) {
+ if (!_above) continue;
+ _above = false;
// XXX: lower the window to its proper layer
+ } else if (state ==
+ property->atom(otk::OBProperty::net_wm_state_below)) {
+ if (!_below) continue;
+ _below = false;
+ // XXX: raise the window to its proper layer
}
}
}
+ calcLayer();
+ Openbox::instance->screen(_screen)->raise(this);
}
if (e.value_mask & CWBorderWidth)
_border_width = e.border_width;
- // resize, then move, as specified in the EWMH section 7.7
+ // resize, then move, as specified in the EWMH section 7.7
if (e.value_mask & (CWWidth | CWHeight)) {
int w = (e.value_mask & CWWidth) ? e.width : _area.width();
int h = (e.value_mask & CWHeight) ? e.height : _area.height();
#include <string>
+#include "screen.hh"
+#include "widget.hh"
#include "otk/point.hh"
#include "otk/strut.hh"
#include "otk/rect.hh"
#include "otk/eventhandler.hh"
-#include "widget.hh"
namespace ob {
//! The window is a 'fullscreen' window, and should be on top of all others
bool _fullscreen;
//! The window should be on top of other windows of the same type
- bool _floating;
+ bool _above;
+ //! The window should be underneath other windows of the same type
+ bool _below;
+
+ OBScreen::StackLayer _layer;
//! A bitmask of values in the OBClient::Decoration enum
/*!
//! Adjusts the window's net_state
void setState(StateAction action, long data1, long data2);
+ //! Calculates the stacking layer for the client window
+ void calcLayer();
+
//! Update the protocols that the window supports and adjusts things if they
//! change
void updateProtocols();
inline bool maxVert() const { return _max_vert; }
//! Returns if the window is maximized horizontally
inline bool maxHorz() const { return _max_horz; }
- //! Returns if the window is fullscreen
- /*!
- When the window is fullscreen, it is kept above all others
- */
- inline bool fullscreen() const { return _fullscreen; }
- //! Returns if the window is floating
- /*!
- When the window is floating, it is kept above all others in the same
- stacking layer as it
- */
- inline bool floating() const { return _floating; }
+ //! Returns the window's stacking layer
+ inline OBScreen::StackLayer layer() const { return _layer; }
//! Removes or reapplies the client's border to its window
/*!
}
+static PyObject *_wrap_OBScreen_raise(PyObject *self, PyObject *args) {
+ PyObject *resultobj;
+ ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
+ ob::OBClient *arg2 = (ob::OBClient *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_ParseTuple(args,(char *)"OO:OBScreen_raise",&obj0,&obj1)) goto fail;
+ if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
+ if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
+ (arg1)->raise(arg2);
+
+ Py_INCREF(Py_None); resultobj = Py_None;
+ return resultobj;
+ fail:
+ return NULL;
+}
+
+
+static PyObject *_wrap_OBScreen_lower(PyObject *self, PyObject *args) {
+ PyObject *resultobj;
+ ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
+ ob::OBClient *arg2 = (ob::OBClient *) 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_ParseTuple(args,(char *)"OO:OBScreen_lower",&obj0,&obj1)) goto fail;
+ if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
+ if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
+ (arg1)->lower(arg2);
+
+ Py_INCREF(Py_None); resultobj = Py_None;
+ return resultobj;
+ fail:
+ return NULL;
+}
+
+
static PyObject * OBScreen_swigregister(PyObject *self, PyObject *args) {
PyObject *obj;
if (!PyArg_ParseTuple(args,(char*)"O", &obj)) return NULL;
}
-static PyObject *_wrap_OBClient_fullscreen(PyObject *self, PyObject *args) {
- PyObject *resultobj;
- ob::OBClient *arg1 = (ob::OBClient *) 0 ;
- bool result;
- PyObject * obj0 = 0 ;
-
- if(!PyArg_ParseTuple(args,(char *)"O:OBClient_fullscreen",&obj0)) goto fail;
- if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
- result = (bool)((ob::OBClient const *)arg1)->fullscreen();
-
- resultobj = PyInt_FromLong((long)result);
- return resultobj;
- fail:
- return NULL;
-}
-
-
-static PyObject *_wrap_OBClient_floating(PyObject *self, PyObject *args) {
+static PyObject *_wrap_OBClient_layer(PyObject *self, PyObject *args) {
PyObject *resultobj;
ob::OBClient *arg1 = (ob::OBClient *) 0 ;
- bool result;
+ int result;
PyObject * obj0 = 0 ;
- if(!PyArg_ParseTuple(args,(char *)"O:OBClient_floating",&obj0)) goto fail;
+ if(!PyArg_ParseTuple(args,(char *)"O:OBClient_layer",&obj0)) goto fail;
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
- result = (bool)((ob::OBClient const *)arg1)->floating();
+ result = (int)((ob::OBClient const *)arg1)->layer();
resultobj = PyInt_FromLong((long)result);
return resultobj;
{ (char *)"OBScreen_manageExisting", _wrap_OBScreen_manageExisting, METH_VARARGS },
{ (char *)"OBScreen_manageWindow", _wrap_OBScreen_manageWindow, METH_VARARGS },
{ (char *)"OBScreen_unmanageWindow", _wrap_OBScreen_unmanageWindow, METH_VARARGS },
+ { (char *)"OBScreen_raise", _wrap_OBScreen_raise, METH_VARARGS },
+ { (char *)"OBScreen_lower", _wrap_OBScreen_lower, METH_VARARGS },
{ (char *)"OBScreen_swigregister", OBScreen_swigregister, METH_VARARGS },
{ (char *)"MwmHints_flags_set", _wrap_MwmHints_flags_set, METH_VARARGS },
{ (char *)"MwmHints_flags_get", _wrap_MwmHints_flags_get, METH_VARARGS },
{ (char *)"OBClient_iconic", _wrap_OBClient_iconic, METH_VARARGS },
{ (char *)"OBClient_maxVert", _wrap_OBClient_maxVert, METH_VARARGS },
{ (char *)"OBClient_maxHorz", _wrap_OBClient_maxHorz, METH_VARARGS },
- { (char *)"OBClient_fullscreen", _wrap_OBClient_fullscreen, METH_VARARGS },
- { (char *)"OBClient_floating", _wrap_OBClient_floating, METH_VARARGS },
+ { (char *)"OBClient_layer", _wrap_OBClient_layer, METH_VARARGS },
{ (char *)"OBClient_toggleClientBorder", _wrap_OBClient_toggleClientBorder, METH_VARARGS },
{ (char *)"OBClient_area", _wrap_OBClient_area, METH_VARARGS },
{ (char *)"OBClient_move", _wrap_OBClient_move, METH_VARARGS },
{ SWIG_PY_INT, (char *)"Openbox_State_Normal", (long) ob::Openbox::State_Normal, 0, 0, 0},
{ SWIG_PY_INT, (char *)"Openbox_State_Exiting", (long) ob::Openbox::State_Exiting, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBScreen_event_mask", (long) ob::OBScreen::event_mask, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Icon", (long) ob::OBScreen::Layer_Icon, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Desktop", (long) ob::OBScreen::Layer_Desktop, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Below", (long) ob::OBScreen::Layer_Below, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Normal", (long) ob::OBScreen::Layer_Normal, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Above", (long) ob::OBScreen::Layer_Above, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Top", (long) ob::OBScreen::Layer_Top, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Fullscreen", (long) ob::OBScreen::Layer_Fullscreen, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_Layer_Internal", (long) ob::OBScreen::Layer_Internal, 0, 0, 0},
+{ SWIG_PY_INT, (char *)"OBScreen_NUM_LAYERS", (long) ob::OBScreen::NUM_LAYERS, 0, 0, 0},
{ SWIG_PY_INT, (char *)"MwmHints_elements", (long) ob::MwmHints::elements, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBClient_TopLeft", (long) ob::OBClient::TopLeft, 0, 0, 0},
{ SWIG_PY_INT, (char *)"OBClient_TopRight", (long) ob::OBClient::TopRight, 0, 0, 0},
#include "python.hh"
#include "otk/display.hh"
+#include <vector>
+
static bool running;
static int anotherWMRunning(Display *display, XErrorEvent *) {
printf(_("Another window manager already running on display %s.\n"),
}
}
_style.load(sconfig);
-
+
// Set the netwm atoms for geomtery and viewport
unsigned long geometry[] = { _info->width(),
_info->height() };
// add to the screen's list
clients.push_back(client);
+ // this puts into the stacking order, then raises it
+ _stacking.push_back(client);
+ raise(client);
// update the root properties
setClientList();
delete client->frame;
client->frame = 0;
- // remove from the screen's list
+ // remove from the screen's lists
+ _stacking.remove(client);
clients.remove(client);
delete client;
setClientList();
}
+void OBScreen::raise(OBClient *client)
+{
+ const int layer = client->layer();
+ std::vector<Window> wins;
+
+ _stacking.remove(client);
+
+ // the stacking list is from highest to lowest
+
+ ClientList::iterator it = _stacking.begin(), end = _stacking.end();
+ // insert the windows above this window
+ for (; it != end; ++it) {
+ if ((*it)->layer() <= layer)
+ break;
+ wins.push_back((*it)->frame->window());
+ }
+ // insert our client
+ wins.push_back(client->frame->window());
+ _stacking.insert(it, client);
+ // insert the remaining below this window
+ for (; it != end; ++it)
+ wins.push_back((*it)->frame->window());
+
+ XRestackWindows(otk::OBDisplay::display, &wins[0], wins.size());
+}
+
+void OBScreen::lower(OBClient *client)
+{
+ const int layer = client->layer();
+ std::vector<Window> wins;
+
+ _stacking.remove(client);
+
+ // the stacking list is from highest to lowest
+
+ ClientList::iterator it = _stacking.begin(), end = _stacking.end();
+ // insert the windows above this window
+ for (; it != end; ++it) {
+ if ((*it)->layer() < layer)
+ break;
+ wins.push_back((*it)->frame->window());
+ }
+ // insert our client
+ wins.push_back(client->frame->window());
+ _stacking.insert(it, client);
+ // insert the remaining below this window
+ for (; it != end; ++it)
+ wins.push_back((*it)->frame->window());
+
+ XRestackWindows(otk::OBDisplay::display, &wins[0], wins.size());
+}
+
}
ButtonPressMask |
ButtonReleaseMask;
- //! All managed clients on the screen
+ enum StackLayer {
+ Layer_Icon, // 0 - iconified windows, in any order at all
+ Layer_Desktop, // 1 - desktop windows
+ Layer_Below, // 2 - normal windows w/ below
+ Layer_Normal, // 3 - normal windows
+ Layer_Above, // 4 - normal windows w/ above
+ Layer_Top, // 5 - always-on-top-windows (docks?)
+ Layer_Fullscreen, // 6 - fullscreeen windows
+ Layer_Internal, // 7 - openbox windows/menus
+ NUM_LAYERS
+ };
+
+ //! All managed clients on the screen (in order of being mapped)
ClientList clients;
private:
//! An offscreen window which gets focus when nothing else has it
Window _focuswindow;
-
+
+ //! A list of all managed clients on the screen, in their stacking order
+ ClientList _stacking;
//! Calculate the OBScreen::_area member
void calcArea();
Set the _NET_WORKAREA root window property.
*/
void setWorkArea();
-
+
public:
#ifndef SWIG
//! Constructs a new OBScreen object
it, etc.
*/
void unmanageWindow(OBClient *client);
+
+ //! Raises a client window above all others in its stacking layer
+ void raise(OBClient *client);
+
+ //! Lowers a client window below all others in its stacking layer
+ void lower(OBClient *client);
};
}