Consistency fixes
[notion.git] / ioncore / region.c
blob1b4353f922af1e637961986e5444ba780298d9ce
1 /*
2 * ion/ioncore/region.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
11 #include <X11/Xatom.h>
13 #include <libtu/objp.h>
14 #include <libextl/extl.h>
15 #include <libmainloop/defer.h>
17 #include "property.h"
18 #include "common.h"
19 #include "global.h"
20 #include "region.h"
21 #include "focus.h"
22 #include "regbind.h"
23 #include "names.h"
24 #include "resize.h"
25 #include "manage.h"
26 #include "extlconv.h"
27 #include "activity.h"
28 #include "region-iter.h"
29 #include "return.h"
30 #include "key.h"
31 #include "log.h"
32 #include "screen-notify.h"
34 #define D2(X)
37 WHook *region_notify_hook=NULL;
40 static void region_notify_change_(WRegion *reg, WRegionNotify how);
43 /*{{{ Init & deinit */
46 void region_init(WRegion *reg, WWindow *par, const WFitParams *fp)
48 if(fp->g.w<0 || fp->g.h<0)
49 warn(TR("Creating region with negative width or height!"));
51 reg->geom=fp->g;
52 reg->flags=0;
53 reg->bindings=NULL;
54 reg->rootwin=NULL;
56 reg->children=NULL;
57 reg->parent=NULL;
58 reg->p_next=NULL;
59 reg->p_prev=NULL;
61 reg->active_sub=NULL;
62 reg->active_prev=NULL;
63 reg->active_next=NULL;
65 reg->ni.name=NULL;
66 reg->ni.inst_off=0;
67 reg->ni.node=NULL;
69 reg->manager=NULL;
71 reg->submapstat=NULL;
73 reg->mgd_activity=FALSE;
75 if(par!=NULL){
76 reg->rootwin=((WRegion*)par)->rootwin;
77 region_set_parent(reg, par);
78 }else{
79 assert(OBJ_IS(reg, WRootWin));
84 static void destroy_children(WRegion *reg)
86 WRegion *sub, *prev=NULL;
87 bool complained=FALSE;
89 /* destroy children */
90 while(1){
91 sub=reg->children;
92 if(sub==NULL)
93 break;
94 assert(!OBJ_IS_BEING_DESTROYED(sub));
95 assert(sub!=prev);
96 if(ioncore_g.opmode!=IONCORE_OPMODE_DEINIT && !complained && OBJ_IS(reg, WClientWin)){
97 warn(TR("Destroying object \"%s\" with client windows as "
98 "children."), region_name(reg));
99 complained=TRUE;
101 prev=sub;
102 destroy_obj((Obj*)sub);
107 void region_deinit(WRegion *reg)
109 region_notify_change(reg, ioncore_g.notifies.deinit);
111 destroy_children(reg);
113 if(ioncore_g.focus_next==reg){
114 D(warn("Region to be focused next destroyed[1]."));
115 ioncore_g.focus_next=NULL;
118 assert(reg->submapstat==NULL);
119 /*region_free_submapstat(reg);*/
120 region_detach_manager(reg);
121 region_unset_return(reg);
122 region_unset_parent(reg);
123 region_remove_bindings(reg);
125 region_unregister(reg);
127 region_focus_deinit(reg);
129 if(ioncore_g.focus_next==reg){
130 D(warn("Region to be focused next destroyed[2]."));
131 ioncore_g.focus_next=NULL;
136 /*}}}*/
139 /*{{{ Dynfuns */
142 bool region_fitrep(WRegion *reg, WWindow *par, const WFitParams *fp)
144 bool ret=FALSE;
145 CALL_DYN_RET(ret, bool, region_fitrep, reg, (reg, par, fp));
146 return ret;
150 void region_updategr(WRegion *reg)
152 CALL_DYN(region_updategr, reg, (reg));
156 void region_map(WRegion *reg)
158 CALL_DYN(region_map, reg, (reg));
159 region_notify_change_(reg, ioncore_g.notifies.map);
163 void region_unmap(WRegion *reg)
165 CALL_DYN(region_unmap, reg, (reg));
166 region_notify_change_(reg, ioncore_g.notifies.unmap);
170 void region_notify_rootpos(WRegion *reg, int x, int y)
172 CALL_DYN(region_notify_rootpos, reg, (reg, x, y));
176 Window region_xwindow(const WRegion *reg)
178 Window ret=None;
179 CALL_DYN_RET(ret, Window, region_xwindow, reg, (reg));
180 return ret;
184 void region_activated(WRegion *reg)
186 CALL_DYN(region_activated, reg, (reg));
190 void region_inactivated(WRegion *reg)
192 CALL_DYN(region_inactivated, reg, (reg));
196 void region_do_set_focus(WRegion *reg, bool warp)
198 CALL_DYN(region_do_set_focus, reg, (reg, warp));
202 /*{{{ Manager region dynfuns */
205 static bool region_managed_prepare_focus_default(WRegion *mgr, WRegion *reg,
206 int flags,
207 WPrepareFocusResult *res)
209 if(!region_prepare_focus(mgr, flags, res))
210 return FALSE;
212 res->reg=reg;
213 res->flags=flags;
214 return TRUE;
218 bool region_managed_prepare_focus(WRegion *mgr, WRegion *reg,
219 int flags,
220 WPrepareFocusResult *res)
222 bool ret=TRUE;
223 CALL_DYN_RET(ret, bool, region_managed_prepare_focus, mgr,
224 (mgr, reg, flags, res));
225 return ret;
229 void region_managed_notify(WRegion *mgr, WRegion *reg, WRegionNotify how)
231 CALL_DYN(region_managed_notify, mgr, (mgr, reg, how));
235 void region_managed_remove(WRegion *mgr, WRegion *reg)
237 CALL_DYN(region_managed_remove, mgr, (mgr, reg));
241 /*EXTL_DOC
242 * Return the object, if any, that is considered ``currently active''
243 * within the objects managed by \var{mplex}.
245 EXTL_SAFE
246 EXTL_EXPORT_MEMBER
247 WRegion *region_current(WRegion *mgr)
249 WRegion *ret=NULL;
250 CALL_DYN_RET(ret, WRegion*, region_current, mgr, (mgr));
251 return ret;
255 void region_child_removed(WRegion *reg, WRegion *sub)
257 CALL_DYN(region_child_removed, reg, (reg, sub));
261 /*}}}*/
264 /*{{{ Dynfun defaults */
267 void region_updategr_default(WRegion *reg)
269 WRegion *sub=NULL;
271 FOR_ALL_CHILDREN(reg, sub){
272 region_updategr(sub);
277 /*}}}*/
280 /*}}}*/
283 /*{{{ Goto */
286 bool region_prepare_focus(WRegion *reg, int flags,
287 WPrepareFocusResult *res)
290 if(TRUE /* !REGION_IS_ACTIVE(reg) ||
291 !REGION_IS_MAPPED(reg) ||
292 ioncore_g.focus_next!=NULL*/){
293 WRegion *mgr=REGION_MANAGER(reg);
294 WRegion *par=REGION_PARENT_REG(reg);
296 if(mgr!=NULL){
297 return region_managed_prepare_focus(mgr, reg, flags, res);
298 }else if(par!=NULL){
299 if(!region_prepare_focus(par, flags, res))
300 return FALSE;
301 /* Just focus reg, if it has no manager, and parent can be
302 * focused.
304 }else if(!REGION_IS_MAPPED(reg)){
305 region_map(reg);
309 res->reg=reg;
310 res->flags=flags;
311 return TRUE;
315 bool region_goto_flags(WRegion *reg, int flags)
317 WPrepareFocusResult res;
318 bool ret;
320 ret=region_prepare_focus(reg, flags, &res);
322 if(res.reg!=NULL){
323 if(res.flags&REGION_GOTO_FOCUS)
324 region_maybewarp(res.reg, !(res.flags&REGION_GOTO_NOWARP));
327 return ret;
331 /*EXTL_DOC
332 * Attempt to display \var{reg}, save region activity status and then
333 * warp to (or simply set focus to if warping is disabled) \var{reg}.
335 * Note that this function is asynchronous; the region will not
336 * actually have received the focus when this function returns.
338 EXTL_EXPORT_MEMBER
339 bool region_goto_focus(WRegion *reg)
341 return region_goto_flags(reg, REGION_GOTO_FOCUS);
344 /*EXTL_DOC
345 * Deprecated in favour of \fnref{WRegion.goto_focus} because 'goto' is a
346 * keyword since Lua 5.2.
348 EXTL_EXPORT_MEMBER
349 bool region_goto(WRegion *reg)
351 return region_goto_focus(reg);
355 * Kept for backwards compatibility
357 EXTL_EXPORT_MEMBER
358 bool region_goto_(WRegion *reg)
360 return region_goto_focus(reg);
364 * Kept for backwards compatibility
366 EXTL_EXPORT_MEMBER
367 bool region_display(WRegion *reg)
369 return region_goto_focus(reg);
373 /*}}}*/
376 /*{{{ Fit/reparent */
379 void region_fit(WRegion *reg, const WRectangle *geom, WRegionFitMode mode)
381 WFitParams fp;
382 fp.g=*geom;
383 fp.mode=mode&~REGION_FIT_GRAVITY;
384 fp.gravity=ForgetGravity;
385 region_fitrep(reg, NULL, &fp);
389 bool region_reparent(WRegion *reg, WWindow *par,
390 const WRectangle *geom, WRegionFitMode mode)
392 WFitParams fp;
393 fp.g=*geom;
394 fp.mode=mode;
395 return region_fitrep(reg, par, &fp);
399 /*}}}*/
402 /*{{{ Close */
405 static void region_rqclose_default(WRegion *reg, bool relocate)
407 if(relocate || region_may_dispose(reg))
408 region_defer_rqdispose(reg);
412 /*EXTL_DOC
413 * Attempt to close/destroy \var{reg}. Whether this operation works
414 * depends on whether the particular type of region in question has
415 * implemented the feature and, in case of client windows, whether
416 * the client supports the \code{WM_DELETE} protocol (see also
417 * \fnref{WClientWin.kill}). The region will not be destroyed when
418 * this function returns. To find out if and when it is destroyed,
419 * use the \codestr{deinit} notification. If \var{relocate} is not set,
420 * and \var{reg} manages other regions, it will not be closed. Otherwise
421 * the managed regions will be attempted to be relocated.
423 EXTL_EXPORT_MEMBER
424 void region_rqclose(WRegion *reg, bool relocate)
426 CALL_DYN(region_rqclose, reg, (reg, relocate));
430 static WRegion *region_rqclose_propagate_default(WRegion *reg,
431 WRegion *maybe_sub)
433 if(maybe_sub==NULL)
434 maybe_sub=region_current(reg);
436 if(maybe_sub!=NULL){
437 return region_rqclose_propagate(maybe_sub, NULL);
438 }else{
439 region_rqclose(reg, FALSE);
440 return reg;
445 /*EXTL_DOC
446 * Recursively attempt to close a region or one of the regions managed by
447 * it. If \var{sub} is set, it will be used as the managed region, otherwise
448 * \fnref{WRegion.current}\code{(reg)}. The object to be closed is
449 * returned, or NULL if nothing can be closed. For further details, see
450 * notes for \fnref{WRegion.rqclose}.
452 EXTL_EXPORT_MEMBER
453 WRegion *region_rqclose_propagate(WRegion *reg, WRegion *maybe_sub)
455 WRegion *ret=NULL;
456 CALL_DYN_RET(ret, WRegion*, region_rqclose_propagate, reg,
457 (reg, maybe_sub));
458 return ret;
462 bool region_may_dispose_default(WRegion *reg)
464 bool res=region_rescue_needed(reg);
466 if(res){
467 const char *name=region_name(reg);
468 warn(TR("Can not destroy %s: contains client windows."),
469 (name!=NULL ? name : TR("(unknown)")));
472 return !res;
476 bool region_may_dispose(WRegion *reg)
478 bool ret=TRUE;
479 CALL_DYN_RET(ret, bool, region_may_dispose, reg, (reg));
480 return ret;
484 static WRegion *region_managed_disposeroot_default(WRegion *UNUSED(mgr), WRegion *reg)
486 return reg;
490 WRegion *region_managed_disposeroot(WRegion *mgr, WRegion *reg)
492 WRegion *ret=NULL;
493 CALL_DYN_RET(ret, WRegion*, region_managed_disposeroot, mgr, (mgr, reg));
494 return ret;
498 WRegion *region_disposeroot(WRegion *reg)
500 WRegion *mgr=REGION_MANAGER(reg);
502 return (mgr!=NULL
503 ? region_managed_disposeroot(mgr, reg)
504 : reg);
508 bool region_rqdispose(WRegion *reg)
510 WRegion *root;
512 if(!region_may_dispose(reg))
513 return FALSE;
515 root=region_disposeroot(reg);
517 if(root==NULL)
518 return FALSE;
520 return region_dispose(root);
524 bool region_dispose_(WRegion *reg, bool not_simple)
526 bool rescue=not_simple;
527 bool was_mcf=(not_simple && region_may_control_focus(reg));
528 WPHolder *ph=NULL;
530 if(rescue){
531 if(!region_rescue(reg, NULL, 0)){
532 warn(TR("Failed to rescue some client windows - not closing."));
533 return FALSE;
537 if(was_mcf)
538 ph=region_unset_get_return(reg);
540 destroy_obj((Obj*)reg);
542 if(ph!=NULL){
543 pholder_goto(ph);
544 destroy_obj((Obj*)ph);
547 return TRUE;
551 bool region_dispose(WRegion *reg)
553 return region_dispose_(reg, TRUE);
557 void region_defer_rqdispose(WRegion *reg)
559 mainloop_defer_action((Obj*)reg, (WDeferredAction*)region_rqdispose);
563 /*}}}*/
566 /*{{{ Manager/parent stuff */
569 /* Routine to call to unmanage a region */
570 void region_detach_manager(WRegion *reg)
572 WRegion *mgr=REGION_MANAGER(reg);
574 if(mgr==NULL)
575 return;
577 region_managed_remove(mgr, reg);
579 assert(REGION_MANAGER(reg)==NULL);
583 void region_unset_manager_pseudoactivity(WRegion *reg)
585 WRegion *mgr=reg->manager, *par=REGION_PARENT_REG(reg);
587 if(mgr==NULL || mgr==par || !REGION_IS_PSEUDOACTIVE(mgr))
588 return;
590 mgr->flags&=~REGION_PSEUDOACTIVE;
592 region_notify_change(mgr, ioncore_g.notifies.pseudoinactivated);
594 region_unset_manager_pseudoactivity(mgr);
598 void region_set_manager_pseudoactivity(WRegion *reg)
600 WRegion *mgr=reg->manager, *par=REGION_PARENT_REG(reg);
602 if(!REGION_IS_ACTIVE(reg) && !REGION_IS_PSEUDOACTIVE(reg))
603 return;
605 if(mgr==NULL || mgr==par || REGION_IS_PSEUDOACTIVE(mgr))
606 return;
608 mgr->flags|=REGION_PSEUDOACTIVE;
610 region_notify_change(mgr, ioncore_g.notifies.pseudoactivated);
612 region_set_manager_pseudoactivity(mgr);
616 /* This should only be called within region_managed_remove,
617 * _after_ any managed lists and other essential structures
618 * of mgr have been broken.
620 void region_unset_manager(WRegion *reg, WRegion *mgr)
622 if(reg->manager!=mgr)
623 return;
625 region_notify_change_(reg, ioncore_g.notifies.unset_manager);
627 region_unset_manager_pseudoactivity(reg);
629 reg->manager=NULL;
631 /* Reset status, as it is set by manager */
632 reg->flags&=~REGION_SKIP_FOCUS;
634 if(region_is_activity_r(reg))
635 region_clear_mgd_activity(mgr);
637 region_unset_return(reg);
641 /* This should be called within region attach routines,
642 * _after_ any managed lists and other essential structures
643 * of mgr have been set up.
645 void region_set_manager(WRegion *reg, WRegion *mgr)
647 assert(reg->manager==NULL);
649 reg->manager=mgr;
651 region_set_manager_pseudoactivity(reg);
653 if(region_is_activity_r(reg))
654 region_mark_mgd_activity(mgr);
656 region_notify_change_(reg, ioncore_g.notifies.set_manager);
660 void region_set_parent(WRegion *reg, WWindow *parent)
662 assert(reg->parent==NULL && parent!=NULL);
663 LINK_ITEM(((WRegion*)parent)->children, reg, p_next, p_prev);
664 reg->parent=parent;
668 void region_unset_parent(WRegion *reg)
670 WRegion *p=REGION_PARENT_REG(reg);
672 if(p==NULL || p==reg)
673 return;
675 UNLINK_ITEM(p->children, reg, p_next, p_prev);
676 reg->parent=NULL;
678 if(p->active_sub==reg){
679 p->active_sub=NULL;
680 region_update_owned_grabs(p);
683 region_child_removed(p, reg);
687 /*EXTL_DOC
688 * Returns the region that manages \var{reg}.
690 EXTL_SAFE
691 EXTL_EXPORT_MEMBER
692 WRegion *region_manager(WRegion *reg)
694 return reg->manager;
698 /*EXTL_DOC
699 * Returns the parent region of \var{reg}.
701 EXTL_SAFE
702 EXTL_EXPORT_MEMBER
703 WWindow *region_parent(WRegion *reg)
705 return reg->parent;
709 WRegion *region_manager_or_parent(WRegion *reg)
711 if(reg->manager!=NULL)
712 return reg->manager;
713 else
714 return (WRegion*)(reg->parent);
718 WRegion *region_get_manager_chk(WRegion *p, const ClassDescr *descr)
720 WRegion *mgr=NULL;
722 if(p!=NULL){
723 mgr=REGION_MANAGER(p);
724 if(obj_is((Obj*)mgr, descr))
725 return mgr;
728 return NULL;
731 /*}}}*/
734 /*{{{ Stacking and ordering */
737 static void region_stacking_default(WRegion *reg,
738 Window *bottomret, Window *topret)
740 Window win=region_xwindow(reg);
741 *bottomret=win;
742 *topret=win;
746 void region_stacking(WRegion *reg, Window *bottomret, Window *topret)
748 CALL_DYN(region_stacking, reg, (reg, bottomret, topret));
752 void region_restack(WRegion *reg, Window other, int mode)
754 CALL_DYN(region_restack, reg, (reg, other, mode));
759 bool region_managed_rqorder(WRegion *reg, WRegion *sub, WRegionOrder order)
761 bool ret=FALSE;
762 CALL_DYN_RET(ret, bool, region_managed_rqorder, reg, (reg, sub, order));
763 return ret;
767 bool region_rqorder(WRegion *reg, WRegionOrder order)
769 WRegion *mgr=REGION_MANAGER(reg);
771 if(mgr==NULL)
772 return FALSE;
773 else
774 return region_managed_rqorder(mgr, reg, order);
778 /*EXTL_DOC
779 * Request ordering. Currently supported values for \var{ord}
780 * are \codestr{front} and \codestr{back}.
782 EXTL_EXPORT_AS(WRegion, rqorder)
783 bool region_rqorder_extl(WRegion *reg, const char *ord)
785 WRegionOrder order;
787 if(strcmp(ord, "front")==0){
788 order=REGION_ORDER_FRONT;
789 }else if(strcmp(ord, "back")==0){
790 order=REGION_ORDER_BACK;
791 }else{
792 return FALSE;
795 return region_rqorder(reg, order);
799 /*}}}*/
802 /*{{{ Misc. */
805 /*EXTL_DOC
806 * Returns the root window \var{reg} is on.
808 EXTL_SAFE
809 EXTL_EXPORT_MEMBER
810 WRootWin *region_rootwin_of(const WRegion *reg)
812 WRootWin *rw;
813 assert(reg!=NULL); /* Lua interface should not pass NULL reg. */
814 rw=(WRootWin*)(reg->rootwin);
815 assert(rw!=NULL);
816 return rw;
820 /*EXTL_DOC
821 * Returns the screen \var{reg} is on.
823 EXTL_SAFE
824 EXTL_EXPORT_MEMBER
825 WScreen *region_screen_of(WRegion *reg)
827 while(reg!=NULL){
828 if(OBJ_IS(reg, WScreen))
829 return (WScreen*)reg;
830 reg=REGION_PARENT_REG(reg);
832 return NULL;
836 Window region_root_of(const WRegion *reg)
838 return WROOTWIN_ROOT(region_rootwin_of(reg));
842 bool region_same_rootwin(const WRegion *reg1, const WRegion *reg2)
844 return (reg1->rootwin==reg2->rootwin);
848 /*EXTL_DOC
849 * Is \var{reg} visible/is it and all it's ancestors mapped?
851 EXTL_SAFE
852 EXTL_EXPORT_AS(WRegion, is_mapped)
853 bool region_is_fully_mapped(WRegion *reg)
855 for(; reg!=NULL; reg=REGION_PARENT_REG(reg)){
856 if(!REGION_IS_MAPPED(reg))
857 return FALSE;
860 return TRUE;
864 void region_rootpos(WRegion *reg, int *xret, int *yret)
866 WRegion *par;
868 par=REGION_PARENT_REG(reg);
870 if(par==NULL || par==reg){
871 *xret=0;
872 *yret=0;
873 return;
876 region_rootpos(par, xret, yret);
878 *xret+=REGION_GEOM(reg).x;
879 *yret+=REGION_GEOM(reg).y;
883 typedef struct{
884 WRegion *reg;
885 WRegionNotify how;
886 } MRSHP;
889 static bool mrsh_notify_change(WHookDummy *fn, void *p_)
891 MRSHP *p=(MRSHP*)p_;
893 fn(p->reg, p->how);
895 return TRUE;
899 static bool mrshe_notify_change(ExtlFn fn, void *p_)
901 MRSHP *p=(MRSHP*)p_;
903 extl_call(fn, "os", NULL, p->reg, stringstore_get(p->how));
905 return TRUE;
909 static void region_notify_change_(WRegion *reg, WRegionNotify how)
911 MRSHP p;
913 p.reg=reg;
914 p.how=how;
916 extl_protect(NULL);
917 hook_call(region_notify_hook, &p, mrsh_notify_change, mrshe_notify_change),
918 extl_unprotect(NULL);
922 void region_notify_change(WRegion *reg, WRegionNotify how)
924 WRegion *mgr=REGION_MANAGER(reg);
926 if(mgr!=NULL)
927 region_managed_notify(mgr, reg, how);
929 region_notify_change_(reg, how);
933 /*EXTL_DOC
934 * Returns the geometry of \var{reg} within its parent; a table with fields
935 * \var{x}, \var{y}, \var{w} and \var{h}.
937 EXTL_SAFE
938 EXTL_EXPORT_MEMBER
939 ExtlTab region_geom(WRegion *reg)
941 return extl_table_from_rectangle(&REGION_GEOM(reg));
945 bool region_handle_drop(WRegion *reg, int x, int y, WRegion *dropped)
947 bool ret=FALSE;
948 CALL_DYN_RET(ret, bool, region_handle_drop, reg, (reg, x, y, dropped));
949 return ret;
953 WRegion *region_managed_within(WRegion *reg, WRegion *mgd)
955 while(mgd!=NULL &&
956 (REGION_PARENT_REG(mgd)==reg ||
957 REGION_PARENT_REG(mgd)==REGION_PARENT_REG(reg))){
959 if(REGION_MANAGER(mgd)==reg)
960 return mgd;
961 mgd=REGION_MANAGER(mgd);
964 return NULL;
967 void ioncore_region_notify(WRegion *reg, WRegionNotify how)
969 const char *p[1];
971 if(how==ioncore_g.notifies.name && obj_is((Obj*)reg, &CLASSDESCR(WWindow))){
972 p[0] = region_name(reg);
973 xwindow_set_text_property(((WWindow*)reg)->win, XA_WM_NAME, p, 1);
977 /*}}}*/
979 /*{{{ Debug printers */
981 #define REGION_DEBUGPRINT( what, next ) \
982 do { \
983 int indent = 1; \
984 char line_indent[24]; \
985 line_indent[0] = ' '; \
986 line_indent[1] = '\0'; \
988 LOG(DEBUG, GENERAL, what " list start ========:"); \
989 while( reg != NULL ) \
991 LOG(DEBUG, GENERAL, "%s%p (%s)", line_indent, (void*)reg, reg->ni.name); \
993 if( indent == sizeof(line_indent )-1 ) \
995 LOG(DEBUG, GENERAL, "too long. cut off"); \
996 break; \
999 reg = next; \
1000 line_indent[indent] = ' '; \
1001 indent++; \
1002 line_indent[indent] = '\0'; \
1004 LOG(DEBUG, GENERAL, what " list end =========="); \
1005 } while(0)
1007 void region_debugprint_parents ( const WRegion* reg )
1009 REGION_DEBUGPRINT( "parent", reg->parent && reg->parent->region.ni.name ? &reg->parent->region : NULL );
1012 void region_debugprint_managers( const WRegion* reg )
1014 REGION_DEBUGPRINT( "manager", reg->manager );
1017 #undef REGION_DEBUGPRINT
1019 /*}}}*/
1022 /*{{{ Dynamic function table and class implementation */
1025 static DynFunTab region_dynfuntab[]={
1026 {region_managed_rqgeom,
1027 region_managed_rqgeom_allow},
1029 {region_managed_rqgeom_absolute,
1030 region_managed_rqgeom_absolute_default},
1032 {region_updategr,
1033 region_updategr_default},
1035 {(DynFun*)region_rescue_clientwins,
1036 (DynFun*)region_rescue_child_clientwins},
1038 {(DynFun*)region_may_dispose,
1039 (DynFun*)region_may_dispose_default},
1041 {(DynFun*)region_prepare_manage,
1042 (DynFun*)region_prepare_manage_default},
1044 {(DynFun*)region_prepare_manage_transient,
1045 (DynFun*)region_prepare_manage_transient_default},
1047 {(DynFun*)region_managed_prepare_focus,
1048 (DynFun*)region_managed_prepare_focus_default},
1050 {(DynFun*)region_managed_disposeroot,
1051 (DynFun*)region_managed_disposeroot_default},
1053 {(DynFun*)region_rqclose_propagate,
1054 (DynFun*)region_rqclose_propagate_default},
1056 {(DynFun*)region_rqclose,
1057 (DynFun*)region_rqclose_default},
1059 {(DynFun*)region_displayname,
1060 (DynFun*)region_name},
1062 {region_stacking,
1063 region_stacking_default},
1065 END_DYNFUNTAB
1069 EXTL_EXPORT
1070 IMPLCLASS(WRegion, Obj, region_deinit, region_dynfuntab);
1073 /*}}}*/