1 #include "clientwrap.h"
10 /***************************************************************************
12 Define the type 'ClientWrap'
14 ***************************************************************************/
16 #define IS_CWRAP(v) ((v)->ob_type == &ClientWrapType)
17 #define IS_VALID_CWRAP(v) ((v)->client != NULL)
18 #define CHECK_CWRAP(self, funcname) { \
19 if (!IS_CWRAP(self)) { \
20 PyErr_SetString(PyExc_TypeError, \
21 "descriptor '" funcname "' requires a 'Client' " \
25 if (!IS_VALID_CWRAP(self)) { \
26 PyErr_SetString(PyExc_ValueError, \
27 "This 'Client' is wrapping a client which no longer "\
34 staticforward PyTypeObject ClientWrapType
;
36 /***************************************************************************
40 ***************************************************************************/
42 static PyObject
*cwrap_valid(ClientWrap
*self
, PyObject
*args
)
44 if (!IS_CWRAP(self
)) {
45 PyErr_SetString(PyExc_TypeError
,
46 "descriptor 'valid' requires a 'Client' object");
49 return PyInt_FromLong(self
->client
!= NULL
);
52 static PyObject
*cwrap_title(ClientWrap
*self
, PyObject
*args
)
54 CHECK_CWRAP(self
, "title");
55 if (!PyArg_ParseTuple(args
, ":title"))
57 return PyString_FromString(self
->client
->title
);
60 static PyObject
*cwrap_setTitle(ClientWrap
*self
, PyObject
*args
)
64 CHECK_CWRAP(self
, "setTitle");
65 if (!PyArg_ParseTuple(args
, "s:setTitle", &title
))
68 PROP_SETS(self
->client
->window
, net_wm_name
, utf8
, title
);
74 static PyObject
*cwrap_iconTitle(ClientWrap
*self
, PyObject
*args
)
76 CHECK_CWRAP(self
, "iconTitle");
77 if (!PyArg_ParseTuple(args
, ":iconTitle"))
79 return PyString_FromString(self
->client
->icon_title
);
82 static PyObject
*cwrap_setIconTitle(ClientWrap
*self
, PyObject
*args
)
86 CHECK_CWRAP(self
, "setIconTitle");
87 if (!PyArg_ParseTuple(args
, "s:setIconTitle", &title
))
90 PROP_SETS(self
->client
->window
, net_wm_icon_name
, utf8
, title
);
96 static PyObject
*cwrap_desktop(ClientWrap
*self
, PyObject
*args
)
98 CHECK_CWRAP(self
, "desktop");
99 if (!PyArg_ParseTuple(args
, ":desktop"))
101 return PyInt_FromLong(self
->client
->desktop
);
104 static PyObject
*cwrap_setDesktop(ClientWrap
*self
, PyObject
*args
)
107 CHECK_CWRAP(self
, "setDesktop");
108 if (!PyArg_ParseTuple(args
, "i:setDesktop", &desktop
))
110 client_set_desktop(self
->client
, desktop
);
115 static PyObject
*cwrap_resName(ClientWrap
*self
, PyObject
*args
)
117 CHECK_CWRAP(self
, "resName");
118 if (!PyArg_ParseTuple(args
, ":resName"))
120 return PyString_FromString(self
->client
->res_name
);
123 static PyObject
*cwrap_resClass(ClientWrap
*self
, PyObject
*args
)
125 CHECK_CWRAP(self
, "resClass");
126 if (!PyArg_ParseTuple(args
, ":resClass"))
128 return PyString_FromString(self
->client
->res_class
);
131 static PyObject
*cwrap_role(ClientWrap
*self
, PyObject
*args
)
133 CHECK_CWRAP(self
, "role");
134 if (!PyArg_ParseTuple(args
, ":role"))
136 return PyString_FromString(self
->client
->role
);
139 static PyObject
*cwrap_transient(ClientWrap
*self
, PyObject
*args
)
141 CHECK_CWRAP(self
, "transient");
142 if (!PyArg_ParseTuple(args
, ":transient"))
144 return PyInt_FromLong(!!self
->client
->transient
);
147 static PyObject
*cwrap_transientFor(ClientWrap
*self
, PyObject
*args
)
149 CHECK_CWRAP(self
, "transientFor");
150 if (!PyArg_ParseTuple(args
, ":transientFor"))
152 if (self
->client
->transient_for
!= NULL
)
153 return clientwrap_new(self
->client
->transient_for
);
158 static PyObject
*cwrap_transients(ClientWrap
*self
, PyObject
*args
)
164 CHECK_CWRAP(self
, "transients");
165 if (!PyArg_ParseTuple(args
, ":transients"))
167 s
= g_slist_length(self
->client
->transients
);
168 tuple
= PyTuple_New(s
);
169 for (i
= 0, it
= self
->client
->transients
; i
< s
; ++i
, it
= it
->next
)
170 PyTuple_SET_ITEM(tuple
, i
, clientwrap_new(it
->data
));
174 static PyObject
*cwrap_type(ClientWrap
*self
, PyObject
*args
)
176 CHECK_CWRAP(self
, "type");
177 if (!PyArg_ParseTuple(args
, ":type"))
179 return PyInt_FromLong(self
->client
->type
);
182 static PyObject
*cwrap_normal(ClientWrap
*self
, PyObject
*args
)
184 CHECK_CWRAP(self
, "normal");
185 if (!PyArg_ParseTuple(args
, ":normal"))
187 return PyInt_FromLong(!!client_normal(self
->client
));
190 static PyObject
*cwrap_area(ClientWrap
*self
, PyObject
*args
)
194 CHECK_CWRAP(self
, "area");
195 if (!PyArg_ParseTuple(args
, ":area"))
197 tuple
= PyTuple_New(4);
198 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(self
->client
->frame
->area
.x
));
199 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(self
->client
->frame
->area
.y
));
200 PyTuple_SET_ITEM(tuple
, 2,
201 PyInt_FromLong(self
->client
->frame
->area
.width
));
202 PyTuple_SET_ITEM(tuple
, 3,
203 PyInt_FromLong(self
->client
->frame
->area
.height
));
207 static PyObject
*cwrap_setArea(ClientWrap
*self
, PyObject
*args
)
209 int x
, y
, w
, h
, final
= TRUE
;
211 CHECK_CWRAP(self
, "setArea");
212 if (!PyArg_ParseTuple(args
, "(iiii)|i:setArea", &x
, &y
, &w
, &h
, &final
))
215 frame_frame_gravity(self
->client
->frame
, &x
, &y
);
216 w
-= self
->client
->frame
->size
.left
+ self
->client
->frame
->size
.right
;
217 h
-= self
->client
->frame
->size
.top
+ self
->client
->frame
->size
.bottom
;
218 client_configure(self
->client
, Corner_TopLeft
, x
, y
, w
, h
, TRUE
, final
);
224 static PyObject
*cwrap_clientArea(ClientWrap
*self
, PyObject
*args
)
228 CHECK_CWRAP(self
, "clientArea");
229 if (!PyArg_ParseTuple(args
, ":clientArea"))
231 tuple
= PyTuple_New(4);
232 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(self
->client
->area
.x
));
233 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(self
->client
->area
.y
));
234 PyTuple_SET_ITEM(tuple
, 2, PyInt_FromLong(self
->client
->area
.width
));
235 PyTuple_SET_ITEM(tuple
, 3, PyInt_FromLong(self
->client
->area
.height
));
239 static PyObject
*cwrap_setClientArea(ClientWrap
*self
, PyObject
*args
)
243 CHECK_CWRAP(self
, "setClientArea");
244 if (!PyArg_ParseTuple(args
, "(iiii)|i:setClientArea", &x
, &y
, &w
, &h
))
247 client_configure(self
->client
, Corner_TopLeft
, x
, y
, w
, h
, TRUE
, TRUE
);
253 static PyObject
*cwrap_frameSize(ClientWrap
*self
, PyObject
*args
)
257 CHECK_CWRAP(self
, "frameSize");
258 if (!PyArg_ParseTuple(args
, ":frameSize"))
260 tuple
= PyTuple_New(4);
261 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(self
->client
->frame
->size
.left
));
262 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(self
->client
->frame
->size
.top
));
263 PyTuple_SET_ITEM(tuple
, 2,
264 PyInt_FromLong(self
->client
->frame
->size
.right
));
265 PyTuple_SET_ITEM(tuple
, 3,
266 PyInt_FromLong(self
->client
->frame
->size
.bottom
));
270 static PyObject
*cwrap_strut(ClientWrap
*self
, PyObject
*args
)
274 CHECK_CWRAP(self
, "strut");
275 if (!PyArg_ParseTuple(args
, ":strut"))
277 tuple
= PyTuple_New(4);
278 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(self
->client
->strut
.left
));
279 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(self
->client
->strut
.top
));
280 PyTuple_SET_ITEM(tuple
, 2, PyInt_FromLong(self
->client
->strut
.right
));
281 PyTuple_SET_ITEM(tuple
, 3, PyInt_FromLong(self
->client
->strut
.bottom
));
285 static PyObject
*cwrap_logicalSize(ClientWrap
*self
, PyObject
*args
)
289 CHECK_CWRAP(self
, "logicalSize");
290 if (!PyArg_ParseTuple(args
, ":logicalSize"))
292 tuple
= PyTuple_New(2);
293 PyTuple_SET_ITEM(tuple
, 0,
294 PyInt_FromLong(self
->client
->logical_size
.width
));
295 PyTuple_SET_ITEM(tuple
, 1,
296 PyInt_FromLong(self
->client
->logical_size
.height
));
300 static PyObject
*cwrap_canFocus(ClientWrap
*self
, PyObject
*args
)
302 CHECK_CWRAP(self
, "canFocus");
303 if (!PyArg_ParseTuple(args
, ":canFocus"))
305 return PyInt_FromLong(!!self
->client
->can_focus
);
308 static PyObject
*cwrap_focus(ClientWrap
*self
, PyObject
*args
)
312 CHECK_CWRAP(self
, "focus");
313 if (!PyArg_ParseTuple(args
, "|i:focus", &focus
))
316 return PyInt_FromLong(!!client_focus(self
->client
));
318 if (focus_client
== self
->client
)
319 client_unfocus(self
->client
);
325 static PyObject
*cwrap_focused(ClientWrap
*self
, PyObject
*args
)
327 CHECK_CWRAP(self
, "focused");
328 if (!PyArg_ParseTuple(args
, ":focused"))
330 return PyInt_FromLong(!!self
->client
->focused
);
333 static PyObject
*cwrap_visible(ClientWrap
*self
, PyObject
*args
)
335 CHECK_CWRAP(self
, "visible");
336 if (!PyArg_ParseTuple(args
, ":visible"))
338 return PyInt_FromLong(!!self
->client
->frame
->visible
);
341 static PyObject
*cwrap_setVisible(ClientWrap
*self
, PyObject
*args
)
345 CHECK_CWRAP(self
, "setVisible");
346 if (!PyArg_ParseTuple(args
, "i:setVisible", &show
))
349 engine_frame_show(self
->client
->frame
);
351 engine_frame_hide(self
->client
->frame
);
356 static PyObject
*cwrap_modal(ClientWrap
*self
, PyObject
*args
)
358 CHECK_CWRAP(self
, "modal");
359 if (!PyArg_ParseTuple(args
, ":modal"))
361 return PyInt_FromLong(!!self
->client
->modal
);
364 static PyObject
*cwrap_setModal(ClientWrap
*self
, PyObject
*args
)
368 CHECK_CWRAP(self
, "setModal");
369 if (!PyArg_ParseTuple(args
, "i:setModal", &modal
))
372 client_set_state(self
->client
,
373 (modal
? prop_atoms
.net_wm_state_add
:
374 prop_atoms
.net_wm_state_remove
),
375 prop_atoms
.net_wm_state_modal
, 0);
381 static PyObject
*cwrap_shaded(ClientWrap
*self
, PyObject
*args
)
383 CHECK_CWRAP(self
, "shaded");
384 if (!PyArg_ParseTuple(args
, ":shaded"))
386 return PyInt_FromLong(!!self
->client
->shaded
);
389 static PyObject
*cwrap_setShaded(ClientWrap
*self
, PyObject
*args
)
393 CHECK_CWRAP(self
, "setShaded");
394 if (!PyArg_ParseTuple(args
, "i:setShaded", &shaded
))
397 client_shade(self
->client
, shaded
);
403 static PyObject
*cwrap_iconic(ClientWrap
*self
, PyObject
*args
)
405 CHECK_CWRAP(self
, "iconic");
406 if (!PyArg_ParseTuple(args
, ":iconic"))
408 return PyInt_FromLong(!!self
->client
->iconic
);
411 static PyObject
*cwrap_setIconic(ClientWrap
*self
, PyObject
*args
)
413 int iconify
, current
= TRUE
;
415 CHECK_CWRAP(self
, "setIconic");
416 if (!PyArg_ParseTuple(args
, "i|i:setIconic", &iconify
, ¤t
))
419 client_iconify(self
->client
, iconify
, current
);
425 static PyObject
*cwrap_maximizedHorz(ClientWrap
*self
, PyObject
*args
)
427 CHECK_CWRAP(self
, "maximizedHorz");
428 if (!PyArg_ParseTuple(args
, ":maximizedHorz"))
430 return PyInt_FromLong(!!self
->client
->max_horz
);
433 static PyObject
*cwrap_setMaximizedHorz(ClientWrap
*self
, PyObject
*args
)
437 CHECK_CWRAP(self
, "setMaximizedHorz");
438 if (!PyArg_ParseTuple(args
, "i:setMaximizedHorz", &max
))
441 client_set_state(self
->client
,
442 (max
? prop_atoms
.net_wm_state_add
:
443 prop_atoms
.net_wm_state_remove
),
444 prop_atoms
.net_wm_state_maximized_horz
, 0);
450 static PyObject
*cwrap_maximizedVert(ClientWrap
*self
, PyObject
*args
)
452 CHECK_CWRAP(self
, "maximizedVert");
453 if (!PyArg_ParseTuple(args
, ":maximizedVert"))
455 return PyInt_FromLong(!!self
->client
->max_vert
);
458 static PyObject
*cwrap_setMaximizedVert(ClientWrap
*self
, PyObject
*args
)
462 CHECK_CWRAP(self
, "setMaximizedVert");
463 if (!PyArg_ParseTuple(args
, "i:setMaximizedVert", &max
))
466 client_set_state(self
->client
,
467 (max
? prop_atoms
.net_wm_state_add
:
468 prop_atoms
.net_wm_state_remove
),
469 prop_atoms
.net_wm_state_maximized_vert
, 0);
475 static PyObject
*cwrap_maximized(ClientWrap
*self
, PyObject
*args
)
477 CHECK_CWRAP(self
, "maximized");
478 if (!PyArg_ParseTuple(args
, ":maximized"))
480 return PyInt_FromLong(self
->client
->max_vert
|| self
->client
->max_horz
);
483 static PyObject
*cwrap_setMaximized(ClientWrap
*self
, PyObject
*args
)
487 CHECK_CWRAP(self
, "setMaximized");
488 if (!PyArg_ParseTuple(args
, "i:setMaximized", &max
))
491 client_set_state(self
->client
,
492 (max
? prop_atoms
.net_wm_state_add
:
493 prop_atoms
.net_wm_state_remove
),
494 prop_atoms
.net_wm_state_maximized_vert
,
495 prop_atoms
.net_wm_state_maximized_horz
);
501 static PyObject
*cwrap_fullscreen(ClientWrap
*self
, PyObject
*args
)
503 CHECK_CWRAP(self
, "fullscreen");
504 if (!PyArg_ParseTuple(args
, ":fullscreen"))
506 return PyInt_FromLong(!!self
->client
->fullscreen
);
509 static PyObject
*cwrap_setFullscreen(ClientWrap
*self
, PyObject
*args
)
513 CHECK_CWRAP(self
, "setFullscreen");
514 if (!PyArg_ParseTuple(args
, "i:setFullscreen", &fs
))
517 client_set_state(self
->client
,
518 (fs
? prop_atoms
.net_wm_state_add
:
519 prop_atoms
.net_wm_state_remove
),
520 prop_atoms
.net_wm_state_fullscreen
, 0);
526 static PyObject
*cwrap_stacking(ClientWrap
*self
, PyObject
*args
)
528 CHECK_CWRAP(self
, "stacking");
529 if (!PyArg_ParseTuple(args
, ":stacking"))
531 return PyInt_FromLong(self
->client
->above
? 1 :
532 self
->client
->below
? -1 : 0);
535 static PyObject
*cwrap_setStacking(ClientWrap
*self
, PyObject
*args
)
539 CHECK_CWRAP(self
, "setStacking");
540 if (!PyArg_ParseTuple(args
, "i:setStacking", &stack
))
542 client_set_state(self
->client
,
543 (stack
> 0 ? prop_atoms
.net_wm_state_add
:
544 prop_atoms
.net_wm_state_remove
),
545 prop_atoms
.net_wm_state_above
, 0);
546 client_set_state(self
->client
,
547 (stack
< 0 ? prop_atoms
.net_wm_state_add
:
548 prop_atoms
.net_wm_state_remove
),
549 prop_atoms
.net_wm_state_below
, 0);
554 static PyObject
*cwrap_raiseWindow(ClientWrap
*self
, PyObject
*args
)
556 CHECK_CWRAP(self
, "raiseWindow");
557 if (!PyArg_ParseTuple(args
, ":raiseWindow"))
559 stacking_raise(self
->client
);
564 static PyObject
*cwrap_lowerWindow(ClientWrap
*self
, PyObject
*args
)
566 CHECK_CWRAP(self
, "lowerWindow");
567 if (!PyArg_ParseTuple(args
, ":lowerWindow"))
569 stacking_lower(self
->client
);
574 static PyObject
*cwrap_skipPager(ClientWrap
*self
, PyObject
*args
)
576 CHECK_CWRAP(self
, "skipPager");
577 if (!PyArg_ParseTuple(args
, ":skipPager"))
579 return PyInt_FromLong(!!self
->client
->skip_pager
);
582 static PyObject
*cwrap_setSkipPager(ClientWrap
*self
, PyObject
*args
)
586 CHECK_CWRAP(self
, "setSkipPager");
587 if (!PyArg_ParseTuple(args
, "i:setSkipPager", &skip
))
590 client_set_state(self
->client
,
591 (skip
? prop_atoms
.net_wm_state_add
:
592 prop_atoms
.net_wm_state_remove
),
593 prop_atoms
.net_wm_state_skip_pager
, 0);
599 static PyObject
*cwrap_skipTaskbar(ClientWrap
*self
, PyObject
*args
)
601 CHECK_CWRAP(self
, "skipTaskbar");
602 if (!PyArg_ParseTuple(args
, ":skipTaskbar"))
604 return PyInt_FromLong(!!self
->client
->skip_taskbar
);
607 static PyObject
*cwrap_setSkipTaskbar(ClientWrap
*self
, PyObject
*args
)
611 CHECK_CWRAP(self
, "setSkipTaskbar");
612 if (!PyArg_ParseTuple(args
, "i:setSkipTaskbar", &skip
))
615 client_set_state(self
->client
,
616 (skip
? prop_atoms
.net_wm_state_add
:
617 prop_atoms
.net_wm_state_remove
),
618 prop_atoms
.net_wm_state_skip_taskbar
, 0);
624 static PyObject
*cwrap_disableDecorations(ClientWrap
*self
, PyObject
*args
)
626 int title
, handle
, border
;
628 CHECK_CWRAP(self
, "disableDecorations");
629 if (!PyArg_ParseTuple(args
, "iii:disableDecorations", &title
, &handle
,
633 self
->client
->disabled_decorations
= 0;
634 if (title
) self
->client
->disabled_decorations
|= Decor_Titlebar
;
635 if (handle
) self
->client
->disabled_decorations
|= Decor_Handle
;
636 if (border
) self
->client
->disabled_decorations
|= Decor_Border
;
637 client_setup_decor_and_functions(self
->client
);
643 static PyObject
*cwrap_close(ClientWrap
*self
, PyObject
*args
)
645 CHECK_CWRAP(self
, "close");
646 if (!PyArg_ParseTuple(args
, ":close"))
648 client_close(self
->client
);
653 static PyObject
*cwrap_window(ClientWrap
*self
, PyObject
*args
)
655 CHECK_CWRAP(self
, "window");
656 if (!PyArg_ParseTuple(args
, ":window"))
658 return PyInt_FromLong(self
->client
->window
);
661 #define METH(n, d) {#n, (PyCFunction)cwrap_##n, METH_VARARGS, #d}
663 static PyMethodDef ClientWrapMethods
[] = {
665 "Returns if the Client instance is still valid. Client instances are "
666 "marked as invalid when the Client they are associated is "
667 "closed/destroyed/released."),
669 "Returns the client's title."),
671 "Change the client's title to the given string. This change will be "
672 "overwritten if/when the client changes its title."),
674 "Returns's the client's icon title. The icon title is the title to "
675 "be displayed when the client is iconified."),
677 "Change the client's icon title to the given string. This change "
678 "will be overwritten if/when the client changes its icon title."),
680 "Returns the desktop on which the client is visible. This value will "
681 "always be in the range [0, ob.Openbox.numDesktops()), unless it is "
682 "0xffffffff. A value of 0xffffffff indicates the client is visible "
685 "Moves the client to the specified desktop. The desktop must be in "
686 "the range [0, ob.Openbox.numDesktops()), unless it is 0xffffffff. A "
687 "value of 0xffffffff indicates the client is visible on all "
690 "Returns the resouce name of the client. The resource name is meant "
691 "to provide an instance name for the client."),
693 "Returns the resouce class of the client. The resource class is "
694 "meant to provide the genereal class of the application. e.g. "
695 "'Emacs', 'Xterm', 'XClock', 'XLoad', and so on."),
697 "Returns the client's role. The role is meant to distinguish between "
698 "different windows of an application. Each window should have a "
701 "Returns True or False describing if the client is a transient "
702 "window. Transient windows are 'temporary' windows, such as "
703 "preference dialogs, and usually have a parent window, which can be "
704 "found from transientFor()."),
706 "Returns the client for which this client is a transient. See "
707 "transient() for a description of transience."),
709 "Returns a tuple containing all the Clients which are transients of "
710 "this window. See transient() for a description of transience."),
712 "Returns the logical type of the window. This is one of the "
713 "ClientType constants. See also normal()."),
715 "Returns True or False for if the client is a 'normal' window. "
716 "Normal windows make up most applications. Non-normal windows have "
717 "special rules applied to them at times such as for focus handling. "
718 "An example of a non-normal window is 'gnome-panel'. This value is "
719 "determined from the client's type(), but does not imply that the "
720 "window is ClientType.Normal. Rather this is a more generic "
721 "definition of 'normal' windows, and includes dialogs and others."),
723 "Returns the area of the screen which the client occupies. It may be "
724 "important to note that this is the position and size of the client "
725 "*with* its decorations. If you want the underlying position and "
726 "size of the client itself, you should use clientArea(). See also "
730 "Sets the client's area, moving and resizing it as specified (or as "
731 "close as can be accomidated)."),
733 "Returns the area of the screen which the client considers itself to "
734 "be occupying. This value is not what you see and should not be used "
735 "for most things (it should, for example, be used for persisting a "
736 "client's dimentions across sessions). See also area()."),
738 "Sets the area of the screen which the client considers itself to be "
739 "occupying. This is not the on-screen visible position and size, and "
740 "should be used with care. You probably want to use setArea() to "
741 "adjust the client. This should be used if you want the client "
742 "window (inside the decorations) to be a specific size. Adjusting "
743 "the client's position with this function is probably always a bad "
744 "idea, because of window gravity."),
746 "Returns the application's specified strut. The strut is the amount "
747 "of space that should be reserved for the application on each side "
750 "Returns the size of the decorations around the client window."),
752 "Returns the client's logical size. The logical size is the client's "
753 "size in more user friendly terms. For many apps this is simply the "
754 "size of the client in pixels, however for some apps this will "
755 "differ (e.g. terminal emulators). This value should be used when "
756 "displaying an applications size to the user."),
758 "Returns True or False for if the client can be focused."),
760 "Focuses (or unfocuses) the client window. Windows which return "
761 "False for canFocus() or visible() cannot be focused. When this "
762 "function returns, the client's focused() state will not be changed "
763 "yet. This only sends the request through the X server. You should "
764 "wait for the hooks.focused hook to fire, and not assume the client "
765 "has been focused."),
767 "Returns True or False for if the client has the input focus."),
769 "Returns True or False for if the client is visible. A client is not "
770 "visible if it is iconic() or if its desktop() is not visible."),
772 "Shows or hides the client. This has no effect if its current "
773 "visible() state is requested."),
775 "Returns True or False for if the client is a modal window. Modal "
776 "windows indicate that they must be dealt with before the program "
777 "can continue. When a modal window is a transient(), its "
778 "transientFor() client cannot be focused or raised above it."),
780 "Make the client window modal or non-modal."),
782 "Returns True or False for if the client is shaded. Shaded windows "
783 "have only their titlebar decorations showing."),
785 "Shade or unshade the client. Shaded windows have only their "
786 "titlebar decorations showing. Windows which do not have a titlebar "
787 "cannot be shaded."),
789 "Returns True or False for if the window is iconified. Iconified "
790 "windows are not visible on any desktops."),
792 "Iconifies or restores the client window. Iconified windows are not "
793 "visible on any desktops. Iconified windows can be restored to the "
794 "currently visible desktop or to their original (native) desktop."),
796 "Returns whether the client is maximized in the horizontal "
798 METH(setMaximizedHorz
,
799 "Maximizes or restores a client horizontally."),
801 "Returns whether the client is maximized in the vertical direction."),
802 METH(setMaximizedVert
,
803 "Maximizes or restores a client vertically."),
805 "Returns whether the client is maximized in the horizontal or "
806 "vertical direction."),
808 "Maximizes or restores a client vertically and horzontally."),
810 "Returns if the client is in fullscreen mode. Fullscreen windows are "
811 "kept above all other windows and are stretched to fill the entire "
812 "physical display."),
814 "Set a client into or out of fullscreen mode. Fullscreen windows are "
815 "kept above all other windows and are stretched to fill the entire "
816 "physical display."),
818 "Returns if the client will be stacked above/below other clients in "
821 "Set how the client will be stacked according to other clients in "
824 "Raises the window to the top of its stacking layer."),
826 "Lowers the window to the bottom of its stacking layer."),
828 "Returns if the client has requested to be skipped (not displayed) "
831 "Set whether the client should be skipped (not displayed) by "
834 "Returns if the client has requested to be skipped (not displayed) "
837 "Set whether the client should be skipped (not displayed) by "
839 METH(disableDecorations
,
840 "Choose which decorations to disable on the client. Note that "
841 "decorations can only be disabled, and decorations that would "
842 "normally not be shown cannot be added. These values may have "
843 "slightly different meanings in different theme engines."),
845 "Requests the client to close its window."),
847 "Returns the client's window id. This is the id by which the X "
848 "server knows the client."),
849 { NULL
, NULL
, 0, NULL
}
852 /***************************************************************************
856 ***************************************************************************/
858 /*static PyObject *cwrap_getattr(ClientWrap *self, char *name)
860 CHECK_CWRAP(self, "getattr");
861 return Py_FindMethod(ClientWrapAttributeMethods, (PyObject*)self, name);
864 static void cwrap_dealloc(ClientWrap
*self
)
866 if (self
->client
!= NULL
)
867 self
->client
->wrap
= NULL
;
868 PyObject_Del((PyObject
*) self
);
871 static PyObject
*cwrap_repr(ClientWrap
*self
)
873 CHECK_CWRAP(self
, "repr");
874 return PyString_FromFormat("Client: 0x%x", (guint
)self
->client
->window
);
877 static int cwrap_compare(ClientWrap
*self
, ClientWrap
*other
)
880 if (!IS_VALID_CWRAP(self
)) {
881 PyErr_SetString(PyExc_ValueError
,
882 "This 'Client' is wrapping a client which no longer "
886 w1
= self
->client
->window
;
887 w2
= other
->client
->window
;
888 return w1
> w2
? 1 : w1
< w2
? -1 : 0;
891 static PyTypeObject ClientWrapType
= {
892 PyObject_HEAD_INIT(NULL
)
897 (destructor
) cwrap_dealloc
, /*tp_dealloc*/
901 (cmpfunc
) cwrap_compare
, /*tp_compare*/
902 (reprfunc
) cwrap_repr
, /*tp_repr*/
904 0, /*tp_as_sequence*/
910 /***************************************************************************
912 Define the type 'ClientType'
914 ***************************************************************************/
916 #define IS_CTYPE(v) ((v)->ob_type == &ClientTypeType)
917 #define CHECK_CTYPE(self, funcname) { \
918 if (!IS_CTYPE(self)) { \
919 PyErr_SetString(PyExc_TypeError, \
920 "descriptor '" funcname "' requires a 'ClientType' " \
926 staticforward PyTypeObject ClientTypeType
;
928 typedef struct ClientType
{
932 static void ctype_dealloc(PyObject
*self
)
937 static PyObject
*ctype_getattr(ClientType
*self
, char *name
)
939 struct S
{ char *name
; int val
; };
941 { "Normal", Type_Normal
},
942 { "Dialog", Type_Dialog
},
943 { "Desktop", Type_Desktop
},
944 { "Dock", Type_Dock
},
945 { "Toolbar", Type_Toolbar
},
946 { "Menu", Type_Menu
},
947 { "Utility", Type_Utility
},
948 { "Splash", Type_Splash
},
952 CHECK_CTYPE(self
, "__getattr__");
954 for (i
= 0; s
[i
].name
!= NULL
; ++i
)
955 if (!strcmp(s
[i
].name
, name
))
956 return PyInt_FromLong(s
[i
].val
);
957 PyErr_SetString(PyExc_AttributeError
, "invalid attribute");
961 static PyTypeObject ClientTypeType
= {
962 PyObject_HEAD_INIT(NULL
)
967 (destructor
) ctype_dealloc
, /*tp_dealloc*/
969 (getattrfunc
) ctype_getattr
, /*tp_getattr*/
974 0, /*tp_as_sequence*/
979 /***************************************************************************
983 ***************************************************************************/
985 void clientwrap_startup()
987 PyObject
*ob
, *obdict
, *type
;
989 ClientWrapType
.ob_type
= &PyType_Type
;
990 ClientWrapType
.tp_methods
= ClientWrapMethods
;
991 PyType_Ready(&ClientWrapType
);
993 ClientTypeType
.ob_type
= &PyType_Type
;
994 PyType_Ready(&ClientTypeType
);
996 /* get the ob module/dict */
997 ob
= PyImport_ImportModule("ob"); /* new */
998 g_assert(ob
!= NULL
);
999 obdict
= PyModule_GetDict(ob
); /* borrowed */
1000 g_assert(obdict
!= NULL
);
1002 /* add the Client type to the ob module */
1003 PyDict_SetItemString(obdict
, "Client", (PyObject
*) &ClientWrapType
);
1005 /* add an instance of ClientType */
1006 type
= (PyObject
*) PyObject_New(ClientType
, &ClientTypeType
);
1007 PyDict_SetItemString(obdict
, "ClientType", type
);
1013 void clientwrap_shutdown()
1017 PyObject
*clientwrap_new(Client
*client
)
1019 g_assert(client
!= NULL
);
1021 if (client
->wrap
!= NULL
) {
1022 /* already has a wrapper! */
1023 Py_INCREF((PyObject
*) client
->wrap
);
1025 client
->wrap
= PyObject_New(ClientWrap
, &ClientWrapType
);
1026 client
->wrap
->client
= client
;
1028 return (PyObject
*) client
->wrap
;