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
,
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
, "Notion WFrame"))
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
)
131 CREATEOBJ_IMPL(WFrame
, frame
, (p
, parent
, fp
, mode
));
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 hints_ret
->max_width
+=woff
;
484 hints_ret
->max_height
+=hoff
;
485 hints_ret
->min_width
+=woff
;
486 hints_ret
->min_height
+=hoff
;
489 int f
=frame
->flags
&(FRAME_SHADED
|FRAME_SHADED_TOGGLE
);
491 if(f
==FRAME_SHADED
|| f
==FRAME_SHADED_TOGGLE
){
492 int h
=frame_shaded_height(frame
);
493 hints_ret
->min_height
=h
;
494 hints_ret
->max_height
=h
;
495 hints_ret
->base_height
=h
;
496 if(!hints_ret
->max_set
){
497 hints_ret
->max_width
=INT_MAX
;
498 hints_ret
->max_set
=TRUE
;
508 /*{{{ Client window rqgeom */
511 static void frame_managed_rqgeom_absolute(WFrame
*frame
, WRegion
*sub
,
512 const WRQGeomParams
*rq
,
515 if(!FORWARD_CWIN_RQGEOM(frame
)){
516 region_managed_rqgeom_absolute_default((WRegion
*)frame
, sub
,
519 WRQGeomParams rq2
=RQGEOMPARAMS_INIT
;
520 int gravity
=ForgetGravity
;
525 rq2
.flags
=rq
->flags
&(REGION_RQGEOM_WEAK_ALL
526 |REGION_RQGEOM_TRYONLY
527 |REGION_RQGEOM_ABSOLUTE
);
529 if(rq
->flags
®ION_RQGEOM_GRAVITY
)
532 mplex_managed_geom(&frame
->mplex
, &off
);
535 off
.w
=REGION_GEOM(frame
).w
-off
.w
;
536 off
.h
=REGION_GEOM(frame
).h
-off
.h
;
538 rq2
.geom
.w
=maxof(rq2
.geom
.w
+off
.w
, 0);
539 rq2
.geom
.h
=maxof(rq2
.geom
.h
+off
.h
, 0);
541 /*region_size_hints_correct((WRegion*)frame, &(geom.w), &(geom.h), TRUE);*/
543 /* If WEAK_? is set, then geom.(x|y) is root-relative as it was not
544 * requested by the client and clientwin_handle_configure_request has
545 * no better guess. Otherwise the coordinates are those requested by
546 * the client (modulo borders/gravity) and we interpret them to be
547 * root-relative coordinates for this frame modulo gravity.
549 if(rq
->flags
®ION_RQGEOM_WEAK_X
)
552 rq2
.geom
.x
+=xgravity_deltax(gravity
, -off
.x
, off
.x
+off
.w
);
554 if(rq
->flags
®ION_RQGEOM_WEAK_Y
)
557 rq2
.geom
.y
+=xgravity_deltay(gravity
, -off
.y
, off
.y
+off
.h
);
559 region_rqgeom((WRegion
*)frame
, &rq2
, geomret
);
574 /*{{{ Frame recreate pholder stuff */
577 static WFramedPHolder
*frame_make_recreate_pholder(WFrame
*frame
, WPHolder
*rph
)
579 WFramedParam fparam
=FRAMEDPARAM_INIT
;
580 WFramedPHolder
*fph
=NULL
;
583 fparam
.mode
=frame
->mode
;
585 fph
=create_framedpholder(rph
, &fparam
);
588 destroy_obj((Obj
*)rph
);
595 static void mplex_migrate_phs_to_fph(WMPlex
*mplex
, WFramedPHolder
*fph
)
597 WMPlexPHolder
*phs
, *ph
;
600 mplex
->misc_phs
=NULL
;
602 phs
->recreate_pholder
=fph
;
604 for(ph
=phs
; ph
!=NULL
; ph
=ph
->next
)
610 bool frame_rescue_clientwins(WFrame
*frame
, WRescueInfo
*info
)
614 ret
=mplex_rescue_clientwins(&frame
->mplex
, info
);
616 /* Now, do placeholders.
617 * We can't currently be arsed to keep them ordered with regions...
618 * First we check if we can simply recreate this frame, which takes
619 * care of e.g. floating frames being destroyed when entering full
620 * screen mode. If not, we check if the target would be a WMPlex, and
621 * migrate there. This takes care of frames destroyed in tilings.
623 mplex_flatten_phs(&frame
->mplex
);
625 if(frame
->mplex
.misc_phs
!=NULL
){
626 WPHolder
*ret_ph
=region_make_return_pholder((WRegion
*)frame
);
627 WFramedPHolder
*fph
=frame_make_recreate_pholder(frame
, ret_ph
);
630 mplex_migrate_phs_to_fph(&frame
->mplex
, fph
);
632 WPHolder
*rescueph
=rescueinfo_pholder(info
);
634 WRegion
*target
=pholder_target(rescueph
);
635 WMPlex
*other_mplex
=OBJ_CAST(target
, WMPlex
);
637 if(other_mplex
!=NULL
){
638 assert(other_mplex
!=&frame
->mplex
);
639 mplex_migrate_phs(&frame
->mplex
, other_mplex
);
655 bool frame_set_shaded(WFrame
*frame
, int sp
)
657 bool set
=(frame
->flags
&FRAME_SHADED
);
658 bool nset
=libtu_do_setparam(sp
, set
);
659 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
*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
*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
)
898 if(extl_table_gets_i(tab
, "saved_x", &p
) &&
899 extl_table_gets_i(tab
, "saved_w", &s
)){
900 frame
->saved_geom
.x
=p
;
901 frame
->saved_geom
.w
=s
;
902 frame
->flags
|=FRAME_SAVED_HORIZ
;
905 if(extl_table_gets_i(tab
, "saved_y", &p
) &&
906 extl_table_gets_i(tab
, "saved_h", &s
)){
907 frame
->saved_geom
.y
=p
;
908 frame
->saved_geom
.h
=s
;
909 frame
->flags
|=FRAME_SAVED_VERT
;
912 mplex_load_contents(&frame
->mplex
, tab
);
916 WRegion
*frame_load(WWindow
*par
, const WFitParams
*fp
, ExtlTab tab
)
918 int mode
=FRAME_MODE_UNKNOWN
;
921 if(!extl_table_gets_i(tab
, "mode", &mode
)){
923 if(extl_table_gets_s(tab
, "mode", &tmp
)){
924 mode
=stringintmap_value(frame_modes
, tmp
, mode
);
929 frame
=create_frame(par
, fp
, mode
);
932 frame_do_load(frame
, tab
);
934 if(DEST_EMPTY(frame
) && frame
->mplex
.mgd
==NULL
){
935 if(frame
->mplex
.misc_phs
!=NULL
){
936 /* Session management hack */
938 fph
=frame_make_recreate_pholder(frame
, ioncore_get_load_pholder());
940 mplex_migrate_phs_to_fph(&frame
->mplex
, fph
);
943 destroy_obj((Obj
*)frame
);
947 return (WRegion
*)frame
;
954 /*{{{ Dynfuntab and class info */
957 static DynFunTab frame_dynfuntab
[]={
958 {region_size_hints
, frame_size_hints
},
960 {mplex_managed_changed
, frame_managed_changed
},
961 {mplex_size_changed
, frame_size_changed_default
},
962 {region_managed_notify
, frame_managed_notify
},
964 {region_activated
, frame_activated
},
965 {region_inactivated
, frame_inactivated
},
967 {(DynFun
*)window_press
, (DynFun
*)frame_press
},
969 {(DynFun
*)region_get_configuration
,
970 (DynFun
*)frame_get_configuration
},
981 {(DynFun
*)region_fitrep
,
982 (DynFun
*)frame_fitrep
},
984 {(DynFun
*)region_managed_disposeroot
,
985 (DynFun
*)frame_managed_disposeroot
},
987 {region_managed_rqgeom_absolute
,
988 frame_managed_rqgeom_absolute
},
990 {(DynFun
*)mplex_default_index
,
991 (DynFun
*)frame_default_index
},
993 {(DynFun
*)region_prepare_manage_transient
,
994 (DynFun
*)frame_prepare_manage_transient
},
996 {(DynFun
*)region_rescue_clientwins
,
997 (DynFun
*)frame_rescue_clientwins
},
1004 IMPLCLASS(WFrame
, WMPlex
, frame_deinit
, frame_dynfuntab
);