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
)
233 idx
=stringintmap_ndx(frame_modes
, modestr
);
237 frame_set_mode(frame
, frame_modes
[idx
].value
);
249 int frame_tab_at_x(WFrame
*frame
, int x
)
254 frame_bar_geom(frame
, &bg
);
256 if(x
>=bg
.x
+bg
.w
|| x
<bg
.x
)
261 for(tab
=0; tab
<FRAME_MCOUNT(frame
); tab
++){
262 tx
+=frame_nth_tab_w(frame
, tab
);
271 int frame_nth_tab_x(WFrame
*frame
, int n
)
277 x
+=frame_nth_tab_w(frame
, i
);
283 int frame_nth_tab_w(WFrame
*frame
, int n
)
285 GrBorderWidths bdw
=GR_BORDER_WIDTHS_INIT
;
287 if (n
>frame
->titles_n
){
288 fprintf(stderr
,"WARNING: we should not be here, please contact notion developers\n");
291 if(frame
->titles
[n
].iw
==0) return 0; /* Too small tab. */
293 if(frame
->bar_brush
!=NULL
)
294 grbrush_get_border_widths(frame
->bar_brush
, &bdw
);
296 return frame
->titles
[n
].iw
+
297 (n
==0 ? bdw
.left
: bdw
.tb_ileft
) +
298 (n
==frame
->titles_n
-1 ? bdw
.right
: bdw
.tb_iright
+bdw
.spacing
);
303 void frame_update_attr_nth(WFrame
*frame
, int i
)
305 if(i
<0 || i
>=frame
->titles_n
)
308 frame_update_attr(frame
, i
, mplex_mx_nth((WMPlex
*)frame
, i
));
312 static void frame_update_attrs(WFrame
*frame
)
318 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
319 frame_update_attr(frame
, i
, sub
);
325 static void frame_free_titles(WFrame
*frame
)
329 if(frame
->titles
!=NULL
){
330 for(i
=0; i
<frame
->titles_n
; i
++){
331 if(frame
->titles
[i
].text
)
332 free(frame
->titles
[i
].text
);
333 gr_stylespec_unalloc(&frame
->titles
[i
].attr
);
342 static void do_init_title(WFrame
*frame
, int i
, WRegion
*sub
)
344 frame
->titles
[i
].text
=NULL
;
346 gr_stylespec_init(&frame
->titles
[i
].attr
);
348 frame_update_attr(frame
, i
, sub
);
352 static bool frame_initialise_titles(WFrame
*frame
)
354 int i
, n
=FRAME_MCOUNT(frame
);
356 frame_free_titles(frame
);
361 frame
->titles
=ALLOC_N(GrTextElem
, n
);
362 if(frame
->titles
==NULL
)
366 if(FRAME_MCOUNT(frame
)==0){
367 do_init_title(frame
, 0, NULL
);
372 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
373 do_init_title(frame
, i
, sub
);
378 frame_recalc_bar(frame
, FALSE
);
387 /*{{{ Resize and reparent */
390 bool frame_fitrep(WFrame
*frame
, WWindow
*par
, const WFitParams
*fp
)
392 WRectangle old_geom
, mg
;
393 bool wchg
=(REGION_GEOM(frame
).w
!=fp
->g
.w
);
394 bool hchg
=(REGION_GEOM(frame
).h
!=fp
->g
.h
);
396 old_geom
=REGION_GEOM(frame
);
398 if(!window_fitrep(&(frame
->mplex
.win
), par
, fp
))
401 mplex_managed_geom((WMPlex
*)frame
, &mg
);
403 if(!(frame
->flags
&FRAME_KEEP_FLAGS
)){
406 frame
->flags
|=(FRAME_SHADED
|FRAME_SAVED_VERT
);
407 frame
->saved_geom
.y
=old_geom
.y
;
408 frame
->saved_geom
.h
=old_geom
.h
;
410 frame
->flags
&=~FRAME_SHADED
;
412 frame
->flags
&=~FRAME_MAXED_VERT
;
417 frame
->flags
|=(FRAME_MIN_HORIZ
|FRAME_SAVED_HORIZ
);
418 frame
->saved_geom
.x
=old_geom
.x
;
419 frame
->saved_geom
.w
=old_geom
.w
;
421 frame
->flags
&=~FRAME_MIN_HORIZ
;
423 frame
->flags
&=~FRAME_MAXED_HORIZ
;
428 mplex_fit_managed((WMPlex
*)frame
);
429 mplex_size_changed((WMPlex
*)frame
, wchg
, hchg
);
436 void frame_size_hints(WFrame
*frame
, WSizeHints
*hints_ret
)
443 mplex_managed_geom((WMPlex
*)frame
, &subgeom
);
445 woff
=MAXOF(REGION_GEOM(frame
).w
-subgeom
.w
, 0);
446 hoff
=MAXOF(REGION_GEOM(frame
).h
-subgeom
.h
, 0);
448 if(FRAME_CURRENT(frame
)!=NULL
)
449 region_size_hints(FRAME_CURRENT(frame
), hints_ret
);
451 sizehints_clear(hints_ret
);
453 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
454 sizehints_adjust_for(hints_ret
, sub
);
457 if(!USE_MINMAX(frame
)){
458 hints_ret
->max_set
=0;
459 hints_ret
->min_set
=0;
460 /*hints_ret->base_set=0;*/
461 hints_ret
->aspect_set
=0;
462 hints_ret
->no_constrain
=FALSE
;
463 /*hints_ret->no_constrain=TRUE;*/
466 if(!hints_ret
->min_set
){
467 hints_ret
->min_width
=0;
468 hints_ret
->min_height
=0;
469 hints_ret
->min_set
=TRUE
;
472 if(!hints_ret
->base_set
){
473 hints_ret
->base_width
=0;
474 hints_ret
->base_height
=0;
475 hints_ret
->base_set
=TRUE
;
478 hints_ret
->base_width
+=woff
;
479 hints_ret
->base_height
+=hoff
;
481 if(hints_ret
->max_set
) {
482 if(hints_ret
->max_width
!=INT_MAX
)
483 hints_ret
->max_width
+=woff
;
484 if(hints_ret
->max_height
!=INT_MAX
)
485 hints_ret
->max_height
+=hoff
;
488 hints_ret
->min_width
+=woff
;
489 hints_ret
->min_height
+=hoff
;
492 int f
=frame
->flags
&(FRAME_SHADED
|FRAME_SHADED_TOGGLE
);
494 if(f
==FRAME_SHADED
|| f
==FRAME_SHADED_TOGGLE
){
495 int h
=frame_shaded_height(frame
);
496 hints_ret
->min_height
=h
;
497 hints_ret
->max_height
=h
;
498 hints_ret
->base_height
=h
;
499 if(!hints_ret
->max_set
){
500 hints_ret
->max_width
=INT_MAX
;
501 hints_ret
->max_set
=TRUE
;
511 /*{{{ Client window rqgeom */
514 static void frame_managed_rqgeom_absolute(WFrame
*frame
, WRegion
*sub
,
515 const WRQGeomParams
*rq
,
518 if(!FORWARD_CWIN_RQGEOM(frame
)){
519 region_managed_rqgeom_absolute_default((WRegion
*)frame
, sub
,
522 WRQGeomParams rq2
=RQGEOMPARAMS_INIT
;
523 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
;
666 rq
.flags
=REGION_RQGEOM_H_ONLY
;
667 rq
.geom
=REGION_GEOM(frame
);
670 if(!(frame
->flags
&FRAME_SAVED_VERT
))
672 rq
.geom
.h
=frame
->saved_geom
.h
;
674 if(frame
->barmode
==FRAME_BAR_NONE
)
676 rq
.geom
.h
=frame_shaded_height(frame
);
679 frame
->flags
|=FRAME_SHADED_TOGGLE
;
681 region_rqgeom((WRegion
*)frame
, &rq
, NULL
);
683 frame
->flags
&=~FRAME_SHADED_TOGGLE
;
685 return (frame
->flags
&FRAME_SHADED
);
690 * Set shading state according to the parameter \var{how}
691 * (\codestr{set}, \codestr{unset}, or \codestr{toggle}).
692 * Resulting state is returned, which may not be
693 * what was requested.
695 EXTL_EXPORT_AS(WFrame
, set_shaded
)
696 bool frame_set_shaded_extl(WFrame
*frame
, const char *how
)
698 return frame_set_shaded(frame
, libtu_string_to_setparam(how
));
703 * Is \var{frame} shaded?
707 bool frame_is_shaded(WFrame
*frame
)
709 return ((frame
->flags
&FRAME_SHADED
)!=0);
714 * Is the attribute \var{attr} set on \var{frame}?
718 bool frame_is_grattr(WFrame
*frame
, const char *attr
)
720 GrAttr a
=stringstore_alloc(attr
);
721 bool set
=gr_stylespec_isset(&frame
->baseattr
, a
);
727 bool frame_set_grattr(WFrame
*frame
, GrAttr a
, int sp
)
729 bool set
=gr_stylespec_isset(&frame
->baseattr
, a
);
730 bool nset
=libtu_do_setparam(sp
, set
);
734 gr_stylespec_set(&frame
->baseattr
, a
);
736 gr_stylespec_unset(&frame
->baseattr
, a
);
737 window_draw((WWindow
*)frame
, TRUE
);
745 * Set extra drawing engine attributes for the frame.
746 * The parameter \var{attr} is the attribute, and \var{how} is
747 * one of \codestr{set}, \codestr{unset}, or \codestr{toggle}.
749 EXTL_EXPORT_AS(WFrame
, set_grattr
)
750 bool frame_set_grattr_extl(WFrame
*frame
, const char *attr
, const char *how
)
753 GrAttr a
=stringstore_alloc(attr
);
754 bool ret
=frame_set_grattr(frame
, a
, libtu_string_to_setparam(how
));
763 void frame_managed_notify(WFrame
*frame
, WRegion
*UNUSED(sub
), WRegionNotify how
)
767 if(how
==ioncore_g
.notifies
.activated
||
768 how
==ioncore_g
.notifies
.inactivated
||
769 how
==ioncore_g
.notifies
.name
||
770 how
==ioncore_g
.notifies
.activity
||
771 how
==ioncore_g
.notifies
.sub_activity
||
772 how
==ioncore_g
.notifies
.tag
){
774 complete
=how
==ioncore_g
.notifies
.name
;
776 frame_update_attrs(frame
);
777 frame_recalc_bar(frame
, complete
);
778 frame_draw_bar(frame
, complete
);
783 static void frame_size_changed_default(WFrame
*frame
,
784 bool wchg
, bool hchg
)
786 int bar_w
=frame
->bar_w
;
789 frame_recalc_bar(frame
, TRUE
);
791 if(frame
->barmode
==FRAME_BAR_SHAPED
&&
792 ((!wchg
&& hchg
) || (wchg
&& bar_w
==frame
->bar_w
))){
793 frame_set_shape(frame
);
798 static void frame_managed_changed(WFrame
*frame
, int mode
, bool sw
,
803 if(mode
!=MPLEX_CHANGE_SWITCHONLY
)
804 frame_initialise_titles(frame
);
806 frame_update_attrs(frame
);
809 need_draw
=!frame_set_background(frame
, FALSE
);
812 frame_draw_bar(frame
, mode
!=MPLEX_CHANGE_SWITCHONLY
);
814 mplex_call_changed_hook((WMPlex
*)frame
,
815 frame_managed_changed_hook
,
820 WRegion
*frame_managed_disposeroot(WFrame
*frame
, WRegion
*reg
)
822 if(DEST_EMPTY(frame
) &&
823 frame
->mplex
.mgd
!=NULL
&&
824 frame
->mplex
.mgd
->reg
==reg
&&
825 frame
->mplex
.mgd
->mgr_next
==NULL
){
826 WRegion
*tmp
=region_disposeroot((WRegion
*)frame
);
827 return (tmp
!=NULL
? tmp
: reg
);
834 int frame_default_index(WFrame
*UNUSED(frame
))
836 return ioncore_g
.frame_default_index
;
843 /*{{{ prepare_manage_transient */
846 WPHolder
*frame_prepare_manage_transient(WFrame
*frame
,
847 const WClientWin
*transient
,
848 const WManageParams
*param
,
851 /* Transient manager searches should not cross tiled frames
852 * unless explicitly floated.
854 if(framemode_is_floating(frame_mode(frame
)) ||
855 extl_table_is_bool_set(transient
->proptab
, "float")){
856 return region_prepare_manage_transient_default((WRegion
*)frame
,
872 ExtlTab
frame_get_configuration(WFrame
*frame
)
874 ExtlTab tab
=mplex_get_configuration(&frame
->mplex
);
876 extl_table_sets_i(tab
, "mode", frame
->mode
);
878 if(frame
->flags
&FRAME_SAVED_VERT
){
879 extl_table_sets_i(tab
, "saved_y", frame
->saved_geom
.y
);
880 extl_table_sets_i(tab
, "saved_h", frame
->saved_geom
.h
);
883 if(frame
->flags
&FRAME_SAVED_HORIZ
){
884 extl_table_sets_i(tab
, "saved_x", frame
->saved_geom
.x
);
885 extl_table_sets_i(tab
, "saved_w", frame
->saved_geom
.w
);
893 void frame_do_load(WFrame
*frame
, ExtlTab tab
)
897 if(extl_table_gets_i(tab
, "saved_x", &p
) &&
898 extl_table_gets_i(tab
, "saved_w", &s
)){
899 frame
->saved_geom
.x
=p
;
900 frame
->saved_geom
.w
=s
;
901 frame
->flags
|=FRAME_SAVED_HORIZ
;
904 if(extl_table_gets_i(tab
, "saved_y", &p
) &&
905 extl_table_gets_i(tab
, "saved_h", &s
)){
906 frame
->saved_geom
.y
=p
;
907 frame
->saved_geom
.h
=s
;
908 frame
->flags
|=FRAME_SAVED_VERT
;
911 mplex_load_contents(&frame
->mplex
, tab
);
915 WRegion
*frame_load(WWindow
*par
, const WFitParams
*fp
, ExtlTab tab
)
917 int mode
=FRAME_MODE_UNKNOWN
;
920 if(!extl_table_gets_i(tab
, "mode", &mode
)){
922 if(extl_table_gets_s(tab
, "mode", &tmp
)){
923 mode
=stringintmap_value(frame_modes
, tmp
, mode
);
928 frame
=create_frame(par
, fp
, mode
, "WFrame");
931 frame_do_load(frame
, tab
);
933 if(DEST_EMPTY(frame
) && frame
->mplex
.mgd
==NULL
){
934 if(frame
->mplex
.misc_phs
!=NULL
){
935 /* Session management hack */
937 fph
=frame_make_recreate_pholder(frame
, ioncore_get_load_pholder());
939 mplex_migrate_phs_to_fph(&frame
->mplex
, fph
);
942 destroy_obj((Obj
*)frame
);
946 return (WRegion
*)frame
;
953 /*{{{ Dynfuntab and class info */
956 static DynFunTab frame_dynfuntab
[]={
957 {region_size_hints
, frame_size_hints
},
959 {mplex_managed_changed
, frame_managed_changed
},
960 {mplex_size_changed
, frame_size_changed_default
},
961 {region_managed_notify
, frame_managed_notify
},
963 {region_activated
, frame_activated
},
964 {region_inactivated
, frame_inactivated
},
966 {(DynFun
*)window_press
, (DynFun
*)frame_press
},
968 {(DynFun
*)region_get_configuration
,
969 (DynFun
*)frame_get_configuration
},
980 {(DynFun
*)region_fitrep
,
981 (DynFun
*)frame_fitrep
},
983 {(DynFun
*)region_managed_disposeroot
,
984 (DynFun
*)frame_managed_disposeroot
},
986 {region_managed_rqgeom_absolute
,
987 frame_managed_rqgeom_absolute
},
989 {(DynFun
*)mplex_default_index
,
990 (DynFun
*)frame_default_index
},
992 {(DynFun
*)region_prepare_manage_transient
,
993 (DynFun
*)frame_prepare_manage_transient
},
995 {(DynFun
*)region_rescue_clientwins
,
996 (DynFun
*)frame_rescue_clientwins
},
1003 IMPLCLASS(WFrame
, WMPlex
, frame_deinit
, frame_dynfuntab
);