use client messages to switch desktops/move windows between desktops

This commit is contained in:
Dana Jansens 2003-01-07 04:51:55 +00:00
parent 85b0dc80cf
commit 4c768d5d63
12 changed files with 692 additions and 452 deletions

View file

@ -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"

File diff suppressed because it is too large Load diff

View file

@ -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 ###

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -15,7 +15,6 @@
%}
%include "stl.i"
%include "exception.i"
//%include std_list.i
//%template(ClientList) std::list<OBClient*>;

View file

@ -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},

View file

@ -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;
}
}

View file

@ -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

View file

@ -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)

View file

@ -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)