use client messages to switch desktops/move windows between desktops
This commit is contained in:
parent
85b0dc80cf
commit
4c768d5d63
12 changed files with 692 additions and 452 deletions
10
otk/otk.i
10
otk/otk.i
|
@ -36,9 +36,14 @@
|
|||
#include "widget.hh"
|
||||
%}
|
||||
|
||||
%include stl.i
|
||||
%include "stl.i"
|
||||
//%include std_list.i
|
||||
|
||||
%ignore otk::OBDisplay::display;
|
||||
%inline %{
|
||||
Display *OBDisplay_display() { return otk::OBDisplay::display; }
|
||||
%};
|
||||
|
||||
namespace otk {
|
||||
%rename(setValue_bool) Configuration::setValue(std::string const &,bool);
|
||||
%rename(setValue_unsigned) Configuration::setValue(const std::string &, unsigned int);
|
||||
|
@ -99,3 +104,6 @@ namespace otk {
|
|||
%include "timerqueue.hh"
|
||||
%include "timerqueuemanager.hh"
|
||||
%include "util.hh"
|
||||
|
||||
// for Mod1Mask etc
|
||||
%include "X11/X.h"
|
||||
|
|
862
otk/otk_wrap.cc
862
otk/otk_wrap.cc
File diff suppressed because it is too large
Load diff
|
@ -105,6 +105,11 @@ def unshade(data):
|
|||
if not client: return
|
||||
OBClient_shade(client, 0)
|
||||
|
||||
def change_desktop(data, num):
|
||||
"""Switches to a specified desktop"""
|
||||
root = ScreenInfo_rootWindow(OBDisplay_screenInfo(data.screen()))
|
||||
send_client_msg(root, OBProperty_net_current_desktop, root, num)
|
||||
|
||||
def next_desktop(data, no_wrap=0):
|
||||
"""Switches to the next desktop, optionally (by default) cycling around to
|
||||
the first when going past the last."""
|
||||
|
@ -115,7 +120,7 @@ def next_desktop(data, no_wrap=0):
|
|||
d = d + 1
|
||||
elif not no_wrap:
|
||||
d = 0
|
||||
OBScreen_changeDesktop(screen, d)
|
||||
change_desktop(data, d)
|
||||
|
||||
def prev_desktop(data, no_wrap=0):
|
||||
"""Switches to the previous desktop, optionally (by default) cycling around
|
||||
|
@ -127,12 +132,49 @@ def prev_desktop(data, no_wrap=0):
|
|||
d = d - 1
|
||||
elif not no_wrap:
|
||||
d = n - 1
|
||||
OBScreen_changeDesktop(screen, d)
|
||||
change_desktop(data, d)
|
||||
|
||||
def change_desktop(data, num):
|
||||
"""Switches to a specified desktop"""
|
||||
def send_to_desktop(data, num):
|
||||
"""Sends a client to a specified desktop"""
|
||||
root = ScreenInfo_rootWindow(OBDisplay_screenInfo(data.screen()))
|
||||
client = Openbox_findClient(openbox, data.window())
|
||||
if client:
|
||||
window = OBClient_window(client)
|
||||
send_client_msg(root, OBProperty_net_wm_desktop, window, num)
|
||||
|
||||
def send_to_next_desktop(data, no_wrap=0, follow=1):
|
||||
"""Sends a window to the next desktop, optionally (by default) cycling
|
||||
around to the first when going past the last. Also optionally moving to
|
||||
the new desktop after sending the window."""
|
||||
client = Openbox_findClient(openbox, data.window())
|
||||
if not client: return
|
||||
screen = Openbox_screen(openbox, data.screen())
|
||||
OBScreen_changeDesktop(screen, num)
|
||||
d = OBScreen_desktop(screen)
|
||||
n = OBScreen_numDesktops(screen)
|
||||
if (d < (n-1)):
|
||||
d = d + 1
|
||||
elif not no_wrap:
|
||||
d = 0
|
||||
send_to_desktop(data, d)
|
||||
if follow:
|
||||
change_desktop(data, d)
|
||||
|
||||
def send_to_prev_desktop(data, no_wrap=0, follow=1):
|
||||
"""Sends a window to the previous desktop, optionally (by default) cycling
|
||||
around to the last when going past the first. Also optionally moving to
|
||||
the new desktop after sending the window."""
|
||||
client = Openbox_findClient(openbox, data.window())
|
||||
if not client: return
|
||||
screen = Openbox_screen(openbox, data.screen())
|
||||
d = OBScreen_desktop(screen)
|
||||
n = OBScreen_numDesktops(screen)
|
||||
if (d > 0):
|
||||
d = d - 1
|
||||
elif not no_wrap:
|
||||
d = n - 1
|
||||
send_to_desktop(data, d)
|
||||
if follow:
|
||||
change_desktop(data, d)
|
||||
|
||||
#########################################
|
||||
### Convenience functions for scripts ###
|
||||
|
|
|
@ -658,8 +658,6 @@ void OBClient::setDesktop(long target)
|
|||
if (target == _desktop) return;
|
||||
|
||||
printf("Setting desktop %ld\n", target);
|
||||
assert(target >= 0 || target == (signed)0xffffffff);
|
||||
//assert(target == 0xffffffff || target < MAX);
|
||||
|
||||
if (!(target >= 0 || target == (signed)0xffffffff)) return;
|
||||
|
||||
|
@ -670,8 +668,12 @@ void OBClient::setDesktop(long target)
|
|||
otk::OBProperty::Atom_Cardinal,
|
||||
(unsigned)_desktop);
|
||||
|
||||
|
||||
// XXX: move the window to the new desktop
|
||||
// 'move' the window to the new desktop
|
||||
if (_desktop == Openbox::instance->screen(_screen)->desktop() ||
|
||||
_desktop == (signed)0xffffffff)
|
||||
frame->show();
|
||||
else
|
||||
frame->hide();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1066,21 +1068,6 @@ void OBClient::changeState()
|
|||
}
|
||||
|
||||
|
||||
void OBClient::setStackLayer(int l)
|
||||
{
|
||||
if (l == 0)
|
||||
_above = _below = false; // normal
|
||||
else if (l > 0) {
|
||||
_above = true;
|
||||
_below = false; // above
|
||||
} else {
|
||||
_above = false;
|
||||
_below = true; // below
|
||||
}
|
||||
changeState();
|
||||
}
|
||||
|
||||
|
||||
void OBClient::shade(bool shade)
|
||||
{
|
||||
if (shade == _shaded) return; // already done
|
||||
|
|
|
@ -335,11 +335,12 @@ private:
|
|||
|
||||
//! Sets the wm_state to the specified value
|
||||
void setWMState(long state);
|
||||
//! Sends the window to the specified desktop
|
||||
void setDesktop(long desktop);
|
||||
//! Adjusts the window's net_state
|
||||
void setState(StateAction action, long data1, long data2);
|
||||
|
||||
//! Sends the window to the specified desktop
|
||||
void setDesktop(long desktop);
|
||||
|
||||
//! Calculates the stacking layer for the client window
|
||||
void calcLayer();
|
||||
|
||||
|
@ -368,7 +369,7 @@ public:
|
|||
#ifndef SWIG
|
||||
//! Constructs a new OBClient object around a specified window id
|
||||
/*!
|
||||
@param window The window id that the OBClient class should handle
|
||||
BB @param window The window id that the OBClient class should handle
|
||||
@param screen The screen on which the window resides
|
||||
*/
|
||||
OBClient(int screen, Window window);
|
||||
|
@ -505,15 +506,6 @@ public:
|
|||
//! Request the client to close its window.
|
||||
void close();
|
||||
|
||||
//! Sets the window's stacking layer
|
||||
/*!
|
||||
@param l An integer specifying the layer.<br>
|
||||
'0' - the normal layer<br>
|
||||
'> 0' - the 'above' layer<br>
|
||||
'< 0' - the 'below' layer
|
||||
*/
|
||||
void setStackLayer(int l);
|
||||
|
||||
//! Shades or unshades the client window
|
||||
/*!
|
||||
@param shade true if the window should be shaded; false if it should be
|
||||
|
|
|
@ -359,6 +359,13 @@ void Openbox::setFocusedClient(OBClient *c)
|
|||
otk::OBProperty::Atom_Window,
|
||||
(c && _focused_screen == *it) ? c->window() : None);
|
||||
}
|
||||
|
||||
// call the python Focus callbacks
|
||||
EventData *data = new_event_data(_focused_screen->number(),
|
||||
c ? c->window() : 0,
|
||||
EventFocus, 0);
|
||||
Openbox::instance->bindings()->fireEvent(data);
|
||||
Py_XDECREF((PyObject*)data);
|
||||
}
|
||||
|
||||
void Openbox::execute(int screen, const std::string &bin)
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
%}
|
||||
|
||||
%include "stl.i"
|
||||
%include "exception.i"
|
||||
//%include std_list.i
|
||||
//%template(ClientList) std::list<OBClient*>;
|
||||
|
||||
|
|
|
@ -1642,40 +1642,6 @@ static PyObject *_wrap_OBScreen_restack(PyObject *self, PyObject *args) {
|
|||
}
|
||||
|
||||
|
||||
static PyObject *_wrap_OBScreen_changeDesktop(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj;
|
||||
ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
|
||||
long arg2 ;
|
||||
PyObject * obj0 = 0 ;
|
||||
|
||||
if(!PyArg_ParseTuple(args,(char *)"Ol:OBScreen_changeDesktop",&obj0,&arg2)) goto fail;
|
||||
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
(arg1)->changeDesktop(arg2);
|
||||
|
||||
Py_INCREF(Py_None); resultobj = Py_None;
|
||||
return resultobj;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *_wrap_OBScreen_changeNumDesktops(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj;
|
||||
ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
|
||||
long arg2 ;
|
||||
PyObject * obj0 = 0 ;
|
||||
|
||||
if(!PyArg_ParseTuple(args,(char *)"Ol:OBScreen_changeNumDesktops",&obj0,&arg2)) goto fail;
|
||||
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
(arg1)->changeNumDesktops(arg2);
|
||||
|
||||
Py_INCREF(Py_None); resultobj = Py_None;
|
||||
return resultobj;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *_wrap_OBScreen_setDesktopName(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj;
|
||||
ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
|
||||
|
@ -2530,23 +2496,6 @@ static PyObject *_wrap_OBClient_close(PyObject *self, PyObject *args) {
|
|||
}
|
||||
|
||||
|
||||
static PyObject *_wrap_OBClient_setStackLayer(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj;
|
||||
ob::OBClient *arg1 = (ob::OBClient *) 0 ;
|
||||
int arg2 ;
|
||||
PyObject * obj0 = 0 ;
|
||||
|
||||
if(!PyArg_ParseTuple(args,(char *)"Oi:OBClient_setStackLayer",&obj0,&arg2)) goto fail;
|
||||
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||
(arg1)->setStackLayer(arg2);
|
||||
|
||||
Py_INCREF(Py_None); resultobj = Py_None;
|
||||
return resultobj;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *_wrap_OBClient_shade(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj;
|
||||
ob::OBClient *arg1 = (ob::OBClient *) 0 ;
|
||||
|
@ -2876,6 +2825,34 @@ static PyObject *_wrap_set_reset_key(PyObject *self, PyObject *args) {
|
|||
}
|
||||
|
||||
|
||||
static PyObject *_wrap_send_client_msg(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj;
|
||||
Window arg1 ;
|
||||
int arg2 ;
|
||||
Window arg3 ;
|
||||
long arg4 ;
|
||||
long arg5 = (long) 0 ;
|
||||
long arg6 = (long) 0 ;
|
||||
long arg7 = (long) 0 ;
|
||||
long arg8 = (long) 0 ;
|
||||
PyObject *result;
|
||||
PyObject * obj0 = 0 ;
|
||||
PyObject * obj2 = 0 ;
|
||||
|
||||
if(!PyArg_ParseTuple(args,(char *)"OiOl|llll:send_client_msg",&obj0,&arg2,&obj2,&arg4,&arg5,&arg6,&arg7,&arg8)) goto fail;
|
||||
arg1 = (Window) PyInt_AsLong(obj0);
|
||||
if (PyErr_Occurred()) SWIG_fail;
|
||||
arg3 = (Window) PyInt_AsLong(obj2);
|
||||
if (PyErr_Occurred()) SWIG_fail;
|
||||
result = (PyObject *)ob::send_client_msg(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8);
|
||||
|
||||
resultobj = result;
|
||||
return resultobj;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef SwigMethods[] = {
|
||||
{ (char *)"Openbox_instance", _wrap_Openbox_instance, METH_VARARGS },
|
||||
{ (char *)"Cursors_session_set", _wrap_Cursors_session_set, METH_VARARGS },
|
||||
|
@ -2924,8 +2901,6 @@ static PyMethodDef SwigMethods[] = {
|
|||
{ (char *)"OBScreen_manageWindow", _wrap_OBScreen_manageWindow, METH_VARARGS },
|
||||
{ (char *)"OBScreen_unmanageWindow", _wrap_OBScreen_unmanageWindow, METH_VARARGS },
|
||||
{ (char *)"OBScreen_restack", _wrap_OBScreen_restack, METH_VARARGS },
|
||||
{ (char *)"OBScreen_changeDesktop", _wrap_OBScreen_changeDesktop, METH_VARARGS },
|
||||
{ (char *)"OBScreen_changeNumDesktops", _wrap_OBScreen_changeNumDesktops, METH_VARARGS },
|
||||
{ (char *)"OBScreen_setDesktopName", _wrap_OBScreen_setDesktopName, METH_VARARGS },
|
||||
{ (char *)"OBScreen_propertyHandler", _wrap_OBScreen_propertyHandler, METH_VARARGS },
|
||||
{ (char *)"OBScreen_clientMessageHandler", _wrap_OBScreen_clientMessageHandler, METH_VARARGS },
|
||||
|
@ -2973,7 +2948,6 @@ static PyMethodDef SwigMethods[] = {
|
|||
{ (char *)"OBClient_move", _wrap_OBClient_move, METH_VARARGS },
|
||||
{ (char *)"OBClient_resize", _wrap_OBClient_resize, METH_VARARGS },
|
||||
{ (char *)"OBClient_close", _wrap_OBClient_close, METH_VARARGS },
|
||||
{ (char *)"OBClient_setStackLayer", _wrap_OBClient_setStackLayer, METH_VARARGS },
|
||||
{ (char *)"OBClient_shade", _wrap_OBClient_shade, METH_VARARGS },
|
||||
{ (char *)"OBClient_focus", _wrap_OBClient_focus, METH_VARARGS },
|
||||
{ (char *)"OBClient_unfocus", _wrap_OBClient_unfocus, METH_VARARGS },
|
||||
|
@ -2990,6 +2964,7 @@ static PyMethodDef SwigMethods[] = {
|
|||
{ (char *)"kbind", _wrap_kbind, METH_VARARGS },
|
||||
{ (char *)"ebind", _wrap_ebind, METH_VARARGS },
|
||||
{ (char *)"set_reset_key", _wrap_set_reset_key, METH_VARARGS },
|
||||
{ (char *)"send_client_msg", _wrap_send_client_msg, METH_VARARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -3158,6 +3133,9 @@ static swig_const_info swig_const_table[] = {
|
|||
{ SWIG_PY_INT, (char *)"EventLeaveWindow", (long) ob::EventLeaveWindow, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"EventNewWindow", (long) ob::EventNewWindow, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"EventCloseWindow", (long) ob::EventCloseWindow, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"EventStartup", (long) ob::EventStartup, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"EventShutdown", (long) ob::EventShutdown, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"EventFocus", (long) ob::EventFocus, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"NUM_EVENTS", (long) ob::NUM_EVENTS, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"X_PROTOCOL", (long) 11, 0, 0, 0},
|
||||
{ SWIG_PY_INT, (char *)"X_PROTOCOL_REVISION", (long) 0, 0, 0, 0},
|
||||
|
|
|
@ -370,6 +370,7 @@ void python_init(char *argv0)
|
|||
init_openbox();
|
||||
PyRun_SimpleString("from _otk import *; from _openbox import *;");
|
||||
PyRun_SimpleString("openbox = Openbox_instance()");
|
||||
PyRun_SimpleString("display = OBDisplay_display()");
|
||||
|
||||
/* XXX
|
||||
sys.path.append('stuff')
|
||||
|
@ -554,4 +555,32 @@ void set_reset_key(const std::string &key)
|
|||
ob::Openbox::instance->bindings()->setResetKey(key);
|
||||
}
|
||||
|
||||
PyObject *send_client_msg(Window target, int type, Window about,
|
||||
long data, long data1, long data2,
|
||||
long data3, long data4)
|
||||
{
|
||||
if (type < 0 || type >= otk::OBProperty::NUM_ATOMS) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Invalid atom type. Must be from otk::OBProperty::Atoms");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XEvent e;
|
||||
e.xclient.type = ClientMessage;
|
||||
e.xclient.format = 32;
|
||||
e.xclient.message_type =
|
||||
Openbox::instance->property()->atom((otk::OBProperty::Atoms)type);
|
||||
e.xclient.window = about;
|
||||
e.xclient.data.l[0] = data;
|
||||
e.xclient.data.l[1] = data1;
|
||||
e.xclient.data.l[2] = data2;
|
||||
e.xclient.data.l[3] = data3;
|
||||
e.xclient.data.l[4] = data4;
|
||||
|
||||
XSendEvent(otk::OBDisplay::display, target, false,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
&e);
|
||||
Py_INCREF(Py_None); return Py_None;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "otk/point.hh"
|
||||
#include "otk/rect.hh"
|
||||
#include "otk/property.hh"
|
||||
|
||||
extern "C" {
|
||||
#include <X11/Xlib.h>
|
||||
|
@ -55,6 +56,7 @@ enum EventAction {
|
|||
EventCloseWindow,
|
||||
EventStartup,
|
||||
EventShutdown,
|
||||
EventFocus,
|
||||
NUM_EVENTS
|
||||
};
|
||||
|
||||
|
@ -142,6 +144,10 @@ PyObject *ebind(ob::EventAction action, PyObject *func);
|
|||
|
||||
void set_reset_key(const std::string &key);
|
||||
|
||||
PyObject *send_client_msg(Window target, int type, Window about,
|
||||
long data, long data1 = 0, long data2 = 0,
|
||||
long data3 = 0, long data4 = 0);
|
||||
|
||||
}
|
||||
|
||||
#endif // __python_hh
|
||||
|
|
|
@ -564,19 +564,9 @@ void OBScreen::unmanageWindow(OBClient *client)
|
|||
|
||||
// remove from the stacking order
|
||||
_stacking.remove(client);
|
||||
|
||||
// pass around focus if this window was focused XXX do this better!
|
||||
if (Openbox::instance->focusedClient() == client) {
|
||||
OBClient *newfocus = 0;
|
||||
OBClient::List::iterator it, end = _stacking.end();
|
||||
for (it = _stacking.begin(); it != end; ++it)
|
||||
if ((*it)->desktop() == _desktop && (*it)->normal() && (*it)->focus()) {
|
||||
newfocus = *it;
|
||||
break;
|
||||
}
|
||||
if (!newfocus)
|
||||
client->unfocus();
|
||||
}
|
||||
|
||||
// unfocus the client
|
||||
client->unfocus();
|
||||
|
||||
// remove from the wm's map
|
||||
Openbox::instance->removeClient(client->window());
|
||||
|
@ -669,6 +659,10 @@ void OBScreen::changeDesktop(long desktop)
|
|||
(*it)->frame->show();
|
||||
}
|
||||
}
|
||||
|
||||
// if nothing is focused, force the callbacks to fire
|
||||
// if (!Openbox::instance->focusedClient())
|
||||
// Openbox::instance->setFocusedClient(0);
|
||||
}
|
||||
|
||||
void OBScreen::changeNumDesktops(long num)
|
||||
|
|
|
@ -116,6 +116,21 @@ private:
|
|||
//! Get desktop names from the root window property
|
||||
void updateDesktopNames();
|
||||
|
||||
//! Changes to the specified desktop, displaying windows on it and hiding
|
||||
//! windows on the others.
|
||||
/*!
|
||||
@param desktop The number of the desktop to switch to (starts from 0).
|
||||
If the desktop is out of valid range, it is ignored.
|
||||
*/
|
||||
void changeDesktop(long desktop);
|
||||
|
||||
//! Changes the number of desktops.
|
||||
/*!
|
||||
@param num The number of desktops that should exist. This value must be
|
||||
greater than 0 or it will be ignored.
|
||||
*/
|
||||
void changeNumDesktops(long num);
|
||||
|
||||
public:
|
||||
#ifndef SWIG
|
||||
//! Constructs a new OBScreen object
|
||||
|
@ -169,21 +184,6 @@ public:
|
|||
//! layer
|
||||
void restack(bool raise, OBClient *client);
|
||||
|
||||
//! Changes to the specified desktop, displaying windows on it and hiding
|
||||
//! windows on the others.
|
||||
/*!
|
||||
@param desktop The number of the desktop to switch to (starts from 0).
|
||||
If the desktop is out of valid range, it is ignored.
|
||||
*/
|
||||
void changeDesktop(long desktop);
|
||||
|
||||
//! Changes the number of desktops.
|
||||
/*!
|
||||
@param num The number of desktops that should exist. This value must be
|
||||
greater than 0 or it will be ignored.
|
||||
*/
|
||||
void changeNumDesktops(long num);
|
||||
|
||||
//! Sets the name of a desktop
|
||||
/*!
|
||||
@param i The index of the desktop to set the name for (starts at 0)
|
||||
|
|
Loading…
Reference in a new issue