]> Dogcows Code - chaz/openbox/blob - clientwrap.c
fe3783edf036fe2fc5f89ec232d38e7d60013efc
[chaz/openbox] / clientwrap.c
1 #include "clientwrap.h"
2 #include "client.h"
3 #include "frame.h"
4 #include "engine.h"
5 #include "stacking.h"
6 #include "focus.h"
7 #include "prop.h"
8 #include <glib.h>
9
10 /***************************************************************************
11
12 Define the type 'ClientWrap'
13
14 ***************************************************************************/
15
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' " \
22 "object"); \
23 return NULL; \
24 } \
25 if (!IS_VALID_CWRAP(self)) { \
26 PyErr_SetString(PyExc_ValueError, \
27 "This 'Client' is wrapping a client which no longer "\
28 "exists."); \
29 return NULL; \
30 } \
31 }
32
33
34 staticforward PyTypeObject ClientWrapType;
35
36 /***************************************************************************
37
38 Attribute methods
39
40 ***************************************************************************/
41
42 static PyObject *cwrap_valid(ClientWrap *self, PyObject *args)
43 {
44 if (!IS_CWRAP(self)) {
45 PyErr_SetString(PyExc_TypeError,
46 "descriptor 'valid' requires a 'Client' object");
47 return NULL;
48 }
49 return PyInt_FromLong(self->client != NULL);
50 }
51
52 static PyObject *cwrap_title(ClientWrap *self, PyObject *args)
53 {
54 CHECK_CWRAP(self, "title");
55 if (!PyArg_ParseTuple(args, ":title"))
56 return NULL;
57 return PyString_FromString(self->client->title);
58 }
59
60 static PyObject *cwrap_setTitle(ClientWrap *self, PyObject *args)
61 {
62 char *title;
63
64 CHECK_CWRAP(self, "setTitle");
65 if (!PyArg_ParseTuple(args, "s:setTitle", &title))
66 return NULL;
67
68 PROP_SETS(self->client->window, net_wm_name, utf8, title);
69
70 Py_INCREF(Py_None);
71 return Py_None;
72 }
73
74 static PyObject *cwrap_iconTitle(ClientWrap *self, PyObject *args)
75 {
76 CHECK_CWRAP(self, "iconTitle");
77 if (!PyArg_ParseTuple(args, ":iconTitle"))
78 return NULL;
79 return PyString_FromString(self->client->icon_title);
80 }
81
82 static PyObject *cwrap_setIconTitle(ClientWrap *self, PyObject *args)
83 {
84 char *title;
85
86 CHECK_CWRAP(self, "setIconTitle");
87 if (!PyArg_ParseTuple(args, "s:setIconTitle", &title))
88 return NULL;
89
90 PROP_SETS(self->client->window, net_wm_icon_name, utf8, title);
91
92 Py_INCREF(Py_None);
93 return Py_None;
94 }
95
96 static PyObject *cwrap_desktop(ClientWrap *self, PyObject *args)
97 {
98 CHECK_CWRAP(self, "desktop");
99 if (!PyArg_ParseTuple(args, ":desktop"))
100 return NULL;
101 return PyInt_FromLong(self->client->desktop);
102 }
103
104 static PyObject *cwrap_setDesktop(ClientWrap *self, PyObject *args)
105 {
106 int desktop;
107 CHECK_CWRAP(self, "setDesktop");
108 if (!PyArg_ParseTuple(args, "i:setDesktop", &desktop))
109 return NULL;
110 client_set_desktop(self->client, desktop);
111 Py_INCREF(Py_None);
112 return Py_None;
113 }
114
115 static PyObject *cwrap_resName(ClientWrap *self, PyObject *args)
116 {
117 CHECK_CWRAP(self, "resName");
118 if (!PyArg_ParseTuple(args, ":resName"))
119 return NULL;
120 return PyString_FromString(self->client->res_name);
121 }
122
123 static PyObject *cwrap_resClass(ClientWrap *self, PyObject *args)
124 {
125 CHECK_CWRAP(self, "resClass");
126 if (!PyArg_ParseTuple(args, ":resClass"))
127 return NULL;
128 return PyString_FromString(self->client->res_class);
129 }
130
131 static PyObject *cwrap_role(ClientWrap *self, PyObject *args)
132 {
133 CHECK_CWRAP(self, "role");
134 if (!PyArg_ParseTuple(args, ":role"))
135 return NULL;
136 return PyString_FromString(self->client->role);
137 }
138
139 static PyObject *cwrap_transient(ClientWrap *self, PyObject *args)
140 {
141 CHECK_CWRAP(self, "transient");
142 if (!PyArg_ParseTuple(args, ":transient"))
143 return NULL;
144 return PyInt_FromLong(!!self->client->transient);
145 }
146
147 static PyObject *cwrap_transientFor(ClientWrap *self, PyObject *args)
148 {
149 CHECK_CWRAP(self, "transientFor");
150 if (!PyArg_ParseTuple(args, ":transientFor"))
151 return NULL;
152 if (self->client->transient_for != NULL)
153 return clientwrap_new(self->client->transient_for);
154 Py_INCREF(Py_None);
155 return Py_None;
156 }
157
158 static PyObject *cwrap_transients(ClientWrap *self, PyObject *args)
159 {
160 PyObject *tuple;
161 GSList *it;
162 guint i, s;
163
164 CHECK_CWRAP(self, "transients");
165 if (!PyArg_ParseTuple(args, ":transients"))
166 return NULL;
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));
171 return tuple;
172 }
173
174 static PyObject *cwrap_type(ClientWrap *self, PyObject *args)
175 {
176 CHECK_CWRAP(self, "type");
177 if (!PyArg_ParseTuple(args, ":type"))
178 return NULL;
179 return PyInt_FromLong(self->client->type);
180 }
181
182 static PyObject *cwrap_normal(ClientWrap *self, PyObject *args)
183 {
184 CHECK_CWRAP(self, "normal");
185 if (!PyArg_ParseTuple(args, ":normal"))
186 return NULL;
187 return PyInt_FromLong(!!client_normal(self->client));
188 }
189
190 static PyObject *cwrap_area(ClientWrap *self, PyObject *args)
191 {
192 PyObject *tuple;
193
194 CHECK_CWRAP(self, "area");
195 if (!PyArg_ParseTuple(args, ":area"))
196 return NULL;
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));
204 return tuple;
205 }
206
207 static PyObject *cwrap_setArea(ClientWrap *self, PyObject *args)
208 {
209 int x, y, w, h, final = TRUE;
210
211 CHECK_CWRAP(self, "setArea");
212 if (!PyArg_ParseTuple(args, "(iiii)|i:setArea", &x, &y, &w, &h, &final))
213 return NULL;
214
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);
219
220 Py_INCREF(Py_None);
221 return Py_None;
222 }
223
224 static PyObject *cwrap_clientArea(ClientWrap *self, PyObject *args)
225 {
226 PyObject *tuple;
227
228 CHECK_CWRAP(self, "clientArea");
229 if (!PyArg_ParseTuple(args, ":clientArea"))
230 return NULL;
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));
236 return tuple;
237 }
238
239 static PyObject *cwrap_setClientArea(ClientWrap *self, PyObject *args)
240 {
241 int x, y, w, h;
242
243 CHECK_CWRAP(self, "setClientArea");
244 if (!PyArg_ParseTuple(args, "(iiii)|i:setClientArea", &x, &y, &w, &h))
245 return NULL;
246
247 client_configure(self->client, Corner_TopLeft, x, y, w, h, TRUE, TRUE);
248
249 Py_INCREF(Py_None);
250 return Py_None;
251 }
252
253 static PyObject *cwrap_frameSize(ClientWrap *self, PyObject *args)
254 {
255 PyObject *tuple;
256
257 CHECK_CWRAP(self, "frameSize");
258 if (!PyArg_ParseTuple(args, ":frameSize"))
259 return NULL;
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));
267 return tuple;
268 }
269
270 static PyObject *cwrap_strut(ClientWrap *self, PyObject *args)
271 {
272 PyObject *tuple;
273
274 CHECK_CWRAP(self, "strut");
275 if (!PyArg_ParseTuple(args, ":strut"))
276 return NULL;
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));
282 return tuple;
283 }
284
285 static PyObject *cwrap_logicalSize(ClientWrap *self, PyObject *args)
286 {
287 PyObject *tuple;
288
289 CHECK_CWRAP(self, "logicalSize");
290 if (!PyArg_ParseTuple(args, ":logicalSize"))
291 return NULL;
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));
297 return tuple;
298 }
299
300 static PyObject *cwrap_canFocus(ClientWrap *self, PyObject *args)
301 {
302 CHECK_CWRAP(self, "canFocus");
303 if (!PyArg_ParseTuple(args, ":canFocus"))
304 return NULL;
305 return PyInt_FromLong(!!self->client->can_focus);
306 }
307
308 static PyObject *cwrap_focus(ClientWrap *self, PyObject *args)
309 {
310 int focus = TRUE;
311
312 CHECK_CWRAP(self, "focus");
313 if (!PyArg_ParseTuple(args, "|i:focus", &focus))
314 return NULL;
315 if (focus)
316 return PyInt_FromLong(!!client_focus(self->client));
317 else {
318 if (focus_client == self->client)
319 client_unfocus(self->client);
320 Py_INCREF(Py_None);
321 return Py_None;
322 }
323 }
324
325 static PyObject *cwrap_focused(ClientWrap *self, PyObject *args)
326 {
327 CHECK_CWRAP(self, "focused");
328 if (!PyArg_ParseTuple(args, ":focused"))
329 return NULL;
330 return PyInt_FromLong(!!self->client->focused);
331 }
332
333 static PyObject *cwrap_visible(ClientWrap *self, PyObject *args)
334 {
335 CHECK_CWRAP(self, "visible");
336 if (!PyArg_ParseTuple(args, ":visible"))
337 return NULL;
338 return PyInt_FromLong(!!self->client->frame->visible);
339 }
340
341 static PyObject *cwrap_setVisible(ClientWrap *self, PyObject *args)
342 {
343 int show;
344
345 CHECK_CWRAP(self, "setVisible");
346 if (!PyArg_ParseTuple(args, "i:setVisible", &show))
347 return NULL;
348 if (show)
349 engine_frame_show(self->client->frame);
350 else
351 engine_frame_hide(self->client->frame);
352 Py_INCREF(Py_None);
353 return Py_None;
354 }
355
356 static PyObject *cwrap_modal(ClientWrap *self, PyObject *args)
357 {
358 CHECK_CWRAP(self, "modal");
359 if (!PyArg_ParseTuple(args, ":modal"))
360 return NULL;
361 return PyInt_FromLong(!!self->client->modal);
362 }
363
364 static PyObject *cwrap_setModal(ClientWrap *self, PyObject *args)
365 {
366 int modal;
367
368 CHECK_CWRAP(self, "setModal");
369 if (!PyArg_ParseTuple(args, "i:setModal", &modal))
370 return NULL;
371
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);
376
377 Py_INCREF(Py_None);
378 return Py_None;
379 }
380
381 static PyObject *cwrap_shaded(ClientWrap *self, PyObject *args)
382 {
383 CHECK_CWRAP(self, "shaded");
384 if (!PyArg_ParseTuple(args, ":shaded"))
385 return NULL;
386 return PyInt_FromLong(!!self->client->shaded);
387 }
388
389 static PyObject *cwrap_setShaded(ClientWrap *self, PyObject *args)
390 {
391 int shaded;
392
393 CHECK_CWRAP(self, "setShaded");
394 if (!PyArg_ParseTuple(args, "i:setShaded", &shaded))
395 return NULL;
396
397 client_shade(self->client, shaded);
398
399 Py_INCREF(Py_None);
400 return Py_None;
401 }
402
403 static PyObject *cwrap_iconic(ClientWrap *self, PyObject *args)
404 {
405 CHECK_CWRAP(self, "iconic");
406 if (!PyArg_ParseTuple(args, ":iconic"))
407 return NULL;
408 return PyInt_FromLong(!!self->client->iconic);
409 }
410
411 static PyObject *cwrap_setIconic(ClientWrap *self, PyObject *args)
412 {
413 int iconify, current = TRUE;
414
415 CHECK_CWRAP(self, "setIconic");
416 if (!PyArg_ParseTuple(args, "i|i:setIconic", &iconify, &current))
417 return NULL;
418
419 client_iconify(self->client, iconify, current);
420
421 Py_INCREF(Py_None);
422 return Py_None;
423 }
424
425 static PyObject *cwrap_maximizedHorz(ClientWrap *self, PyObject *args)
426 {
427 CHECK_CWRAP(self, "maximizedHorz");
428 if (!PyArg_ParseTuple(args, ":maximizedHorz"))
429 return NULL;
430 return PyInt_FromLong(!!self->client->max_horz);
431 }
432
433 static PyObject *cwrap_setMaximizedHorz(ClientWrap *self, PyObject *args)
434 {
435 int max;
436
437 CHECK_CWRAP(self, "setMaximizedHorz");
438 if (!PyArg_ParseTuple(args, "i:setMaximizedHorz", &max))
439 return NULL;
440
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);
445
446 Py_INCREF(Py_None);
447 return Py_None;
448 }
449
450 static PyObject *cwrap_maximizedVert(ClientWrap *self, PyObject *args)
451 {
452 CHECK_CWRAP(self, "maximizedVert");
453 if (!PyArg_ParseTuple(args, ":maximizedVert"))
454 return NULL;
455 return PyInt_FromLong(!!self->client->max_vert);
456 }
457
458 static PyObject *cwrap_setMaximizedVert(ClientWrap *self, PyObject *args)
459 {
460 int max;
461
462 CHECK_CWRAP(self, "setMaximizedVert");
463 if (!PyArg_ParseTuple(args, "i:setMaximizedVert", &max))
464 return NULL;
465
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);
470
471 Py_INCREF(Py_None);
472 return Py_None;
473 }
474
475 static PyObject *cwrap_maximized(ClientWrap *self, PyObject *args)
476 {
477 CHECK_CWRAP(self, "maximized");
478 if (!PyArg_ParseTuple(args, ":maximized"))
479 return NULL;
480 return PyInt_FromLong(self->client->max_vert || self->client->max_horz);
481 }
482
483 static PyObject *cwrap_setMaximized(ClientWrap *self, PyObject *args)
484 {
485 int max;
486
487 CHECK_CWRAP(self, "setMaximized");
488 if (!PyArg_ParseTuple(args, "i:setMaximized", &max))
489 return NULL;
490
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);
496
497 Py_INCREF(Py_None);
498 return Py_None;
499 }
500
501 static PyObject *cwrap_fullscreen(ClientWrap *self, PyObject *args)
502 {
503 CHECK_CWRAP(self, "fullscreen");
504 if (!PyArg_ParseTuple(args, ":fullscreen"))
505 return NULL;
506 return PyInt_FromLong(!!self->client->fullscreen);
507 }
508
509 static PyObject *cwrap_setFullscreen(ClientWrap *self, PyObject *args)
510 {
511 int fs;
512
513 CHECK_CWRAP(self, "setFullscreen");
514 if (!PyArg_ParseTuple(args, "i:setFullscreen", &fs))
515 return NULL;
516
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);
521
522 Py_INCREF(Py_None);
523 return Py_None;
524 }
525
526 static PyObject *cwrap_stacking(ClientWrap *self, PyObject *args)
527 {
528 CHECK_CWRAP(self, "stacking");
529 if (!PyArg_ParseTuple(args, ":stacking"))
530 return NULL;
531 return PyInt_FromLong(self->client->above ? 1 :
532 self->client->below ? -1 : 0);
533 }
534
535 static PyObject *cwrap_setStacking(ClientWrap *self, PyObject *args)
536 {
537 int stack;
538
539 CHECK_CWRAP(self, "setStacking");
540 if (!PyArg_ParseTuple(args, "i:setStacking", &stack))
541 return NULL;
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);
550 Py_INCREF(Py_None);
551 return Py_None;
552 }
553
554 static PyObject *cwrap_raiseWindow(ClientWrap *self, PyObject *args)
555 {
556 CHECK_CWRAP(self, "raiseWindow");
557 if (!PyArg_ParseTuple(args, ":raiseWindow"))
558 return NULL;
559 stacking_raise(self->client);
560 Py_INCREF(Py_None);
561 return Py_None;
562 }
563
564 static PyObject *cwrap_lowerWindow(ClientWrap *self, PyObject *args)
565 {
566 CHECK_CWRAP(self, "lowerWindow");
567 if (!PyArg_ParseTuple(args, ":lowerWindow"))
568 return NULL;
569 stacking_lower(self->client);
570 Py_INCREF(Py_None);
571 return Py_None;
572 }
573
574 static PyObject *cwrap_skipPager(ClientWrap *self, PyObject *args)
575 {
576 CHECK_CWRAP(self, "skipPager");
577 if (!PyArg_ParseTuple(args, ":skipPager"))
578 return NULL;
579 return PyInt_FromLong(!!self->client->skip_pager);
580 }
581
582 static PyObject *cwrap_setSkipPager(ClientWrap *self, PyObject *args)
583 {
584 int skip;
585
586 CHECK_CWRAP(self, "setSkipPager");
587 if (!PyArg_ParseTuple(args, "i:setSkipPager", &skip))
588 return NULL;
589
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);
594
595 Py_INCREF(Py_None);
596 return Py_None;
597 }
598
599 static PyObject *cwrap_skipTaskbar(ClientWrap *self, PyObject *args)
600 {
601 CHECK_CWRAP(self, "skipTaskbar");
602 if (!PyArg_ParseTuple(args, ":skipTaskbar"))
603 return NULL;
604 return PyInt_FromLong(!!self->client->skip_taskbar);
605 }
606
607 static PyObject *cwrap_setSkipTaskbar(ClientWrap *self, PyObject *args)
608 {
609 int skip;
610
611 CHECK_CWRAP(self, "setSkipTaskbar");
612 if (!PyArg_ParseTuple(args, "i:setSkipTaskbar", &skip))
613 return NULL;
614
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);
619
620 Py_INCREF(Py_None);
621 return Py_None;
622 }
623
624 static PyObject *cwrap_disableDecorations(ClientWrap *self, PyObject *args)
625 {
626 int title, handle, border;
627
628 CHECK_CWRAP(self, "disableDecorations");
629 if (!PyArg_ParseTuple(args, "iii:disableDecorations", &title, &handle,
630 &border))
631 return NULL;
632
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);
638
639 Py_INCREF(Py_None);
640 return Py_None;
641 }
642
643 static PyObject *cwrap_close(ClientWrap *self, PyObject *args)
644 {
645 CHECK_CWRAP(self, "close");
646 if (!PyArg_ParseTuple(args, ":close"))
647 return NULL;
648 client_close(self->client);
649 Py_INCREF(Py_None);
650 return Py_None;
651 }
652
653 static PyObject *cwrap_window(ClientWrap *self, PyObject *args)
654 {
655 CHECK_CWRAP(self, "window");
656 if (!PyArg_ParseTuple(args, ":window"))
657 return NULL;
658 return PyInt_FromLong(self->client->window);
659 }
660
661 #define METH(n, d) {#n, (PyCFunction)cwrap_##n, METH_VARARGS, #d}
662
663 static PyMethodDef ClientWrapMethods[] = {
664 METH(valid,
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."),
668 METH(title,
669 "Returns the client's title."),
670 METH(setTitle,
671 "Change the client's title to the given string. This change will be "
672 "overwritten if/when the client changes its title."),
673 METH(iconTitle,
674 "Returns's the client's icon title. The icon title is the title to "
675 "be displayed when the client is iconified."),
676 METH(setIconTitle,
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."),
679 METH(desktop,
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 "
683 "on all desktops."),
684 METH(setDesktop,
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 "
688 "desktops."),
689 METH(resName,
690 "Returns the resouce name of the client. The resource name is meant "
691 "to provide an instance name for the client."),
692 METH(resClass,
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."),
696 METH(role,
697 "Returns the client's role. The role is meant to distinguish between "
698 "different windows of an application. Each window should have a "
699 "unique role."),
700 METH(transient,
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()."),
705 METH(transientFor,
706 "Returns the client for which this client is a transient. See "
707 "transient() for a description of transience."),
708 METH(transients,
709 "Returns a tuple containing all the Clients which are transients of "
710 "this window. See transient() for a description of transience."),
711 METH(type,
712 "Returns the logical type of the window. This is one of the "
713 "ClientType constants. See also normal()."),
714 METH(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."),
722 METH(area,
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 "
727 "logicalSize()."),
728
729 METH(setArea,
730 "Sets the client's area, moving and resizing it as specified (or as "
731 "close as can be accomidated)."),
732 METH(clientArea,
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()."),
737 METH(setClientArea,
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."),
745 METH(strut,
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 "
748 "of the screen."),
749 METH(frameSize,
750 "Returns the size of the decorations around the client window."),
751 METH(logicalSize,
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."),
757 METH(canFocus,
758 "Returns True or False for if the client can be focused."),
759 METH(focus,
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."),
766 METH(focused,
767 "Returns True or False for if the client has the input focus."),
768 METH(visible,
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."),
771 METH(setVisible,
772 "Shows or hides the client. This has no effect if its current "
773 "visible() state is requested."),
774 METH(modal,
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."),
779 METH(setModal,
780 "Make the client window modal or non-modal."),
781 METH(shaded,
782 "Returns True or False for if the client is shaded. Shaded windows "
783 "have only their titlebar decorations showing."),
784 METH(setShaded,
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."),
788 METH(iconic,
789 "Returns True or False for if the window is iconified. Iconified "
790 "windows are not visible on any desktops."),
791 METH(setIconic,
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."),
795 METH(maximizedHorz,
796 "Returns whether the client is maximized in the horizontal "
797 "direction."),
798 METH(setMaximizedHorz,
799 "Maximizes or restores a client horizontally."),
800 METH(maximizedVert,
801 "Returns whether the client is maximized in the vertical direction."),
802 METH(setMaximizedVert,
803 "Maximizes or restores a client vertically."),
804 METH(maximized,
805 "Returns whether the client is maximized in the horizontal or "
806 "vertical direction."),
807 METH(setMaximized,
808 "Maximizes or restores a client vertically and horzontally."),
809 METH(fullscreen,
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."),
813 METH(setFullscreen,
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."),
817 METH(stacking,
818 "Returns if the client will be stacked above/below other clients in "
819 "the same layer."),
820 METH(setStacking,
821 "Set how the client will be stacked according to other clients in "
822 "its layer."),
823 METH(raiseWindow,
824 "Raises the window to the top of its stacking layer."),
825 METH(lowerWindow,
826 "Lowers the window to the bottom of its stacking layer."),
827 METH(skipPager,
828 "Returns if the client has requested to be skipped (not displayed) "
829 "by pagers."),
830 METH(setSkipPager,
831 "Set whether the client should be skipped (not displayed) by "
832 "pagers."),
833 METH(skipTaskbar,
834 "Returns if the client has requested to be skipped (not displayed) "
835 "by taskbars."),
836 METH(setSkipTaskbar,
837 "Set whether the client should be skipped (not displayed) by "
838 "taskbars."),
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."),
844 METH(close,
845 "Requests the client to close its window."),
846 METH(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 }
850 };
851
852 /***************************************************************************
853
854 Type methods/struct
855
856 ***************************************************************************/
857
858 /*static PyObject *cwrap_getattr(ClientWrap *self, char *name)
859 {
860 CHECK_CWRAP(self, "getattr");
861 return Py_FindMethod(ClientWrapAttributeMethods, (PyObject*)self, name);
862 }*/
863
864 static void cwrap_dealloc(ClientWrap *self)
865 {
866 if (self->client != NULL)
867 self->client->wrap = NULL;
868 PyObject_Del((PyObject*) self);
869 }
870
871 static PyObject *cwrap_repr(ClientWrap *self)
872 {
873 CHECK_CWRAP(self, "repr");
874 return PyString_FromFormat("Client: 0x%x", (guint)self->client->window);
875 }
876
877 static int cwrap_compare(ClientWrap *self, ClientWrap *other)
878 {
879 Window w1, w2;
880 if (!IS_VALID_CWRAP(self)) {
881 PyErr_SetString(PyExc_ValueError,
882 "This 'Client' is wrapping a client which no longer "
883 "exists.");
884 }
885
886 w1 = self->client->window;
887 w2 = other->client->window;
888 return w1 > w2 ? 1 : w1 < w2 ? -1 : 0;
889 }
890
891 static PyTypeObject ClientWrapType = {
892 PyObject_HEAD_INIT(NULL)
893 0,
894 "Client",
895 sizeof(ClientWrap),
896 0,
897 (destructor) cwrap_dealloc, /*tp_dealloc*/
898 0, /*tp_print*/
899 0, /*tp_getattr*/
900 0, /*tp_setattr*/
901 (cmpfunc) cwrap_compare, /*tp_compare*/
902 (reprfunc) cwrap_repr, /*tp_repr*/
903 0, /*tp_as_number*/
904 0, /*tp_as_sequence*/
905 0, /*tp_as_mapping*/
906 0, /*tp_hash */
907 };
908
909
910 /***************************************************************************
911
912 Define the type 'ClientType'
913
914 ***************************************************************************/
915
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' " \
921 "object"); \
922 return NULL; \
923 } \
924 }
925
926 staticforward PyTypeObject ClientTypeType;
927
928 typedef struct ClientType {
929 PyObject_HEAD
930 } ClientType;
931
932 static void ctype_dealloc(PyObject *self)
933 {
934 PyObject_Del(self);
935 }
936
937 static PyObject *ctype_getattr(ClientType *self, char *name)
938 {
939 struct S { char *name; int val; };
940 struct S s[] = {
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 },
949 { NULL, 0 } };
950 int i;
951
952 CHECK_CTYPE(self, "__getattr__");
953
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");
958 return NULL;
959 }
960
961 static PyTypeObject ClientTypeType = {
962 PyObject_HEAD_INIT(NULL)
963 0,
964 "Type",
965 sizeof(ClientType),
966 0,
967 (destructor) ctype_dealloc, /*tp_dealloc*/
968 0, /*tp_print*/
969 (getattrfunc) ctype_getattr, /*tp_getattr*/
970 0, /*tp_setattr*/
971 0, /*tp_compare*/
972 0, /*tp_repr*/
973 0, /*tp_as_number*/
974 0, /*tp_as_sequence*/
975 0, /*tp_as_mapping*/
976 0, /*tp_hash */
977 };
978
979 /***************************************************************************
980
981 External methods
982
983 ***************************************************************************/
984
985 void clientwrap_startup()
986 {
987 PyObject *ob, *obdict, *type;
988
989 ClientWrapType.ob_type = &PyType_Type;
990 ClientWrapType.tp_methods = ClientWrapMethods;
991 PyType_Ready(&ClientWrapType);
992
993 ClientTypeType.ob_type = &PyType_Type;
994 PyType_Ready(&ClientTypeType);
995
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);
1001
1002 /* add the Client type to the ob module */
1003 PyDict_SetItemString(obdict, "Client", (PyObject*) &ClientWrapType);
1004
1005 /* add an instance of ClientType */
1006 type = (PyObject*) PyObject_New(ClientType, &ClientTypeType);
1007 PyDict_SetItemString(obdict, "ClientType", type);
1008 Py_DECREF(type);
1009
1010 Py_DECREF(ob);
1011 }
1012
1013 void clientwrap_shutdown()
1014 {
1015 }
1016
1017 PyObject *clientwrap_new(Client *client)
1018 {
1019 g_assert(client != NULL);
1020
1021 if (client->wrap != NULL) {
1022 /* already has a wrapper! */
1023 Py_INCREF((PyObject*) client->wrap);
1024 } else {
1025 client->wrap = PyObject_New(ClientWrap, &ClientWrapType);
1026 client->wrap->client = client;
1027 }
1028 return (PyObject*) client->wrap;
1029 }
This page took 0.082105 seconds and 3 git commands to generate.