diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-03-16 21:11:39 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-03-16 21:11:39 +0000 |
| commit | f8a47de5ec444c452093371e3db16857eb39a490 (patch) | |
| tree | 31db2567842d98232775f9980f7a8d2586c0ac71 /openbox/clientwrap.c | |
| parent | 8ba0586bcbdc7fe9648f1063812126d71a041670 (diff) | |
merge the C branch into HEAD
Diffstat (limited to 'openbox/clientwrap.c')
| -rw-r--r-- | openbox/clientwrap.c | 1029 |
1 files changed, 1029 insertions, 0 deletions
diff --git a/openbox/clientwrap.c b/openbox/clientwrap.c new file mode 100644 index 00000000..fe3783ed --- /dev/null +++ b/openbox/clientwrap.c @@ -0,0 +1,1029 @@ +#include "clientwrap.h" +#include "client.h" +#include "frame.h" +#include "engine.h" +#include "stacking.h" +#include "focus.h" +#include "prop.h" +#include <glib.h> + +/*************************************************************************** + + Define the type 'ClientWrap' + + ***************************************************************************/ + +#define IS_CWRAP(v) ((v)->ob_type == &ClientWrapType) +#define IS_VALID_CWRAP(v) ((v)->client != NULL) +#define CHECK_CWRAP(self, funcname) { \ + if (!IS_CWRAP(self)) { \ + PyErr_SetString(PyExc_TypeError, \ + "descriptor '" funcname "' requires a 'Client' " \ + "object"); \ + return NULL; \ + } \ + if (!IS_VALID_CWRAP(self)) { \ + PyErr_SetString(PyExc_ValueError, \ + "This 'Client' is wrapping a client which no longer "\ + "exists."); \ + return NULL; \ + } \ +} + + +staticforward PyTypeObject ClientWrapType; + +/*************************************************************************** + + Attribute methods + + ***************************************************************************/ + +static PyObject *cwrap_valid(ClientWrap *self, PyObject *args) +{ + if (!IS_CWRAP(self)) { + PyErr_SetString(PyExc_TypeError, + "descriptor 'valid' requires a 'Client' object"); + return NULL; + } + return PyInt_FromLong(self->client != NULL); +} + +static PyObject *cwrap_title(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "title"); + if (!PyArg_ParseTuple(args, ":title")) + return NULL; + return PyString_FromString(self->client->title); +} + +static PyObject *cwrap_setTitle(ClientWrap *self, PyObject *args) +{ + char *title; + + CHECK_CWRAP(self, "setTitle"); + if (!PyArg_ParseTuple(args, "s:setTitle", &title)) + return NULL; + + PROP_SETS(self->client->window, net_wm_name, utf8, title); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_iconTitle(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "iconTitle"); + if (!PyArg_ParseTuple(args, ":iconTitle")) + return NULL; + return PyString_FromString(self->client->icon_title); +} + +static PyObject *cwrap_setIconTitle(ClientWrap *self, PyObject *args) +{ + char *title; + + CHECK_CWRAP(self, "setIconTitle"); + if (!PyArg_ParseTuple(args, "s:setIconTitle", &title)) + return NULL; + + PROP_SETS(self->client->window, net_wm_icon_name, utf8, title); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_desktop(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "desktop"); + if (!PyArg_ParseTuple(args, ":desktop")) + return NULL; + return PyInt_FromLong(self->client->desktop); +} + +static PyObject *cwrap_setDesktop(ClientWrap *self, PyObject *args) +{ + int desktop; + CHECK_CWRAP(self, "setDesktop"); + if (!PyArg_ParseTuple(args, "i:setDesktop", &desktop)) + return NULL; + client_set_desktop(self->client, desktop); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_resName(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "resName"); + if (!PyArg_ParseTuple(args, ":resName")) + return NULL; + return PyString_FromString(self->client->res_name); +} + +static PyObject *cwrap_resClass(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "resClass"); + if (!PyArg_ParseTuple(args, ":resClass")) + return NULL; + return PyString_FromString(self->client->res_class); +} + +static PyObject *cwrap_role(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "role"); + if (!PyArg_ParseTuple(args, ":role")) + return NULL; + return PyString_FromString(self->client->role); +} + +static PyObject *cwrap_transient(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "transient"); + if (!PyArg_ParseTuple(args, ":transient")) + return NULL; + return PyInt_FromLong(!!self->client->transient); +} + +static PyObject *cwrap_transientFor(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "transientFor"); + if (!PyArg_ParseTuple(args, ":transientFor")) + return NULL; + if (self->client->transient_for != NULL) + return clientwrap_new(self->client->transient_for); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_transients(ClientWrap *self, PyObject *args) +{ + PyObject *tuple; + GSList *it; + guint i, s; + + CHECK_CWRAP(self, "transients"); + if (!PyArg_ParseTuple(args, ":transients")) + return NULL; + s = g_slist_length(self->client->transients); + tuple = PyTuple_New(s); + for (i = 0, it = self->client->transients; i < s; ++i, it = it->next) + PyTuple_SET_ITEM(tuple, i, clientwrap_new(it->data)); + return tuple; +} + +static PyObject *cwrap_type(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "type"); + if (!PyArg_ParseTuple(args, ":type")) + return NULL; + return PyInt_FromLong(self->client->type); +} + +static PyObject *cwrap_normal(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "normal"); + if (!PyArg_ParseTuple(args, ":normal")) + return NULL; + return PyInt_FromLong(!!client_normal(self->client)); +} + +static PyObject *cwrap_area(ClientWrap *self, PyObject *args) +{ + PyObject *tuple; + + CHECK_CWRAP(self, "area"); + if (!PyArg_ParseTuple(args, ":area")) + return NULL; + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->frame->area.x)); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->frame->area.y)); + PyTuple_SET_ITEM(tuple, 2, + PyInt_FromLong(self->client->frame->area.width)); + PyTuple_SET_ITEM(tuple, 3, + PyInt_FromLong(self->client->frame->area.height)); + return tuple; +} + +static PyObject *cwrap_setArea(ClientWrap *self, PyObject *args) +{ + int x, y, w, h, final = TRUE; + + CHECK_CWRAP(self, "setArea"); + if (!PyArg_ParseTuple(args, "(iiii)|i:setArea", &x, &y, &w, &h, &final)) + return NULL; + + frame_frame_gravity(self->client->frame, &x, &y); + w -= self->client->frame->size.left + self->client->frame->size.right; + h -= self->client->frame->size.top + self->client->frame->size.bottom; + client_configure(self->client, Corner_TopLeft, x, y, w, h, TRUE, final); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_clientArea(ClientWrap *self, PyObject *args) +{ + PyObject *tuple; + + CHECK_CWRAP(self, "clientArea"); + if (!PyArg_ParseTuple(args, ":clientArea")) + return NULL; + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->area.x)); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->area.y)); + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(self->client->area.width)); + PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(self->client->area.height)); + return tuple; +} + +static PyObject *cwrap_setClientArea(ClientWrap *self, PyObject *args) +{ + int x, y, w, h; + + CHECK_CWRAP(self, "setClientArea"); + if (!PyArg_ParseTuple(args, "(iiii)|i:setClientArea", &x, &y, &w, &h)) + return NULL; + + client_configure(self->client, Corner_TopLeft, x, y, w, h, TRUE, TRUE); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_frameSize(ClientWrap *self, PyObject *args) +{ + PyObject *tuple; + + CHECK_CWRAP(self, "frameSize"); + if (!PyArg_ParseTuple(args, ":frameSize")) + return NULL; + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->frame->size.left)); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->frame->size.top)); + PyTuple_SET_ITEM(tuple, 2, + PyInt_FromLong(self->client->frame->size.right)); + PyTuple_SET_ITEM(tuple, 3, + PyInt_FromLong(self->client->frame->size.bottom)); + return tuple; +} + +static PyObject *cwrap_strut(ClientWrap *self, PyObject *args) +{ + PyObject *tuple; + + CHECK_CWRAP(self, "strut"); + if (!PyArg_ParseTuple(args, ":strut")) + return NULL; + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->client->strut.left)); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->client->strut.top)); + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(self->client->strut.right)); + PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(self->client->strut.bottom)); + return tuple; +} + +static PyObject *cwrap_logicalSize(ClientWrap *self, PyObject *args) +{ + PyObject *tuple; + + CHECK_CWRAP(self, "logicalSize"); + if (!PyArg_ParseTuple(args, ":logicalSize")) + return NULL; + tuple = PyTuple_New(2); + PyTuple_SET_ITEM(tuple, 0, + PyInt_FromLong(self->client->logical_size.width)); + PyTuple_SET_ITEM(tuple, 1, + PyInt_FromLong(self->client->logical_size.height)); + return tuple; +} + +static PyObject *cwrap_canFocus(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "canFocus"); + if (!PyArg_ParseTuple(args, ":canFocus")) + return NULL; + return PyInt_FromLong(!!self->client->can_focus); +} + +static PyObject *cwrap_focus(ClientWrap *self, PyObject *args) +{ + int focus = TRUE; + + CHECK_CWRAP(self, "focus"); + if (!PyArg_ParseTuple(args, "|i:focus", &focus)) + return NULL; + if (focus) + return PyInt_FromLong(!!client_focus(self->client)); + else { + if (focus_client == self->client) + client_unfocus(self->client); + Py_INCREF(Py_None); + return Py_None; + } +} + +static PyObject *cwrap_focused(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "focused"); + if (!PyArg_ParseTuple(args, ":focused")) + return NULL; + return PyInt_FromLong(!!self->client->focused); +} + +static PyObject *cwrap_visible(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "visible"); + if (!PyArg_ParseTuple(args, ":visible")) + return NULL; + return PyInt_FromLong(!!self->client->frame->visible); +} + +static PyObject *cwrap_setVisible(ClientWrap *self, PyObject *args) +{ + int show; + + CHECK_CWRAP(self, "setVisible"); + if (!PyArg_ParseTuple(args, "i:setVisible", &show)) + return NULL; + if (show) + engine_frame_show(self->client->frame); + else + engine_frame_hide(self->client->frame); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_modal(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "modal"); + if (!PyArg_ParseTuple(args, ":modal")) + return NULL; + return PyInt_FromLong(!!self->client->modal); +} + +static PyObject *cwrap_setModal(ClientWrap *self, PyObject *args) +{ + int modal; + + CHECK_CWRAP(self, "setModal"); + if (!PyArg_ParseTuple(args, "i:setModal", &modal)) + return NULL; + + client_set_state(self->client, + (modal ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_modal, 0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_shaded(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "shaded"); + if (!PyArg_ParseTuple(args, ":shaded")) + return NULL; + return PyInt_FromLong(!!self->client->shaded); +} + +static PyObject *cwrap_setShaded(ClientWrap *self, PyObject *args) +{ + int shaded; + + CHECK_CWRAP(self, "setShaded"); + if (!PyArg_ParseTuple(args, "i:setShaded", &shaded)) + return NULL; + + client_shade(self->client, shaded); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_iconic(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "iconic"); + if (!PyArg_ParseTuple(args, ":iconic")) + return NULL; + return PyInt_FromLong(!!self->client->iconic); +} + +static PyObject *cwrap_setIconic(ClientWrap *self, PyObject *args) +{ + int iconify, current = TRUE; + + CHECK_CWRAP(self, "setIconic"); + if (!PyArg_ParseTuple(args, "i|i:setIconic", &iconify, ¤t)) + return NULL; + + client_iconify(self->client, iconify, current); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_maximizedHorz(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "maximizedHorz"); + if (!PyArg_ParseTuple(args, ":maximizedHorz")) + return NULL; + return PyInt_FromLong(!!self->client->max_horz); +} + +static PyObject *cwrap_setMaximizedHorz(ClientWrap *self, PyObject *args) +{ + int max; + + CHECK_CWRAP(self, "setMaximizedHorz"); + if (!PyArg_ParseTuple(args, "i:setMaximizedHorz", &max)) + return NULL; + + client_set_state(self->client, + (max ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_maximized_horz, 0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_maximizedVert(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "maximizedVert"); + if (!PyArg_ParseTuple(args, ":maximizedVert")) + return NULL; + return PyInt_FromLong(!!self->client->max_vert); +} + +static PyObject *cwrap_setMaximizedVert(ClientWrap *self, PyObject *args) +{ + int max; + + CHECK_CWRAP(self, "setMaximizedVert"); + if (!PyArg_ParseTuple(args, "i:setMaximizedVert", &max)) + return NULL; + + client_set_state(self->client, + (max ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_maximized_vert, 0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_maximized(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "maximized"); + if (!PyArg_ParseTuple(args, ":maximized")) + return NULL; + return PyInt_FromLong(self->client->max_vert || self->client->max_horz); +} + +static PyObject *cwrap_setMaximized(ClientWrap *self, PyObject *args) +{ + int max; + + CHECK_CWRAP(self, "setMaximized"); + if (!PyArg_ParseTuple(args, "i:setMaximized", &max)) + return NULL; + + client_set_state(self->client, + (max ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_maximized_vert, + prop_atoms.net_wm_state_maximized_horz); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_fullscreen(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "fullscreen"); + if (!PyArg_ParseTuple(args, ":fullscreen")) + return NULL; + return PyInt_FromLong(!!self->client->fullscreen); +} + +static PyObject *cwrap_setFullscreen(ClientWrap *self, PyObject *args) +{ + int fs; + + CHECK_CWRAP(self, "setFullscreen"); + if (!PyArg_ParseTuple(args, "i:setFullscreen", &fs)) + return NULL; + + client_set_state(self->client, + (fs ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_fullscreen, 0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_stacking(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "stacking"); + if (!PyArg_ParseTuple(args, ":stacking")) + return NULL; + return PyInt_FromLong(self->client->above ? 1 : + self->client->below ? -1 : 0); +} + +static PyObject *cwrap_setStacking(ClientWrap *self, PyObject *args) +{ + int stack; + + CHECK_CWRAP(self, "setStacking"); + if (!PyArg_ParseTuple(args, "i:setStacking", &stack)) + return NULL; + client_set_state(self->client, + (stack > 0 ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_above, 0); + client_set_state(self->client, + (stack < 0 ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_below, 0); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_raiseWindow(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "raiseWindow"); + if (!PyArg_ParseTuple(args, ":raiseWindow")) + return NULL; + stacking_raise(self->client); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_lowerWindow(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "lowerWindow"); + if (!PyArg_ParseTuple(args, ":lowerWindow")) + return NULL; + stacking_lower(self->client); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_skipPager(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "skipPager"); + if (!PyArg_ParseTuple(args, ":skipPager")) + return NULL; + return PyInt_FromLong(!!self->client->skip_pager); +} + +static PyObject *cwrap_setSkipPager(ClientWrap *self, PyObject *args) +{ + int skip; + + CHECK_CWRAP(self, "setSkipPager"); + if (!PyArg_ParseTuple(args, "i:setSkipPager", &skip)) + return NULL; + + client_set_state(self->client, + (skip ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_skip_pager, 0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_skipTaskbar(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "skipTaskbar"); + if (!PyArg_ParseTuple(args, ":skipTaskbar")) + return NULL; + return PyInt_FromLong(!!self->client->skip_taskbar); +} + +static PyObject *cwrap_setSkipTaskbar(ClientWrap *self, PyObject *args) +{ + int skip; + + CHECK_CWRAP(self, "setSkipTaskbar"); + if (!PyArg_ParseTuple(args, "i:setSkipTaskbar", &skip)) + return NULL; + + client_set_state(self->client, + (skip ? prop_atoms.net_wm_state_add : + prop_atoms.net_wm_state_remove), + prop_atoms.net_wm_state_skip_taskbar, 0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_disableDecorations(ClientWrap *self, PyObject *args) +{ + int title, handle, border; + + CHECK_CWRAP(self, "disableDecorations"); + if (!PyArg_ParseTuple(args, "iii:disableDecorations", &title, &handle, + &border)) + return NULL; + + self->client->disabled_decorations = 0; + if (title) self->client->disabled_decorations |= Decor_Titlebar; + if (handle) self->client->disabled_decorations |= Decor_Handle; + if (border) self->client->disabled_decorations |= Decor_Border; + client_setup_decor_and_functions(self->client); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_close(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "close"); + if (!PyArg_ParseTuple(args, ":close")) + return NULL; + client_close(self->client); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *cwrap_window(ClientWrap *self, PyObject *args) +{ + CHECK_CWRAP(self, "window"); + if (!PyArg_ParseTuple(args, ":window")) + return NULL; + return PyInt_FromLong(self->client->window); +} + +#define METH(n, d) {#n, (PyCFunction)cwrap_##n, METH_VARARGS, #d} + +static PyMethodDef ClientWrapMethods[] = { + METH(valid, + "Returns if the Client instance is still valid. Client instances are " + "marked as invalid when the Client they are associated is " + "closed/destroyed/released."), + METH(title, + "Returns the client's title."), + METH(setTitle, + "Change the client's title to the given string. This change will be " + "overwritten if/when the client changes its title."), + METH(iconTitle, + "Returns's the client's icon title. The icon title is the title to " + "be displayed when the client is iconified."), + METH(setIconTitle, + "Change the client's icon title to the given string. This change " + "will be overwritten if/when the client changes its icon title."), + METH(desktop, + "Returns the desktop on which the client is visible. This value will " + "always be in the range [0, ob.Openbox.numDesktops()), unless it is " + "0xffffffff. A value of 0xffffffff indicates the client is visible " + "on all desktops."), + METH(setDesktop, + "Moves the client to the specified desktop. The desktop must be in " + "the range [0, ob.Openbox.numDesktops()), unless it is 0xffffffff. A " + "value of 0xffffffff indicates the client is visible on all " + "desktops."), + METH(resName, + "Returns the resouce name of the client. The resource name is meant " + "to provide an instance name for the client."), + METH(resClass, + "Returns the resouce class of the client. The resource class is " + "meant to provide the genereal class of the application. e.g. " + "'Emacs', 'Xterm', 'XClock', 'XLoad', and so on."), + METH(role, + "Returns the client's role. The role is meant to distinguish between " + "different windows of an application. Each window should have a " + "unique role."), + METH(transient, + "Returns True or False describing if the client is a transient " + "window. Transient windows are 'temporary' windows, such as " + "preference dialogs, and usually have a parent window, which can be " + "found from transientFor()."), + METH(transientFor, + "Returns the client for which this client is a transient. See " + "transient() for a description of transience."), + METH(transients, + "Returns a tuple containing all the Clients which are transients of " + "this window. See transient() for a description of transience."), + METH(type, + "Returns the logical type of the window. This is one of the " + "ClientType constants. See also normal()."), + METH(normal, + "Returns True or False for if the client is a 'normal' window. " + "Normal windows make up most applications. Non-normal windows have " + "special rules applied to them at times such as for focus handling. " + "An example of a non-normal window is 'gnome-panel'. This value is " + "determined from the client's type(), but does not imply that the " + "window is ClientType.Normal. Rather this is a more generic " + "definition of 'normal' windows, and includes dialogs and others."), + METH(area, + "Returns the area of the screen which the client occupies. It may be " + "important to note that this is the position and size of the client " + "*with* its decorations. If you want the underlying position and " + "size of the client itself, you should use clientArea(). See also " + "logicalSize()."), + + METH(setArea, + "Sets the client's area, moving and resizing it as specified (or as " + "close as can be accomidated)."), + METH(clientArea, + "Returns the area of the screen which the client considers itself to " + "be occupying. This value is not what you see and should not be used " + "for most things (it should, for example, be used for persisting a " + "client's dimentions across sessions). See also area()."), + METH(setClientArea, + "Sets the area of the screen which the client considers itself to be " + "occupying. This is not the on-screen visible position and size, and " + "should be used with care. You probably want to use setArea() to " + "adjust the client. This should be used if you want the client " + "window (inside the decorations) to be a specific size. Adjusting " + "the client's position with this function is probably always a bad " + "idea, because of window gravity."), + METH(strut, + "Returns the application's specified strut. The strut is the amount " + "of space that should be reserved for the application on each side " + "of the screen."), + METH(frameSize, + "Returns the size of the decorations around the client window."), + METH(logicalSize, + "Returns the client's logical size. The logical size is the client's " + "size in more user friendly terms. For many apps this is simply the " + "size of the client in pixels, however for some apps this will " + "differ (e.g. terminal emulators). This value should be used when " + "displaying an applications size to the user."), + METH(canFocus, + "Returns True or False for if the client can be focused."), + METH(focus, + "Focuses (or unfocuses) the client window. Windows which return " + "False for canFocus() or visible() cannot be focused. When this " + "function returns, the client's focused() state will not be changed " + "yet. This only sends the request through the X server. You should " + "wait for the hooks.focused hook to fire, and not assume the client " + "has been focused."), + METH(focused, + "Returns True or False for if the client has the input focus."), + METH(visible, + "Returns True or False for if the client is visible. A client is not " + "visible if it is iconic() or if its desktop() is not visible."), + METH(setVisible, + "Shows or hides the client. This has no effect if its current " + "visible() state is requested."), + METH(modal, + "Returns True or False for if the client is a modal window. Modal " + "windows indicate that they must be dealt with before the program " + "can continue. When a modal window is a transient(), its " + "transientFor() client cannot be focused or raised above it."), + METH(setModal, + "Make the client window modal or non-modal."), + METH(shaded, + "Returns True or False for if the client is shaded. Shaded windows " + "have only their titlebar decorations showing."), + METH(setShaded, + "Shade or unshade the client. Shaded windows have only their " + "titlebar decorations showing. Windows which do not have a titlebar " + "cannot be shaded."), + METH(iconic, + "Returns True or False for if the window is iconified. Iconified " + "windows are not visible on any desktops."), + METH(setIconic, + "Iconifies or restores the client window. Iconified windows are not " + "visible on any desktops. Iconified windows can be restored to the " + "currently visible desktop or to their original (native) desktop."), + METH(maximizedHorz, + "Returns whether the client is maximized in the horizontal " + "direction."), + METH(setMaximizedHorz, + "Maximizes or restores a client horizontally."), + METH(maximizedVert, + "Returns whether the client is maximized in the vertical direction."), + METH(setMaximizedVert, + "Maximizes or restores a client vertically."), + METH(maximized, + "Returns whether the client is maximized in the horizontal or " + "vertical direction."), + METH(setMaximized, + "Maximizes or restores a client vertically and horzontally."), + METH(fullscreen, + "Returns if the client is in fullscreen mode. Fullscreen windows are " + "kept above all other windows and are stretched to fill the entire " + "physical display."), + METH(setFullscreen, + "Set a client into or out of fullscreen mode. Fullscreen windows are " + "kept above all other windows and are stretched to fill the entire " + "physical display."), + METH(stacking, + "Returns if the client will be stacked above/below other clients in " + "the same layer."), + METH(setStacking, + "Set how the client will be stacked according to other clients in " + "its layer."), + METH(raiseWindow, + "Raises the window to the top of its stacking layer."), + METH(lowerWindow, + "Lowers the window to the bottom of its stacking layer."), + METH(skipPager, + "Returns if the client has requested to be skipped (not displayed) " + "by pagers."), + METH(setSkipPager, + "Set whether the client should be skipped (not displayed) by " + "pagers."), + METH(skipTaskbar, + "Returns if the client has requested to be skipped (not displayed) " + "by taskbars."), + METH(setSkipTaskbar, + "Set whether the client should be skipped (not displayed) by " + "taskbars."), + METH(disableDecorations, + "Choose which decorations to disable on the client. Note that " + "decorations can only be disabled, and decorations that would " + "normally not be shown cannot be added. These values may have " + "slightly different meanings in different theme engines."), + METH(close, + "Requests the client to close its window."), + METH(window, + "Returns the client's window id. This is the id by which the X " + "server knows the client."), + { NULL, NULL, 0, NULL } +}; + +/*************************************************************************** + + Type methods/struct + + ***************************************************************************/ + +/*static PyObject *cwrap_getattr(ClientWrap *self, char *name) +{ + CHECK_CWRAP(self, "getattr"); + return Py_FindMethod(ClientWrapAttributeMethods, (PyObject*)self, name); +}*/ + +static void cwrap_dealloc(ClientWrap *self) +{ + if (self->client != NULL) + self->client->wrap = NULL; + PyObject_Del((PyObject*) self); +} + +static PyObject *cwrap_repr(ClientWrap *self) +{ + CHECK_CWRAP(self, "repr"); + return PyString_FromFormat("Client: 0x%x", (guint)self->client->window); +} + +static int cwrap_compare(ClientWrap *self, ClientWrap *other) +{ + Window w1, w2; + if (!IS_VALID_CWRAP(self)) { + PyErr_SetString(PyExc_ValueError, + "This 'Client' is wrapping a client which no longer " + "exists."); + } + + w1 = self->client->window; + w2 = other->client->window; + return w1 > w2 ? 1 : w1 < w2 ? -1 : 0; +} + +static PyTypeObject ClientWrapType = { + PyObject_HEAD_INIT(NULL) + 0, + "Client", + sizeof(ClientWrap), + 0, + (destructor) cwrap_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + (cmpfunc) cwrap_compare, /*tp_compare*/ + (reprfunc) cwrap_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + + +/*************************************************************************** + + Define the type 'ClientType' + + ***************************************************************************/ + +#define IS_CTYPE(v) ((v)->ob_type == &ClientTypeType) +#define CHECK_CTYPE(self, funcname) { \ + if (!IS_CTYPE(self)) { \ + PyErr_SetString(PyExc_TypeError, \ + "descriptor '" funcname "' requires a 'ClientType' " \ + "object"); \ + return NULL; \ + } \ +} + +staticforward PyTypeObject ClientTypeType; + +typedef struct ClientType { + PyObject_HEAD +} ClientType; + +static void ctype_dealloc(PyObject *self) +{ + PyObject_Del(self); +} + +static PyObject *ctype_getattr(ClientType *self, char *name) +{ + struct S { char *name; int val; }; + struct S s[] = { + { "Normal", Type_Normal }, + { "Dialog", Type_Dialog }, + { "Desktop", Type_Desktop }, + { "Dock", Type_Dock }, + { "Toolbar", Type_Toolbar }, + { "Menu", Type_Menu }, + { "Utility", Type_Utility }, + { "Splash", Type_Splash }, + { NULL, 0 } }; + int i; + + CHECK_CTYPE(self, "__getattr__"); + + for (i = 0; s[i].name != NULL; ++i) + if (!strcmp(s[i].name, name)) + return PyInt_FromLong(s[i].val); + PyErr_SetString(PyExc_AttributeError, "invalid attribute"); + return NULL; +} + +static PyTypeObject ClientTypeType = { + PyObject_HEAD_INIT(NULL) + 0, + "Type", + sizeof(ClientType), + 0, + (destructor) ctype_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc) ctype_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + +/*************************************************************************** + + External methods + + ***************************************************************************/ + +void clientwrap_startup() +{ + PyObject *ob, *obdict, *type; + + ClientWrapType.ob_type = &PyType_Type; + ClientWrapType.tp_methods = ClientWrapMethods; + PyType_Ready(&ClientWrapType); + + ClientTypeType.ob_type = &PyType_Type; + PyType_Ready(&ClientTypeType); + + /* get the ob module/dict */ + ob = PyImport_ImportModule("ob"); /* new */ + g_assert(ob != NULL); + obdict = PyModule_GetDict(ob); /* borrowed */ + g_assert(obdict != NULL); + + /* add the Client type to the ob module */ + PyDict_SetItemString(obdict, "Client", (PyObject*) &ClientWrapType); + + /* add an instance of ClientType */ + type = (PyObject*) PyObject_New(ClientType, &ClientTypeType); + PyDict_SetItemString(obdict, "ClientType", type); + Py_DECREF(type); + + Py_DECREF(ob); +} + +void clientwrap_shutdown() +{ +} + +PyObject *clientwrap_new(Client *client) +{ + g_assert(client != NULL); + + if (client->wrap != NULL) { + /* already has a wrapper! */ + Py_INCREF((PyObject*) client->wrap); + } else { + client->wrap = PyObject_New(ClientWrap, &ClientWrapType); + client->wrap->client = client; + } + return (PyObject*) client->wrap; +} |
