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 "widget.hh"
%} %}
%include stl.i %include "stl.i"
//%include std_list.i //%include std_list.i
%ignore otk::OBDisplay::display;
%inline %{
Display *OBDisplay_display() { return otk::OBDisplay::display; }
%};
namespace otk { namespace otk {
%rename(setValue_bool) Configuration::setValue(std::string const &,bool); %rename(setValue_bool) Configuration::setValue(std::string const &,bool);
%rename(setValue_unsigned) Configuration::setValue(const std::string &, unsigned int); %rename(setValue_unsigned) Configuration::setValue(const std::string &, unsigned int);
@ -99,3 +104,6 @@ namespace otk {
%include "timerqueue.hh" %include "timerqueue.hh"
%include "timerqueuemanager.hh" %include "timerqueuemanager.hh"
%include "util.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 if not client: return
OBClient_shade(client, 0) 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): def next_desktop(data, no_wrap=0):
"""Switches to the next desktop, optionally (by default) cycling around to """Switches to the next desktop, optionally (by default) cycling around to
the first when going past the last.""" the first when going past the last."""
@ -115,7 +120,7 @@ def next_desktop(data, no_wrap=0):
d = d + 1 d = d + 1
elif not no_wrap: elif not no_wrap:
d = 0 d = 0
OBScreen_changeDesktop(screen, d) change_desktop(data, d)
def prev_desktop(data, no_wrap=0): def prev_desktop(data, no_wrap=0):
"""Switches to the previous desktop, optionally (by default) cycling around """Switches to the previous desktop, optionally (by default) cycling around
@ -127,12 +132,49 @@ def prev_desktop(data, no_wrap=0):
d = d - 1 d = d - 1
elif not no_wrap: elif not no_wrap:
d = n - 1 d = n - 1
OBScreen_changeDesktop(screen, d) change_desktop(data, d)
def change_desktop(data, num): def send_to_desktop(data, num):
"""Switches to a specified desktop""" """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()) 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 ### ### Convenience functions for scripts ###

View file

@ -658,8 +658,6 @@ void OBClient::setDesktop(long target)
if (target == _desktop) return; if (target == _desktop) return;
printf("Setting desktop %ld\n", target); printf("Setting desktop %ld\n", target);
assert(target >= 0 || target == (signed)0xffffffff);
//assert(target == 0xffffffff || target < MAX);
if (!(target >= 0 || target == (signed)0xffffffff)) return; if (!(target >= 0 || target == (signed)0xffffffff)) return;
@ -670,8 +668,12 @@ void OBClient::setDesktop(long target)
otk::OBProperty::Atom_Cardinal, otk::OBProperty::Atom_Cardinal,
(unsigned)_desktop); (unsigned)_desktop);
// 'move' the window to the new desktop
// XXX: 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) void OBClient::shade(bool shade)
{ {
if (shade == _shaded) return; // already done if (shade == _shaded) return; // already done

View file

@ -335,11 +335,12 @@ private:
//! Sets the wm_state to the specified value //! Sets the wm_state to the specified value
void setWMState(long state); void setWMState(long state);
//! Sends the window to the specified desktop
void setDesktop(long desktop);
//! Adjusts the window's net_state //! Adjusts the window's net_state
void setState(StateAction action, long data1, long data2); 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 //! Calculates the stacking layer for the client window
void calcLayer(); void calcLayer();
@ -368,7 +369,7 @@ public:
#ifndef SWIG #ifndef SWIG
//! Constructs a new OBClient object around a specified window id //! 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 @param screen The screen on which the window resides
*/ */
OBClient(int screen, Window window); OBClient(int screen, Window window);
@ -505,15 +506,6 @@ public:
//! Request the client to close its window. //! Request the client to close its window.
void close(); 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 //! Shades or unshades the client window
/*! /*!
@param shade true if the window should be shaded; false if it should be @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, otk::OBProperty::Atom_Window,
(c && _focused_screen == *it) ? c->window() : None); (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) void Openbox::execute(int screen, const std::string &bin)

View file

@ -15,7 +15,6 @@
%} %}
%include "stl.i" %include "stl.i"
%include "exception.i"
//%include std_list.i //%include std_list.i
//%template(ClientList) std::list<OBClient*>; //%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) { static PyObject *_wrap_OBScreen_setDesktopName(PyObject *self, PyObject *args) {
PyObject *resultobj; PyObject *resultobj;
ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; 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) { static PyObject *_wrap_OBClient_shade(PyObject *self, PyObject *args) {
PyObject *resultobj; PyObject *resultobj;
ob::OBClient *arg1 = (ob::OBClient *) 0 ; 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[] = { static PyMethodDef SwigMethods[] = {
{ (char *)"Openbox_instance", _wrap_Openbox_instance, METH_VARARGS }, { (char *)"Openbox_instance", _wrap_Openbox_instance, METH_VARARGS },
{ (char *)"Cursors_session_set", _wrap_Cursors_session_set, 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_manageWindow", _wrap_OBScreen_manageWindow, METH_VARARGS },
{ (char *)"OBScreen_unmanageWindow", _wrap_OBScreen_unmanageWindow, METH_VARARGS }, { (char *)"OBScreen_unmanageWindow", _wrap_OBScreen_unmanageWindow, METH_VARARGS },
{ (char *)"OBScreen_restack", _wrap_OBScreen_restack, 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_setDesktopName", _wrap_OBScreen_setDesktopName, METH_VARARGS },
{ (char *)"OBScreen_propertyHandler", _wrap_OBScreen_propertyHandler, METH_VARARGS }, { (char *)"OBScreen_propertyHandler", _wrap_OBScreen_propertyHandler, METH_VARARGS },
{ (char *)"OBScreen_clientMessageHandler", _wrap_OBScreen_clientMessageHandler, 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_move", _wrap_OBClient_move, METH_VARARGS },
{ (char *)"OBClient_resize", _wrap_OBClient_resize, METH_VARARGS }, { (char *)"OBClient_resize", _wrap_OBClient_resize, METH_VARARGS },
{ (char *)"OBClient_close", _wrap_OBClient_close, 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_shade", _wrap_OBClient_shade, METH_VARARGS },
{ (char *)"OBClient_focus", _wrap_OBClient_focus, METH_VARARGS }, { (char *)"OBClient_focus", _wrap_OBClient_focus, METH_VARARGS },
{ (char *)"OBClient_unfocus", _wrap_OBClient_unfocus, METH_VARARGS }, { (char *)"OBClient_unfocus", _wrap_OBClient_unfocus, METH_VARARGS },
@ -2990,6 +2964,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"kbind", _wrap_kbind, METH_VARARGS }, { (char *)"kbind", _wrap_kbind, METH_VARARGS },
{ (char *)"ebind", _wrap_ebind, METH_VARARGS }, { (char *)"ebind", _wrap_ebind, METH_VARARGS },
{ (char *)"set_reset_key", _wrap_set_reset_key, METH_VARARGS }, { (char *)"set_reset_key", _wrap_set_reset_key, METH_VARARGS },
{ (char *)"send_client_msg", _wrap_send_client_msg, METH_VARARGS },
{ NULL, NULL } { 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 *)"EventLeaveWindow", (long) ob::EventLeaveWindow, 0, 0, 0},
{ SWIG_PY_INT, (char *)"EventNewWindow", (long) ob::EventNewWindow, 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 *)"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 *)"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", (long) 11, 0, 0, 0},
{ SWIG_PY_INT, (char *)"X_PROTOCOL_REVISION", (long) 0, 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(); init_openbox();
PyRun_SimpleString("from _otk import *; from _openbox import *;"); PyRun_SimpleString("from _otk import *; from _openbox import *;");
PyRun_SimpleString("openbox = Openbox_instance()"); PyRun_SimpleString("openbox = Openbox_instance()");
PyRun_SimpleString("display = OBDisplay_display()");
/* XXX /* XXX
sys.path.append('stuff') sys.path.append('stuff')
@ -554,4 +555,32 @@ void set_reset_key(const std::string &key)
ob::Openbox::instance->bindings()->setResetKey(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/point.hh"
#include "otk/rect.hh" #include "otk/rect.hh"
#include "otk/property.hh"
extern "C" { extern "C" {
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -55,6 +56,7 @@ enum EventAction {
EventCloseWindow, EventCloseWindow,
EventStartup, EventStartup,
EventShutdown, EventShutdown,
EventFocus,
NUM_EVENTS NUM_EVENTS
}; };
@ -142,6 +144,10 @@ PyObject *ebind(ob::EventAction action, PyObject *func);
void set_reset_key(const std::string &key); 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 #endif // __python_hh

View file

@ -565,18 +565,8 @@ void OBScreen::unmanageWindow(OBClient *client)
// remove from the stacking order // remove from the stacking order
_stacking.remove(client); _stacking.remove(client);
// pass around focus if this window was focused XXX do this better! // unfocus the client
if (Openbox::instance->focusedClient() == client) { client->unfocus();
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();
}
// remove from the wm's map // remove from the wm's map
Openbox::instance->removeClient(client->window()); Openbox::instance->removeClient(client->window());
@ -669,6 +659,10 @@ void OBScreen::changeDesktop(long desktop)
(*it)->frame->show(); (*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) void OBScreen::changeNumDesktops(long num)

View file

@ -116,6 +116,21 @@ private:
//! Get desktop names from the root window property //! Get desktop names from the root window property
void updateDesktopNames(); 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: public:
#ifndef SWIG #ifndef SWIG
//! Constructs a new OBScreen object //! Constructs a new OBScreen object
@ -169,21 +184,6 @@ public:
//! layer //! layer
void restack(bool raise, OBClient *client); 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 //! Sets the name of a desktop
/*! /*!
@param i The index of the desktop to set the name for (starts at 0) @param i The index of the desktop to set the name for (starts at 0)