]> git.decadent.org.uk Git - ion3.git/blob - ioncore/group-cw.c
dc5cc69e6b43aca6dadc2e8cbc9e05a73aae8e47
[ion3.git] / ioncore / group-cw.c
1 /*
2  * ion/ioncore/group-cw.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2006. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <string.h>
13
14 #include <libtu/objp.h>
15 #include <libmainloop/defer.h>
16
17 #include "common.h"
18 #include "group-cw.h"
19 #include "clientwin.h"
20 #include "regbind.h"
21 #include "bindmaps.h"
22 #include "frame.h"
23 #include "resize.h"
24 #include "pholder.h"
25 #include "names.h"
26 #include "framedpholder.h"
27 #include "grouppholder.h"
28
29
30 #define DFLT_SZPLCY SIZEPOLICY_FREE_GLUE__SOUTH
31
32
33 /*{{{ Add/remove managed */
34
35
36 WRegion *create_transient_frame(WWindow *par, 
37                                 const WFitParams *fp)
38 {
39     return (WRegion*)create_frame(par, fp, FRAME_MODE_TRANSIENT);
40 }
41
42
43 static WPHolder *groupcw_transient_pholder(WGroupCW *cwg, 
44                                            const WClientWin *cwin,
45                                            const WManageParams *mp)
46 {
47     WGroupAttachParams param=GROUPATTACHPARAMS_INIT;
48     WFramedParam fp=FRAMEDPARAM_INIT;
49     WPHolder *ph;
50     
51     param.level_set=1;
52     param.level=STACKING_LEVEL_MODAL1;
53     
54     param.szplcy_set=1;
55     param.szplcy=cwg->transient_szplcy;
56     
57     param.switchto_set=1;
58     param.switchto=1;
59
60     param.geom_weak_set=1;
61     param.geom_weak=REGION_RQGEOM_WEAK_ALL;
62     
63     if(!ioncore_g.framed_transients){
64         param.geom_set=TRUE;
65         param.geom=mp->geom;
66         
67         return (WPHolder*)create_grouppholder(&cwg->grp, NULL, &param);
68     }else{
69         fp.inner_geom_gravity_set=1;
70         fp.inner_geom=mp->geom;
71         fp.gravity=ForgetGravity;
72         fp.mkframe=create_transient_frame;
73         
74         ph=(WPHolder*)create_grouppholder(&cwg->grp, NULL, &param);
75         
76         return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
77     }
78 }
79
80
81 WPHolder *groupcw_prepare_manage(WGroupCW *cwg, const WClientWin *cwin,
82                                  const WManageParams *param, int redir)
83 {
84     if(redir==MANAGE_REDIR_STRICT_YES)
85         return NULL;
86     
87     /* Only catch windows with transient mode set to current here. */
88     if(clientwin_get_transient_mode(cwin)!=TRANSIENT_MODE_CURRENT)
89         return NULL;
90     
91     return groupcw_transient_pholder(cwg, cwin, param);
92 }
93
94
95 static bool groupcw_should_manage_transient(WGroupCW *cwg, 
96                                             WClientWin *tfor)
97 {
98     WRegion *mgr;
99     
100     if(group_find_stacking(&cwg->grp, (WRegion*)tfor))
101         return TRUE;
102  
103     mgr=REGION_MANAGER(tfor);
104     
105     if(mgr!=NULL && ioncore_g.framed_transients && OBJ_IS(mgr, WFrame))
106         return (group_find_stacking(&cwg->grp, mgr)!=NULL);
107     
108     return FALSE;
109 }
110
111
112 WPHolder *groupcw_prepare_manage_transient(WGroupCW *cwg, 
113                                            const WClientWin *transient,
114                                            const WManageParams *param,
115                                            int unused)
116 {
117     WPHolder *ph=region_prepare_manage_transient_default((WRegion*)cwg,
118                                                          transient,
119                                                          param,
120                                                          unused);
121     
122     if(ph==NULL && groupcw_should_manage_transient(cwg, param->tfor))
123         ph=groupcw_transient_pholder(cwg, transient, param);
124
125     return ph;
126 }
127
128
129 /*}}}*/
130
131
132 /*{{{ Misc. */
133
134
135 /*_EXTL_DOC
136  * Toggle transients managed by \var{cwin} between top/bottom
137  * of the window.
138  */
139 EXTL_EXPORT_MEMBER
140 void groupcw_toggle_transients_pos(WGroupCW *cwg)
141 {
142     WStacking *st;
143     WGroupIterTmp tmp;
144     
145     if((cwg->transient_szplcy&SIZEPOLICY_VERT_MASK)==SIZEPOLICY_VERT_TOP){
146         cwg->transient_szplcy&=~SIZEPOLICY_VERT_MASK;
147         cwg->transient_szplcy|=SIZEPOLICY_VERT_BOTTOM;
148     }else{
149         cwg->transient_szplcy&=~SIZEPOLICY_VERT_MASK;
150         cwg->transient_szplcy|=SIZEPOLICY_VERT_TOP;
151     }
152
153     FOR_ALL_NODES_IN_GROUP(&cwg->grp, st, tmp){
154         st->szplcy&=~SIZEPOLICY_VERT_MASK;
155         st->szplcy|=(cwg->transient_szplcy&SIZEPOLICY_VERT_MASK);
156         
157         if(st->reg!=NULL){
158             WFitParams fp;
159
160             fp.g=REGION_GEOM(cwg);
161             
162             sizepolicy(&st->szplcy, st->reg, NULL, 
163                        REGION_RQGEOM_WEAK_ALL, &fp);
164             region_fitrep(st->reg, NULL, &fp);
165         }
166     }
167 }
168
169
170 const char *groupcw_displayname(WGroupCW *cwg)
171 {
172     const char *name=NULL;
173     
174     if(cwg->grp.bottom!=NULL && cwg->grp.bottom->reg!=NULL)
175         name=region_name(cwg->grp.bottom->reg);
176     
177     if(name==NULL)
178         name=region_name((WRegion*)cwg);
179     
180     return name;
181 }
182
183
184 void groupcw_managed_notify(WGroupCW *cwg, WRegion *reg, const char *how)
185 {
186     if(group_bottom(&cwg->grp)==reg 
187        && strcmp(how, "name")==0){
188         /* Title has changed */
189         region_notify_change((WRegion*)cwg, how);
190     }
191 }
192
193
194 /*}}}*/
195
196
197 /*{{{ WGroupCW class */
198
199
200 bool groupcw_init(WGroupCW *cwg, WWindow *parent, const WFitParams *fp)
201 {
202     cwg->transient_szplcy=DFLT_SZPLCY;
203     /*cwg->fs_pholder=NULL;*/
204     
205     if(!group_init(&(cwg->grp), parent, fp))
206         return FALSE;
207     
208     cwg->grp.bottom_last_close=TRUE;
209
210     region_add_bindmap((WRegion*)cwg, ioncore_groupcw_bindmap);
211     
212     return TRUE;
213 }
214
215
216 WGroupCW *create_groupcw(WWindow *parent, const WFitParams *fp)
217 {
218     CREATEOBJ_IMPL(WGroupCW, groupcw, (p, parent, fp));
219 }
220
221
222 void groupcw_deinit(WGroupCW *cwg)
223 {    
224     group_deinit(&(cwg->grp));
225 }
226
227
228 WRegion *groupcw_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
229 {
230     WGroupCW *ws;
231     ExtlTab substab, subtab;
232     int i, n;
233     
234     ws=create_groupcw(par, fp);
235     
236     if(ws==NULL)
237         return NULL;
238         
239     if(!extl_table_gets_t(tab, "managed", &substab))
240         return (WRegion*)ws;
241
242     n=extl_table_get_n(substab);
243     for(i=1; i<=n; i++){
244         if(extl_table_geti_t(substab, i, &subtab)){
245             group_attach_new(&ws->grp, subtab);
246             extl_unref_table(subtab);
247         }
248     }
249     
250     extl_unref_table(substab);
251     
252     if(ws->grp.managed_list==NULL){
253         destroy_obj((Obj*)ws);
254         return NULL;
255     }
256
257     return (WRegion*)ws;
258 }
259
260
261 static DynFunTab groupcw_dynfuntab[]={
262     {(DynFun*)region_prepare_manage, 
263      (DynFun*)groupcw_prepare_manage},
264     
265     {(DynFun*)region_prepare_manage_transient,
266      (DynFun*)groupcw_prepare_manage_transient},
267     
268     /*
269     {(DynFun*)region_handle_drop,
270      (DynFun*)groupcw_handle_drop},
271     
272     {(DynFun*)group_do_add_managed,
273      (DynFun*)groupcw_do_add_managed},
274     */
275     
276     /*
277     {(DynFun*)region_get_rescue_pholder_for,
278      (DynFun*)groupcw_get_rescue_pholder_for},
279      */
280     
281     {(DynFun*)region_prepare_manage,
282      (DynFun*)groupcw_prepare_manage},
283
284     {(DynFun*)region_prepare_manage_transient,
285      (DynFun*)groupcw_prepare_manage_transient},
286     
287     {(DynFun*)region_displayname,
288      (DynFun*)groupcw_displayname},
289     
290     {region_managed_notify,
291      groupcw_managed_notify},
292     
293     END_DYNFUNTAB
294 };
295
296
297 EXTL_EXPORT
298 IMPLCLASS(WGroupCW, WGroup, groupcw_deinit, groupcw_dynfuntab);
299
300
301 /*}}}*/
302