2 * ion/mod_statusbar/statusbar.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
12 #include <libtu/objp.h>
13 #include <libtu/minmax.h>
14 #include <libtu/ptrlist.h>
15 #include <libtu/misc.h>
16 #include <ioncore/common.h>
17 #include <ioncore/global.h>
18 #include <ioncore/window.h>
19 #include <ioncore/binding.h>
20 #include <ioncore/regbind.h>
21 #include <ioncore/event.h>
22 #include <ioncore/resize.h>
23 #include <ioncore/gr.h>
24 #include <ioncore/gr-util.h>
25 #include <ioncore/names.h>
26 #include <ioncore/strings.h>
27 #include <ioncore/basicpholder.h>
28 #include <ioncore/sizehint.h>
30 #include "statusbar.h"
35 static void statusbar_set_elems(WStatusBar
*sb
, ExtlTab t
);
36 static void statusbar_free_elems(WStatusBar
*sb
);
37 static void statusbar_arrange_systray(WStatusBar
*p
);
38 static void statusbar_rearrange(WStatusBar
*sb
, bool rs
);
39 static void do_calc_systray_w(WStatusBar
*p
, WSBElem
*el
);
40 static void statusbar_calc_systray_w(WStatusBar
*p
);
42 static WStatusBar
*statusbars
=NULL
;
48 bool statusbar_init(WStatusBar
*p
, WWindow
*parent
, const WFitParams
*fp
)
50 if(!window_init(&(p
->wwin
), parent
, fp
, "WStatusBar"))
62 p
->systray_enabled
=TRUE
;
64 statusbar_updategr(p
);
67 window_deinit(&(p
->wwin
));
71 window_select_input(&(p
->wwin
), IONCORE_EVENTMASK_CWINMGR
);
73 region_register((WRegion
*)p
);
75 region_add_bindmap((WRegion
*)p
, mod_statusbar_statusbar_bindmap
);
77 LINK_ITEM(statusbars
, p
, sb_next
, sb_prev
);
84 WStatusBar
*create_statusbar(WWindow
*parent
, const WFitParams
*fp
)
86 CREATEOBJ_IMPL(WStatusBar
, statusbar
, (p
, parent
, fp
));
90 void statusbar_deinit(WStatusBar
*p
)
92 UNLINK_ITEM(statusbars
, p
, sb_next
, sb_prev
);
94 statusbar_free_elems(p
);
97 grbrush_release(p
->brush
);
101 window_deinit(&(p
->wwin
));
108 /*{{{ Content stuff */
111 static void init_sbelem(WSBElem
*el
)
113 el
->type
=WSBELEM_NONE
;
118 el
->meter
=STRINGID_NONE
;
119 el
->attr
=STRINGID_NONE
;
121 el
->align
=WSBELEM_ALIGN_CENTER
;
128 static bool gets_stringstore(ExtlTab t
, const char *str
, StringId
*id
)
132 if(extl_table_gets_s(t
, str
, &s
)){
133 *id
=stringstore_alloc(s
);
135 return (*id
!=STRINGID_NONE
);
142 static WSBElem
*get_sbelems(ExtlTab t
, int *nret
, int *filleridxret
)
144 int i
, n
=extl_table_get_n(t
);
154 el
=ALLOC_N(WSBElem
, n
);
164 if(extl_table_geti_t(t
, i
+1, &tt
)){
165 if(extl_table_gets_i(tt
, "type", &(el
[i
].type
))){
166 if(el
[i
].type
==WSBELEM_TEXT
|| el
[i
].type
==WSBELEM_STRETCH
){
167 extl_table_gets_s(tt
, "text", &(el
[i
].text
));
168 }else if(el
[i
].type
==WSBELEM_METER
){
169 gets_stringstore(tt
, "meter", &(el
[i
].meter
));
170 extl_table_gets_s(tt
, "tmpl", &(el
[i
].tmpl
));
171 extl_table_gets_i(tt
, "align", &(el
[i
].align
));
172 extl_table_gets_i(tt
, "zeropad", &(el
[i
].zeropad
));
173 el
[i
].zeropad
=MAXOF(el
[i
].zeropad
, 0);
174 }else if(el
[i
].type
==WSBELEM_SYSTRAY
){
177 gets_stringstore(tt
, "meter", &(el
[i
].meter
));
178 extl_table_gets_i(tt
, "align", &(el
[i
].align
));
180 tmp
=stringstore_get(el
[i
].meter
);
182 if(tmp
==NULL
|| strcmp(tmp
, "systray")==0)
184 }else if(el
[i
].type
==WSBELEM_FILLER
){
188 extl_unref_table(tt
);
193 WSBElem
*el2
=REALLOC_N(el
, WSBElem
, n
, n
+1);
197 el
[n
].type
=WSBELEM_SYSTRAY
;
208 static void free_sbelems(WSBElem
*el
, int n
)
217 if(el
[i
].meter
!=STRINGID_NONE
)
218 stringstore_free(el
[i
].meter
);
219 if(el
[i
].attr
!=STRINGID_NONE
)
220 stringstore_free(el
[i
].attr
);
221 if(el
[i
].traywins
!=NULL
)
222 ptrlist_clear(&el
[i
].traywins
);
229 static void statusbar_set_elems(WStatusBar
*sb
, ExtlTab t
)
231 statusbar_free_elems(sb
);
233 sb
->elems
=get_sbelems(t
, &(sb
->nelems
), &(sb
->filleridx
));
237 static void statusbar_free_elems(WStatusBar
*sb
)
240 free_sbelems(sb
->elems
, sb
->nelems
);
255 static void statusbar_resize(WStatusBar
*p
)
257 WRQGeomParams rq
=RQGEOMPARAMS_INIT
;
259 rq
.flags
=REGION_RQGEOM_WEAK_X
|REGION_RQGEOM_WEAK_Y
;
261 rq
.geom
.w
=p
->natural_w
;
262 rq
.geom
.h
=p
->natural_h
;
263 rq
.geom
.x
=REGION_GEOM(p
).x
;
264 rq
.geom
.y
=REGION_GEOM(p
).y
;
266 if(rectangle_compare(&rq
.geom
, ®ION_GEOM(p
))!=RECTANGLE_SAME
)
267 region_rqgeom((WRegion
*)p
, &rq
, NULL
);
271 static void calc_elem_w(WStatusBar
*p
, WSBElem
*el
, GrBrush
*brush
)
275 if(el
->type
==WSBELEM_SYSTRAY
){
276 do_calc_systray_w(p
, el
);
285 if(el
->type
==WSBELEM_METER
){
288 str
=(el
->text
!=NULL
? el
->text
: STATUSBAR_NX_STR
);
289 el
->text_w
=grbrush_get_text_width(brush
, str
, strlen(str
));
292 str_w
=str
!=NULL
? grbrush_get_text_width(brush
, str
, strlen(str
)) : 0;
293 el
->max_w
=MAXOF(str_w
, el
->text_w
);
296 el
->text_w
=(str
!=NULL
297 ? grbrush_get_text_width(brush
, str
, strlen(str
))
299 el
->max_w
=el
->text_w
;
304 static void statusbar_calc_widths(WStatusBar
*sb
)
308 for(i
=0; i
<sb
->nelems
; i
++)
309 calc_elem_w(sb
, &(sb
->elems
[i
]), sb
->brush
);
313 static void statusbar_do_update_natural_size(WStatusBar
*p
)
323 bdw
.left
=0; bdw
.right
=0;
324 bdw
.top
=0; bdw
.bottom
=0;
327 grbrush_get_border_widths(p
->brush
, &bdw
);
328 grbrush_get_font_extents(p
->brush
, &fnte
);
331 for(i
=0; i
<p
->nelems
; i
++)
332 totw
+=p
->elems
[i
].max_w
;
334 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, p
->traywins
, tmp
){
335 stmh
=MAXOF(stmh
, REGION_GEOM(reg
).h
);
338 p
->natural_w
=bdw
.left
+totw
+bdw
.right
;
339 p
->natural_h
=MAXOF(stmh
, fnte
.max_height
)+bdw
.top
+bdw
.bottom
;
343 void statusbar_size_hints(WStatusBar
*p
, WSizeHints
*h
)
346 h
->min_width
=p
->natural_w
;
347 h
->min_height
=p
->natural_h
;
350 h
->max_width
=INT_MAX
;/*p->natural_w;*/
351 h
->max_height
=p
->natural_h
;
361 static WSBElem
*statusbar_associate_systray(WStatusBar
*sb
, WRegion
*reg
)
363 WClientWin
*cwin
=OBJ_CAST(reg
, WClientWin
);
364 WSBElem
*el
=NULL
, *fbel
=NULL
;
369 extl_table_gets_s(cwin
->proptab
, "statusbar", &name
);
371 for(i
=0; i
<sb
->nelems
; i
++){
374 if(sb
->elems
[i
].type
!=WSBELEM_SYSTRAY
)
377 meter
=stringstore_get(sb
->elems
[i
].meter
);
383 if(name
!=NULL
&& strcmp(meter
, name
)==0){
387 if(strcmp(meter
, "systray")==0)
400 ptrlist_insert_last(&el
->traywins
, (Obj
*)reg
);
406 static WSBElem
*statusbar_unassociate_systray(WStatusBar
*sb
, WRegion
*reg
)
410 for(i
=0; i
<sb
->nelems
; i
++){
411 if(ptrlist_remove(&(sb
->elems
[i
].traywins
), (Obj
*)reg
))
412 return &sb
->elems
[i
];
420 static void do_calc_systray_w(WStatusBar
*p
, WSBElem
*el
)
427 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, el
->traywins
, tmp
){
428 w
=w
+REGION_GEOM(reg
).w
+padding
;
431 el
->text_w
=MAXOF(0, w
);
432 el
->max_w
=el
->text_w
; /* for now */
436 static void statusbar_calc_systray_w(WStatusBar
*p
)
440 for(i
=0; i
<p
->nelems
; i
++){
441 if(p
->elems
[i
].type
==WSBELEM_SYSTRAY
)
442 do_calc_systray_w(p
, &p
->elems
[i
]);
447 static void statusbar_arrange_systray(WStatusBar
*p
)
452 int padding
=0, ymiddle
;
456 grbrush_get_border_widths(p
->brush
, &bdw
);
462 ymiddle
=bdw
.top
+(REGION_GEOM(p
).h
-bdw
.top
-bdw
.bottom
)/2;
464 for(i
=0; i
<p
->nelems
; i
++){
465 WSBElem
*el
=&p
->elems
[i
];
466 if(el
->type
!=WSBELEM_SYSTRAY
)
469 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, el
->traywins
, tmp
){
470 WRectangle g
=REGION_GEOM(reg
);
473 region_fit(reg
, &g
, REGION_FIT_EXACT
);
480 static void systray_adjust_size(WRegion
*reg
, WRectangle
*g
)
482 g
->h
=CF_STATUSBAR_SYSTRAY_HEIGHT
;
484 region_size_hints_correct(reg
, &g
->w
, &g
->h
, TRUE
);
489 static WRegion
*statusbar_do_attach_final(WStatusBar
*sb
,
491 void *UNUSED(unused
))
496 if(!ptrlist_insert_last(&sb
->traywins
, (Obj
*)reg
))
499 el
=statusbar_associate_systray(sb
, reg
);
501 ptrlist_remove(&sb
->traywins
, (Obj
*)reg
);
505 fp
.g
=REGION_GEOM(reg
);
506 fp
.mode
=REGION_FIT_EXACT
;
507 systray_adjust_size(reg
, &fp
.g
);
509 region_fitrep(reg
, NULL
, &fp
);
511 do_calc_systray_w(sb
, el
);
513 region_set_manager(reg
, (WRegion
*)sb
);
515 statusbar_rearrange(sb
, TRUE
);
517 if(REGION_IS_MAPPED(sb
))
524 static WRegion
*statusbar_do_attach(WStatusBar
*sb
, WRegionAttachData
*data
)
530 fp
.g
.h
=CF_STATUSBAR_SYSTRAY_HEIGHT
;
531 fp
.g
.w
=CF_STATUSBAR_SYSTRAY_HEIGHT
;
532 fp
.mode
=REGION_FIT_WHATEVER
|REGION_FIT_BOUNDS
;
534 return region_attach_helper((WRegion
*)sb
, (WWindow
*)sb
, &fp
,
535 (WRegionDoAttachFn
*)statusbar_do_attach_final
,
540 static WRegion
*statusbar_attach_ph(WStatusBar
*sb
, int UNUSED(flags
),
541 WRegionAttachData
*data
)
543 return statusbar_do_attach(sb
, data
);
547 static WPHolder
*statusbar_prepare_manage(WStatusBar
*sb
,
548 const WClientWin
*UNUSED(cwin
),
549 const WManageParams
*UNUSED(param
),
552 if(!MANAGE_PRIORITY_OK(priority
, MANAGE_PRIORITY_LOW
))
555 return (WPHolder
*)create_basicpholder((WRegion
*)sb
,
556 ((WBasicPHolderHandler
*)
557 statusbar_attach_ph
));
561 static void statusbar_managed_remove(WStatusBar
*sb
, WRegion
*reg
)
565 ptrlist_remove(&sb
->traywins
, (Obj
*)reg
);
567 el
=statusbar_unassociate_systray(sb
, reg
);
569 region_unset_manager(reg
, (WRegion
*)sb
);
571 if(el
!=NULL
&& ioncore_g
.opmode
!=IONCORE_OPMODE_DEINIT
){
572 do_calc_systray_w(sb
, el
);
573 statusbar_rearrange(sb
, TRUE
);
578 static void statusbar_managed_rqgeom(WStatusBar
*sb
, WRegion
*reg
,
579 const WRQGeomParams
*rq
,
584 g
.x
=REGION_GEOM(reg
).x
;
585 g
.y
=REGION_GEOM(reg
).y
;
589 systray_adjust_size(reg
, &g
);
591 if(rq
->flags
®ION_RQGEOM_TRYONLY
){
597 region_fit(reg
, &g
, REGION_FIT_EXACT
);
599 statusbar_calc_systray_w(sb
);
600 statusbar_rearrange(sb
, TRUE
);
603 *geomret
=REGION_GEOM(reg
);
608 void statusbar_map(WStatusBar
*sb
)
613 window_map((WWindow
*)sb
);
615 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, sb
->traywins
, tmp
)
620 void statusbar_unmap(WStatusBar
*sb
)
625 window_unmap((WWindow
*)sb
);
627 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, sb
->traywins
, tmp
)
632 bool statusbar_fitrep(WStatusBar
*sb
, WWindow
*par
, const WFitParams
*fp
)
634 bool wchg
=(REGION_GEOM(sb
).w
!=fp
->g
.w
);
635 bool hchg
=(REGION_GEOM(sb
).h
!=fp
->g
.h
);
637 if(!window_fitrep(&(sb
->wwin
), par
, fp
))
641 statusbar_calculate_xs(sb
);
642 statusbar_arrange_systray(sb
);
643 statusbar_draw(sb
, TRUE
);
650 WPHolder
*statusbar_prepare_manage_transient(WStatusBar
*sb
,
651 const WClientWin
*cwin
,
652 const WManageParams
*param
,
655 WRegion
*mgr
=REGION_MANAGER(sb
);
658 mgr
=(WRegion
*)region_screen_of((WRegion
*)sb
);
661 return region_prepare_manage(mgr
, cwin
, param
,
662 MANAGE_PRIORITY_NONE
);
675 static ExtlFn parse_template_fn
;
676 static bool parse_template_fn_set
=FALSE
;
680 void mod_statusbar__set_template_parser(ExtlFn fn
)
682 if(parse_template_fn_set
)
683 extl_unref_fn(parse_template_fn
);
684 parse_template_fn
=extl_ref_fn(fn
);
685 parse_template_fn_set
=TRUE
;
690 * Set statusbar template.
693 void statusbar_set_template(WStatusBar
*sb
, const char *tmpl
)
695 ExtlTab t
=extl_table_none();
698 if(parse_template_fn_set
){
700 ok
=extl_call(parse_template_fn
, "s", "t", tmpl
, &t
);
701 extl_unprotect(NULL
);
705 statusbar_set_template_table(sb
, t
);
710 * Set statusbar template as table.
713 void statusbar_set_template_table(WStatusBar
*sb
, ExtlTab t
)
718 statusbar_set_elems(sb
, t
);
720 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, sb
->traywins
, tmp
){
721 statusbar_associate_systray(sb
, reg
);
724 statusbar_calc_widths(sb
);
725 statusbar_rearrange(sb
, FALSE
);
730 * Get statusbar template as table.
733 ExtlTab
statusbar_get_template_table(WStatusBar
*sb
)
735 int count
= sb
->nelems
;
738 ExtlTab t
= extl_create_table();
740 for(i
=0; i
<count
; i
++){
741 ExtlTab tt
= extl_create_table();
743 extl_table_sets_i(tt
, "type", sb
->elems
[i
].type
);
744 extl_table_sets_s(tt
, "text", sb
->elems
[i
].text
);
745 extl_table_sets_s(tt
, "meter", stringstore_get(sb
->elems
[i
].meter
));
746 extl_table_sets_s(tt
, "tmpl", sb
->elems
[i
].tmpl
);
747 extl_table_sets_i(tt
, "align", sb
->elems
[i
].align
);
748 extl_table_sets_i(tt
, "zeropad", sb
->elems
[i
].zeropad
);
750 extl_table_seti_t(t
, (i
+1), tt
);
751 extl_unref_table(tt
);
758 static void reset_stretch(WStatusBar
*sb
)
762 for(i
=0; i
<sb
->nelems
; i
++)
763 sb
->elems
[i
].stretch
=0;
767 static void positive_stretch(WStatusBar
*sb
)
771 for(i
=0; i
<sb
->nelems
; i
++)
772 sb
->elems
[i
].stretch
=MAXOF(0, sb
->elems
[i
].stretch
);
776 static void spread_stretch(WStatusBar
*sb
)
780 WSBElem
*el
, *lel
, *rel
;
782 for(i
=0; i
<sb
->nelems
; i
++){
785 if(el
->type
!=WSBELEM_METER
&& el
->type
!=WSBELEM_SYSTRAY
)
788 diff
=el
->max_w
-el
->text_w
;
793 if(el
->align
!=WSBELEM_ALIGN_RIGHT
){
794 for(j
=i
+1; j
<sb
->nelems
; j
++){
795 if(sb
->elems
[j
].type
==WSBELEM_STRETCH
){
802 if(el
->align
!=WSBELEM_ALIGN_LEFT
){
803 for(k
=i
-1; k
>=0; k
--){
804 if(sb
->elems
[k
].type
==WSBELEM_STRETCH
){
811 if(rel
!=NULL
&& lel
!=NULL
){
825 static void statusbar_rearrange(WStatusBar
*sb
, bool rs
)
828 int onw
=sb
->natural_w
;
829 int onh
=sb
->natural_h
;
831 statusbar_do_update_natural_size(sb
);
833 if( (sb
->natural_h
>onh
&& REGION_GEOM(sb
).h
>=onh
)
834 || (sb
->natural_h
<onh
&& REGION_GEOM(sb
).h
<=onh
)
835 || (sb
->natural_w
>onw
&& REGION_GEOM(sb
).w
>=onw
)
836 || (sb
->natural_w
<onw
&& REGION_GEOM(sb
).w
<=onw
)){
838 statusbar_resize(sb
);
844 positive_stretch(sb
);
845 statusbar_calculate_xs(sb
);
848 statusbar_arrange_systray(sb
);
854 * Set statusbar template.
857 void statusbar_update(WStatusBar
*sb
, ExtlTab t
)
866 for(i
=0; i
<sb
->nelems
; i
++){
871 if(el
->type
!=WSBELEM_METER
)
879 if(el
->attr
!=GRATTR_NONE
){
880 stringstore_free(el
->attr
);
881 el
->attr
=GRATTR_NONE
;
884 meter
=stringstore_get(el
->meter
);
890 extl_table_gets_s(t
, meter
, &(el
->text
));
893 str
=STATUSBAR_NX_STR
;
896 int l
=strlen(el
->text
);
897 int ml
=str_len(el
->text
);
898 int diff
=el
->zeropad
-ml
;
900 char *tmp
=ALLOC_N(char, l
+diff
+1);
902 memset(tmp
, '0', diff
);
903 memcpy(tmp
+diff
, el
->text
, l
+1);
911 if(el
->tmpl
!=NULL
&& el
->text
!=NULL
){
912 char *tmp
=grbrush_make_label(sb
->brush
, el
->text
, el
->max_w
);
920 el
->text_w
=grbrush_get_text_width(sb
->brush
, str
, strlen(str
));
922 if(el
->text_w
>el
->max_w
&& el
->tmpl
==NULL
){
923 el
->max_w
=el
->text_w
;
927 attrnm
=scat(meter
, "_hint");
930 if(extl_table_gets_s(t
, attrnm
, &s
)){
931 el
->attr
=stringstore_alloc(s
);
939 statusbar_rearrange(sb
, grow
);
941 window_draw((WWindow
*)sb
, FALSE
);
951 void statusbar_updategr(WStatusBar
*p
)
955 nbrush
=gr_get_brush(p
->wwin
.win
, region_rootwin_of((WRegion
*)p
),
961 grbrush_release(p
->brush
);
965 statusbar_calc_widths(p
);
966 statusbar_rearrange(p
, TRUE
);
968 window_draw(&(p
->wwin
), TRUE
);
978 int statusbar_orientation(WStatusBar
*UNUSED(sb
))
980 return REGION_ORIENTATION_HORIZONTAL
;
985 * Returns a list of all statusbars.
988 ExtlTab
mod_statusbar_statusbars()
990 ExtlTab t
=extl_create_table();
994 for(sb
=statusbars
; sb
!=NULL
; sb
=sb
->sb_next
){
995 extl_table_seti_o(t
, i
, (Obj
*)sb
);
1003 WStatusBar
*mod_statusbar_find_suitable(WClientWin
*cwin
,
1004 const WManageParams
*param
)
1008 for(sb
=statusbars
; sb
!=NULL
; sb
=sb
->sb_next
){
1011 if(!sb
->systray_enabled
)
1013 if(!region_same_rootwin((WRegion
*)sb
, (WRegion
*)cwin
))
1022 bool statusbar_set_systray(WStatusBar
*sb
, int sp
)
1024 bool set
=sb
->systray_enabled
;
1025 bool nset
=libtu_do_setparam(sp
, set
);
1027 sb
->systray_enabled
=nset
;
1034 * Enable or disable use of \var{sb} as systray.
1035 * The parameter \var{how} can be one of
1036 * \codestr{set}, \codestr{unset}, or \codestr{toggle}.
1037 * Resulting state is returned.
1039 EXTL_EXPORT_AS(WStatusBar
, set_systray
)
1040 bool statusbar_set_systray_extl(WStatusBar
*sb
, const char *how
)
1042 return statusbar_set_systray(sb
, libtu_string_to_setparam(how
));
1047 * Is \var{sb} used as a systray?
1049 EXTL_EXPORT_AS(WStatusBar
, is_systray
)
1050 bool statusbar_is_systray_extl(WStatusBar
*sb
)
1052 return sb
->systray_enabled
;
1062 WRegion
*statusbar_load(WWindow
*par
, const WFitParams
*fp
, ExtlTab tab
)
1064 WStatusBar
*sb
=create_statusbar(par
, fp
);
1068 ExtlTab t
=extl_table_none();
1069 if(extl_table_gets_s(tab
, "template", &tmpl
)){
1070 statusbar_set_template(sb
, tmpl
);
1072 }else if(extl_table_gets_t(tab
, "template_table", &t
)){
1073 statusbar_set_template_table(sb
, t
);
1074 extl_unref_table(t
);
1076 const char *tmpl
=TR("[ %date || load: %load ] %filler%systray");
1077 statusbar_set_template(sb
, tmpl
);
1080 extl_table_gets_b(tab
, "systray", &sb
->systray_enabled
);
1083 return (WRegion
*)sb
;
1090 /*{{{ Dynamic function table and class implementation */
1093 static DynFunTab statusbar_dynfuntab
[]={
1094 {window_draw
, statusbar_draw
},
1095 {region_updategr
, statusbar_updategr
},
1096 {region_size_hints
, statusbar_size_hints
},
1097 {(DynFun
*)region_orientation
, (DynFun
*)statusbar_orientation
},
1099 {region_managed_rqgeom
, statusbar_managed_rqgeom
},
1100 {(DynFun
*)region_prepare_manage
, (DynFun
*)statusbar_prepare_manage
},
1101 {region_managed_remove
, statusbar_managed_remove
},
1103 {(DynFun
*)region_prepare_manage_transient
,
1104 (DynFun
*)statusbar_prepare_manage_transient
},
1106 {region_map
, statusbar_map
},
1107 {region_unmap
, statusbar_unmap
},
1109 {(DynFun
*)region_fitrep
,
1110 (DynFun
*)statusbar_fitrep
},
1117 IMPLCLASS(WStatusBar
, WWindow
, statusbar_deinit
, statusbar_dynfuntab
);