4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
11 #include <libtu/obj.h>
12 #include <libtu/objp.h>
13 #include <libtu/minmax.h>
14 #include <libtu/map.h>
15 #include <libmainloop/defer.h>
29 #include "frame-pointer.h"
30 #include "frame-draw.h"
38 #include "framedpholder.h"
42 extern bool frame_set_background(WFrame
*frame
, bool set_always
);
43 extern void frame_initialise_gr(WFrame
*frame
);
45 static bool frame_initialise_titles(WFrame
*frame
);
46 static void frame_free_titles(WFrame
*frame
);
48 static void frame_add_mode_bindmaps(WFrame
*frame
);
51 WHook
*frame_managed_changed_hook
=NULL
;
53 #define FORWARD_CWIN_RQGEOM(FRAME) framemode_is_floating(frame_mode(FRAME))
54 #define USE_MINMAX(FRAME) framemode_is_floating(frame_mode(FRAME))
55 #define DEST_EMPTY(FRAME) framemode_is_floating(frame_mode(FRAME))
58 WFrameMode
framemode_unalt(WFrameMode mode
)
60 if(mode
==FRAME_MODE_UNKNOWN_ALT
)
61 return FRAME_MODE_UNKNOWN
;
62 else if(mode
==FRAME_MODE_TILED_ALT
)
63 return FRAME_MODE_TILED
;
64 else if(mode
==FRAME_MODE_FLOATING_ALT
)
65 return FRAME_MODE_FLOATING
;
66 else if(mode
==FRAME_MODE_TRANSIENT_ALT
)
67 return FRAME_MODE_TRANSIENT
;
73 static WFrameMode
framemode_is_floating(WFrameMode mode
)
75 WFrameMode modea
=framemode_unalt(mode
);
77 return (modea
==FRAME_MODE_FLOATING
|| modea
==FRAME_MODE_TRANSIENT
);
81 /*{{{ Destroy/create frame */
84 bool frame_init(WFrame
*frame
, WWindow
*parent
, const WFitParams
*fp
,
85 WFrameMode mode
, char *name
)
90 frame
->saved_geom
.w
=0;
91 frame
->saved_geom
.h
=0;
92 frame
->saved_geom
.x
=0;
93 frame
->saved_geom
.y
=0;
94 frame
->tab_dragged_idx
=-1;
99 frame
->tr_mode
=GR_TRANSPARENCY_DEFAULT
;
101 frame
->bar_brush
=NULL
;
103 frame_tabs_width_recalc_init(frame
);
105 gr_stylespec_init(&frame
->baseattr
);
107 if(!mplex_init((WMPlex
*)frame
, parent
, fp
, name
))
110 frame_initialise_gr(frame
);
111 frame_initialise_titles(frame
);
113 region_add_bindmap((WRegion
*)frame
, ioncore_frame_bindmap
);
114 region_add_bindmap((WRegion
*)frame
, ioncore_mplex_bindmap
);
116 frame_add_mode_bindmaps(frame
);
118 mplex_managed_geom((WMPlex
*)frame
, &mg
);
121 frame
->flags
|=FRAME_SHADED
;
123 ((WRegion
*)frame
)->flags
|=REGION_PLEASE_WARP
;
129 WFrame
*create_frame(WWindow
*parent
, const WFitParams
*fp
, WFrameMode mode
, char *name
)
131 CREATEOBJ_IMPL(WFrame
, frame
, (p
, parent
, fp
, mode
, name
));
135 void frame_deinit(WFrame
*frame
)
137 frame_free_titles(frame
);
138 frame_release_brushes(frame
);
139 gr_stylespec_unalloc(&frame
->baseattr
);
140 mplex_deinit((WMPlex
*)frame
);
147 /*{{{ Mode switching */
150 static void frame_add_mode_bindmaps(WFrame
*frame
)
152 WFrameMode modea
=framemode_unalt(frame
->mode
);
154 if(modea
==FRAME_MODE_FLOATING
){
155 region_add_bindmap((WRegion
*)frame
, ioncore_mplex_toplevel_bindmap
);
156 region_add_bindmap((WRegion
*)frame
, ioncore_frame_toplevel_bindmap
);
157 region_add_bindmap((WRegion
*)frame
, ioncore_frame_floating_bindmap
);
158 }else if(modea
==FRAME_MODE_TRANSIENT
){
159 region_add_bindmap((WRegion
*)frame
, ioncore_frame_transient_bindmap
);
160 region_add_bindmap((WRegion
*)frame
, ioncore_frame_floating_bindmap
);
162 /* mode==FRAME_MODE_TILED || mode==FRAME_MODE_TILED_ALT || mode==FRAME_MODE_UNKNOWN */
163 region_add_bindmap((WRegion
*)frame
, ioncore_mplex_toplevel_bindmap
);
164 region_add_bindmap((WRegion
*)frame
, ioncore_frame_toplevel_bindmap
);
165 region_add_bindmap((WRegion
*)frame
, ioncore_frame_tiled_bindmap
);
170 void frame_set_mode(WFrame
*frame
, WFrameMode mode
)
172 if(frame
->mode
==mode
)
175 frame_clear_shape(frame
);
177 frame_release_brushes(frame
);
179 region_remove_bindmap((WRegion
*)frame
, ioncore_mplex_toplevel_bindmap
);
180 region_remove_bindmap((WRegion
*)frame
, ioncore_frame_toplevel_bindmap
);
181 region_remove_bindmap((WRegion
*)frame
, ioncore_frame_tiled_bindmap
);
182 region_remove_bindmap((WRegion
*)frame
, ioncore_frame_floating_bindmap
);
183 region_remove_bindmap((WRegion
*)frame
, ioncore_frame_transient_bindmap
);
187 frame_add_mode_bindmaps(frame
);
189 frame_updategr(frame
);
193 WFrameMode
frame_mode(WFrame
*frame
)
199 static StringIntMap frame_modes
[]={
200 {"unknown", FRAME_MODE_UNKNOWN
},
201 {"unknown-alt", FRAME_MODE_UNKNOWN_ALT
},
202 {"tiled", FRAME_MODE_TILED
},
203 {"tiled-alt", FRAME_MODE_TILED_ALT
},
204 {"floating", FRAME_MODE_FLOATING
},
205 {"floating-alt", FRAME_MODE_FLOATING_ALT
},
206 {"transient", FRAME_MODE_TRANSIENT
},
207 {"transient-alt", FRAME_MODE_TRANSIENT_ALT
},
216 EXTL_EXPORT_AS(WFrame
, mode
)
217 const char *frame_mode_extl(WFrame
*frame
)
219 return stringintmap_key(frame_modes
, frame
->mode
, NULL
);
224 * Set frame mode (one of
225 * \codestr{unknown}, \codestr{tiled}, \codestr{floating}, \codestr{transient},
226 * or any of these suffixed with \codestr{-alt}).
228 EXTL_EXPORT_AS(WFrame
, set_mode
)
229 bool frame_set_mode_extl(WFrame
*frame
, const char *modestr
)
234 idx
=stringintmap_ndx(frame_modes
, modestr
);
238 frame_set_mode(frame
, frame_modes
[idx
].value
);
250 int frame_tab_at_x(WFrame
*frame
, int x
)
255 frame_bar_geom(frame
, &bg
);
257 if(x
>=bg
.x
+bg
.w
|| x
<bg
.x
)
262 for(tab
=0; tab
<FRAME_MCOUNT(frame
); tab
++){
263 tx
+=frame_nth_tab_w(frame
, tab
);
272 int frame_nth_tab_x(WFrame
*frame
, int n
)
278 x
+=frame_nth_tab_w(frame
, i
);
284 int frame_nth_tab_w(WFrame
*frame
, int n
)
286 GrBorderWidths bdw
=GR_BORDER_WIDTHS_INIT
;
288 if (n
>frame
->titles_n
){
289 fprintf(stderr
,"WARNING: we should not be here, please contact notion developers\n");
292 if(frame
->titles
[n
].iw
==0) return 0; /* Too small tab. */
294 if(frame
->bar_brush
!=NULL
)
295 grbrush_get_border_widths(frame
->bar_brush
, &bdw
);
297 return frame
->titles
[n
].iw
+
298 (n
==0 ? bdw
.left
: bdw
.tb_ileft
) +
299 (n
==frame
->titles_n
-1 ? bdw
.right
: bdw
.tb_iright
+bdw
.spacing
);
304 void frame_update_attr_nth(WFrame
*frame
, int i
)
308 if(i
<0 || i
>=frame
->titles_n
)
311 frame_update_attr(frame
, i
, mplex_mx_nth((WMPlex
*)frame
, i
));
315 static void frame_update_attrs(WFrame
*frame
)
321 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
322 frame_update_attr(frame
, i
, sub
);
328 static void frame_free_titles(WFrame
*frame
)
332 if(frame
->titles
!=NULL
){
333 for(i
=0; i
<frame
->titles_n
; i
++){
334 if(frame
->titles
[i
].text
)
335 free(frame
->titles
[i
].text
);
336 gr_stylespec_unalloc(&frame
->titles
[i
].attr
);
345 static void do_init_title(WFrame
*frame
, int i
, WRegion
*sub
)
347 frame
->titles
[i
].text
=NULL
;
349 gr_stylespec_init(&frame
->titles
[i
].attr
);
351 frame_update_attr(frame
, i
, sub
);
355 static bool frame_initialise_titles(WFrame
*frame
)
357 int i
, n
=FRAME_MCOUNT(frame
);
359 frame_free_titles(frame
);
364 frame
->titles
=ALLOC_N(GrTextElem
, n
);
365 if(frame
->titles
==NULL
)
369 if(FRAME_MCOUNT(frame
)==0){
370 do_init_title(frame
, 0, NULL
);
375 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
376 do_init_title(frame
, i
, sub
);
381 frame_recalc_bar(frame
, FALSE
);
390 /*{{{ Resize and reparent */
393 bool frame_fitrep(WFrame
*frame
, WWindow
*par
, const WFitParams
*fp
)
395 WRectangle old_geom
, mg
;
396 bool wchg
=(REGION_GEOM(frame
).w
!=fp
->g
.w
);
397 bool hchg
=(REGION_GEOM(frame
).h
!=fp
->g
.h
);
399 old_geom
=REGION_GEOM(frame
);
401 if(!window_fitrep(&(frame
->mplex
.win
), par
, fp
))
404 mplex_managed_geom((WMPlex
*)frame
, &mg
);
406 if(!(frame
->flags
&FRAME_KEEP_FLAGS
)){
409 frame
->flags
|=(FRAME_SHADED
|FRAME_SAVED_VERT
);
410 frame
->saved_geom
.y
=old_geom
.y
;
411 frame
->saved_geom
.h
=old_geom
.h
;
413 frame
->flags
&=~FRAME_SHADED
;
415 frame
->flags
&=~FRAME_MAXED_VERT
;
420 frame
->flags
|=(FRAME_MIN_HORIZ
|FRAME_SAVED_HORIZ
);
421 frame
->saved_geom
.x
=old_geom
.x
;
422 frame
->saved_geom
.w
=old_geom
.w
;
424 frame
->flags
&=~FRAME_MIN_HORIZ
;
426 frame
->flags
&=~FRAME_MAXED_HORIZ
;
431 mplex_fit_managed((WMPlex
*)frame
);
432 mplex_size_changed((WMPlex
*)frame
, wchg
, hchg
);
439 void frame_size_hints(WFrame
*frame
, WSizeHints
*hints_ret
)
446 mplex_managed_geom((WMPlex
*)frame
, &subgeom
);
448 woff
=maxof(REGION_GEOM(frame
).w
-subgeom
.w
, 0);
449 hoff
=maxof(REGION_GEOM(frame
).h
-subgeom
.h
, 0);
451 if(FRAME_CURRENT(frame
)!=NULL
)
452 region_size_hints(FRAME_CURRENT(frame
), hints_ret
);
454 sizehints_clear(hints_ret
);
456 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
457 sizehints_adjust_for(hints_ret
, sub
);
460 if(!USE_MINMAX(frame
)){
461 hints_ret
->max_set
=0;
462 hints_ret
->min_set
=0;
463 /*hints_ret->base_set=0;*/
464 hints_ret
->aspect_set
=0;
465 hints_ret
->no_constrain
=FALSE
;
466 /*hints_ret->no_constrain=TRUE;*/
469 if(!hints_ret
->min_set
){
470 hints_ret
->min_width
=0;
471 hints_ret
->min_height
=0;
472 hints_ret
->min_set
=TRUE
;
475 if(!hints_ret
->base_set
){
476 hints_ret
->base_width
=0;
477 hints_ret
->base_height
=0;
478 hints_ret
->base_set
=TRUE
;
481 hints_ret
->base_width
+=woff
;
482 hints_ret
->base_height
+=hoff
;
483 if(hints_ret
->max_width
!=INT_MAX
)
484 hints_ret
->max_width
+=woff
;
485 if(hints_ret
->max_height
!=INT_MAX
)
486 hints_ret
->max_height
+=hoff
;
487 hints_ret
->min_width
+=woff
;
488 hints_ret
->min_height
+=hoff
;
491 int f
=frame
->flags
&(FRAME_SHADED
|FRAME_SHADED_TOGGLE
);
493 if(f
==FRAME_SHADED
|| f
==FRAME_SHADED_TOGGLE
){
494 int h
=frame_shaded_height(frame
);
495 hints_ret
->min_height
=h
;
496 hints_ret
->max_height
=h
;
497 hints_ret
->base_height
=h
;
498 if(!hints_ret
->max_set
){
499 hints_ret
->max_width
=INT_MAX
;
500 hints_ret
->max_set
=TRUE
;
510 /*{{{ Client window rqgeom */
513 static void frame_managed_rqgeom_absolute(WFrame
*frame
, WRegion
*sub
,
514 const WRQGeomParams
*rq
,
517 if(!FORWARD_CWIN_RQGEOM(frame
)){
518 region_managed_rqgeom_absolute_default((WRegion
*)frame
, sub
,
521 WRQGeomParams rq2
=RQGEOMPARAMS_INIT
;
522 int gravity
=ForgetGravity
;
527 rq2
.flags
=rq
->flags
&(REGION_RQGEOM_WEAK_ALL
528 |REGION_RQGEOM_TRYONLY
529 |REGION_RQGEOM_ABSOLUTE
);
531 if(rq
->flags
®ION_RQGEOM_GRAVITY
)
534 mplex_managed_geom(&frame
->mplex
, &off
);
537 off
.w
=REGION_GEOM(frame
).w
-off
.w
;
538 off
.h
=REGION_GEOM(frame
).h
-off
.h
;
540 rq2
.geom
.w
=maxof(rq2
.geom
.w
+off
.w
, 0);
541 rq2
.geom
.h
=maxof(rq2
.geom
.h
+off
.h
, 0);
543 /*region_size_hints_correct((WRegion*)frame, &(geom.w), &(geom.h), TRUE);*/
545 /* If WEAK_? is set, then geom.(x|y) is root-relative as it was not
546 * requested by the client and clientwin_handle_configure_request has
547 * no better guess. Otherwise the coordinates are those requested by
548 * the client (modulo borders/gravity) and we interpret them to be
549 * root-relative coordinates for this frame modulo gravity.
551 if(rq
->flags
®ION_RQGEOM_WEAK_X
)
554 rq2
.geom
.x
+=xgravity_deltax(gravity
, -off
.x
, off
.x
+off
.w
);
556 if(rq
->flags
®ION_RQGEOM_WEAK_Y
)
559 rq2
.geom
.y
+=xgravity_deltay(gravity
, -off
.y
, off
.y
+off
.h
);
561 region_rqgeom((WRegion
*)frame
, &rq2
, geomret
);
576 /*{{{ Frame recreate pholder stuff */
579 static WFramedPHolder
*frame_make_recreate_pholder(WFrame
*frame
, WPHolder
*rph
)
581 WFramedParam fparam
=FRAMEDPARAM_INIT
;
582 WFramedPHolder
*fph
=NULL
;
585 fparam
.mode
=frame
->mode
;
587 fph
=create_framedpholder(rph
, &fparam
);
590 destroy_obj((Obj
*)rph
);
597 static void mplex_migrate_phs_to_fph(WMPlex
*mplex
, WFramedPHolder
*fph
)
599 WMPlexPHolder
*phs
, *ph
;
602 mplex
->misc_phs
=NULL
;
604 phs
->recreate_pholder
=fph
;
606 for(ph
=phs
; ph
!=NULL
; ph
=ph
->next
)
612 bool frame_rescue_clientwins(WFrame
*frame
, WRescueInfo
*info
)
616 ret
=mplex_rescue_clientwins(&frame
->mplex
, info
);
618 /* Now, do placeholders.
619 * We can't currently be arsed to keep them ordered with regions...
620 * First we check if we can simply recreate this frame, which takes
621 * care of e.g. floating frames being destroyed when entering full
622 * screen mode. If not, we check if the target would be a WMPlex, and
623 * migrate there. This takes care of frames destroyed in tilings.
625 mplex_flatten_phs(&frame
->mplex
);
627 if(frame
->mplex
.misc_phs
!=NULL
){
628 WPHolder
*ret_ph
=region_make_return_pholder((WRegion
*)frame
);
629 WFramedPHolder
*fph
=frame_make_recreate_pholder(frame
, ret_ph
);
632 mplex_migrate_phs_to_fph(&frame
->mplex
, fph
);
634 WPHolder
*rescueph
=rescueinfo_pholder(info
);
636 WRegion
*target
=pholder_target(rescueph
);
637 WMPlex
*other_mplex
=OBJ_CAST(target
, WMPlex
);
639 if(other_mplex
!=NULL
){
640 assert(other_mplex
!=&frame
->mplex
);
641 mplex_migrate_phs(&frame
->mplex
, other_mplex
);
657 bool frame_set_shaded(WFrame
*frame
, int sp
)
659 bool set
=(frame
->flags
&FRAME_SHADED
);
660 bool nset
=libtu_do_setparam(sp
, set
);
661 WRQGeomParams rq
=RQGEOMPARAMS_INIT
;
668 rq
.flags
=REGION_RQGEOM_H_ONLY
;
669 rq
.geom
=REGION_GEOM(frame
);
672 if(!(frame
->flags
&FRAME_SAVED_VERT
))
674 rq
.geom
.h
=frame
->saved_geom
.h
;
676 if(frame
->barmode
==FRAME_BAR_NONE
)
678 rq
.geom
.h
=frame_shaded_height(frame
);
681 frame
->flags
|=FRAME_SHADED_TOGGLE
;
683 region_rqgeom((WRegion
*)frame
, &rq
, NULL
);
685 frame
->flags
&=~FRAME_SHADED_TOGGLE
;
687 return (frame
->flags
&FRAME_SHADED
);
692 * Set shading state according to the parameter \var{how}
693 * (\codestr{set}, \codestr{unset}, or \codestr{toggle}).
694 * Resulting state is returned, which may not be
695 * what was requested.
697 EXTL_EXPORT_AS(WFrame
, set_shaded
)
698 bool frame_set_shaded_extl(WFrame
*frame
, const char *how
)
700 return frame_set_shaded(frame
, libtu_string_to_setparam(how
));
705 * Is \var{frame} shaded?
709 bool frame_is_shaded(WFrame
*frame
)
711 return ((frame
->flags
&FRAME_SHADED
)!=0);
716 * Is the attribute \var{attr} set on \var{frame}?
720 bool frame_is_grattr(WFrame
*frame
, const char *attr
)
722 GrAttr a
=stringstore_alloc(attr
);
723 bool set
=gr_stylespec_isset(&frame
->baseattr
, a
);
729 bool frame_set_grattr(WFrame
*frame
, GrAttr a
, int sp
)
731 bool set
=gr_stylespec_isset(&frame
->baseattr
, a
);
732 bool nset
=libtu_do_setparam(sp
, set
);
736 gr_stylespec_set(&frame
->baseattr
, a
);
738 gr_stylespec_unset(&frame
->baseattr
, a
);
739 window_draw((WWindow
*)frame
, TRUE
);
747 * Set extra drawing engine attributes for the frame.
748 * The parameter \var{attr} is the attribute, and \var{how} is
749 * one of \codestr{set}, \codestr{unset}, or \codestr{toggle}.
751 EXTL_EXPORT_AS(WFrame
, set_grattr
)
752 bool frame_set_grattr_extl(WFrame
*frame
, const char *attr
, const char *how
)
755 GrAttr a
=stringstore_alloc(attr
);
756 bool ret
=frame_set_grattr(frame
, a
, libtu_string_to_setparam(how
));
765 void frame_managed_notify(WFrame
*frame
, WRegion
*sub
, WRegionNotify how
)
769 if(how
==ioncore_g
.notifies
.activated
||
770 how
==ioncore_g
.notifies
.inactivated
||
771 how
==ioncore_g
.notifies
.name
||
772 how
==ioncore_g
.notifies
.activity
||
773 how
==ioncore_g
.notifies
.sub_activity
||
774 how
==ioncore_g
.notifies
.tag
){
776 complete
=how
==ioncore_g
.notifies
.name
;
778 frame_update_attrs(frame
);
779 frame_recalc_bar(frame
, complete
);
780 frame_draw_bar(frame
, complete
);
785 static void frame_size_changed_default(WFrame
*frame
,
786 bool wchg
, bool hchg
)
788 int bar_w
=frame
->bar_w
;
791 frame_recalc_bar(frame
, TRUE
);
793 if(frame
->barmode
==FRAME_BAR_SHAPED
&&
794 ((!wchg
&& hchg
) || (wchg
&& bar_w
==frame
->bar_w
))){
795 frame_set_shape(frame
);
800 static void frame_managed_changed(WFrame
*frame
, int mode
, bool sw
,
805 if(mode
!=MPLEX_CHANGE_SWITCHONLY
)
806 frame_initialise_titles(frame
);
808 frame_update_attrs(frame
);
811 need_draw
=!frame_set_background(frame
, FALSE
);
814 frame_draw_bar(frame
, mode
!=MPLEX_CHANGE_SWITCHONLY
);
816 mplex_call_changed_hook((WMPlex
*)frame
,
817 frame_managed_changed_hook
,
822 WRegion
*frame_managed_disposeroot(WFrame
*frame
, WRegion
*reg
)
824 if(DEST_EMPTY(frame
) &&
825 frame
->mplex
.mgd
!=NULL
&&
826 frame
->mplex
.mgd
->reg
==reg
&&
827 frame
->mplex
.mgd
->mgr_next
==NULL
){
828 WRegion
*tmp
=region_disposeroot((WRegion
*)frame
);
829 return (tmp
!=NULL
? tmp
: reg
);
836 int frame_default_index(WFrame
*frame
)
838 return ioncore_g
.frame_default_index
;
845 /*{{{ prepare_manage_transient */
848 WPHolder
*frame_prepare_manage_transient(WFrame
*frame
,
849 const WClientWin
*transient
,
850 const WManageParams
*param
,
853 /* Transient manager searches should not cross tiled frames
854 * unless explicitly floated.
856 if(framemode_is_floating(frame_mode(frame
)) ||
857 extl_table_is_bool_set(transient
->proptab
, "float")){
858 return region_prepare_manage_transient_default((WRegion
*)frame
,
874 ExtlTab
frame_get_configuration(WFrame
*frame
)
876 ExtlTab tab
=mplex_get_configuration(&frame
->mplex
);
878 extl_table_sets_i(tab
, "mode", frame
->mode
);
880 if(frame
->flags
&FRAME_SAVED_VERT
){
881 extl_table_sets_i(tab
, "saved_y", frame
->saved_geom
.y
);
882 extl_table_sets_i(tab
, "saved_h", frame
->saved_geom
.h
);
885 if(frame
->flags
&FRAME_SAVED_HORIZ
){
886 extl_table_sets_i(tab
, "saved_x", frame
->saved_geom
.x
);
887 extl_table_sets_i(tab
, "saved_w", frame
->saved_geom
.w
);
895 void frame_do_load(WFrame
*frame
, ExtlTab tab
)
900 if(extl_table_gets_i(tab
, "saved_x", &p
) &&
901 extl_table_gets_i(tab
, "saved_w", &s
)){
902 frame
->saved_geom
.x
=p
;
903 frame
->saved_geom
.w
=s
;
904 frame
->flags
|=FRAME_SAVED_HORIZ
;
907 if(extl_table_gets_i(tab
, "saved_y", &p
) &&
908 extl_table_gets_i(tab
, "saved_h", &s
)){
909 frame
->saved_geom
.y
=p
;
910 frame
->saved_geom
.h
=s
;
911 frame
->flags
|=FRAME_SAVED_VERT
;
914 mplex_load_contents(&frame
->mplex
, tab
);
918 WRegion
*frame_load(WWindow
*par
, const WFitParams
*fp
, ExtlTab tab
)
920 int mode
=FRAME_MODE_UNKNOWN
;
923 if(!extl_table_gets_i(tab
, "mode", &mode
)){
925 if(extl_table_gets_s(tab
, "mode", &tmp
)){
926 mode
=stringintmap_value(frame_modes
, tmp
, mode
);
931 frame
=create_frame(par
, fp
, mode
, "WFrame");
934 frame_do_load(frame
, tab
);
936 if(DEST_EMPTY(frame
) && frame
->mplex
.mgd
==NULL
){
937 if(frame
->mplex
.misc_phs
!=NULL
){
938 /* Session management hack */
940 fph
=frame_make_recreate_pholder(frame
, ioncore_get_load_pholder());
942 mplex_migrate_phs_to_fph(&frame
->mplex
, fph
);
945 destroy_obj((Obj
*)frame
);
949 return (WRegion
*)frame
;
956 /*{{{ Dynfuntab and class info */
959 static DynFunTab frame_dynfuntab
[]={
960 {region_size_hints
, frame_size_hints
},
962 {mplex_managed_changed
, frame_managed_changed
},
963 {mplex_size_changed
, frame_size_changed_default
},
964 {region_managed_notify
, frame_managed_notify
},
966 {region_activated
, frame_activated
},
967 {region_inactivated
, frame_inactivated
},
969 {(DynFun
*)window_press
, (DynFun
*)frame_press
},
971 {(DynFun
*)region_get_configuration
,
972 (DynFun
*)frame_get_configuration
},
983 {(DynFun
*)region_fitrep
,
984 (DynFun
*)frame_fitrep
},
986 {(DynFun
*)region_managed_disposeroot
,
987 (DynFun
*)frame_managed_disposeroot
},
989 {region_managed_rqgeom_absolute
,
990 frame_managed_rqgeom_absolute
},
992 {(DynFun
*)mplex_default_index
,
993 (DynFun
*)frame_default_index
},
995 {(DynFun
*)region_prepare_manage_transient
,
996 (DynFun
*)frame_prepare_manage_transient
},
998 {(DynFun
*)region_rescue_clientwins
,
999 (DynFun
*)frame_rescue_clientwins
},
1006 IMPLCLASS(WFrame
, WMPlex
, frame_deinit
, frame_dynfuntab
);