]> git.decadent.org.uk Git - ion3.git/blob - ioncore/manage.c
[svn-inject] Installing original source of ion3
[ion3.git] / ioncore / manage.c
1 /*
2  * ion/ioncore/manage.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 <libtu/objp.h>
13 #include <libextl/extl.h>
14 #include "global.h"
15 #include "common.h"
16 #include "region.h"
17 #include "manage.h"
18 #include "names.h"
19 #include "fullscreen.h"
20 #include "pointer.h"
21 #include "netwm.h"
22 #include "extlconv.h"
23
24
25 /*{{{ Add */
26
27
28 WScreen *clientwin_find_suitable_screen(WClientWin *cwin, 
29                                         const WManageParams *param)
30 {
31     WScreen *scr=NULL, *found=NULL;
32     bool respectpos=(param->tfor!=NULL || param->userpos);
33     
34     FOR_ALL_SCREENS(scr){
35         if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin))
36             continue;
37         if(REGION_IS_ACTIVE(scr)){
38             found=scr;
39             if(!respectpos)
40                 break;
41         }
42         
43         if(rectangle_contains(&REGION_GEOM(scr), param->geom.x, param->geom.y)){
44             found=scr;
45             if(respectpos)
46                 break;
47         }
48         
49         if(found==NULL)
50             found=scr;
51     }
52     
53     return found;
54 }
55
56
57 bool clientwin_do_manage_default(WClientWin *cwin, 
58                                  const WManageParams *param)
59 {
60     WRegion *r=NULL, *r2;
61     WScreen *scr=NULL;
62     WPHolder *ph=NULL;
63     int fs=-1;
64     int swf;
65     bool ok, tmp;
66
67     /* Check if param->tfor or any of its managers want to manage cwin. */
68     if(param->tfor!=NULL){
69         assert(param->tfor!=cwin);
70         ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin, 
71                                            param, 0);
72     }
73     
74     /* Find a suitable screen */
75     scr=clientwin_find_suitable_screen(cwin, param);
76     if(scr==NULL){
77         warn(TR("Unable to find a screen for a new client window."));
78         return FALSE;
79     }
80     
81     if(ph==NULL){
82         /* Find a placeholder for non-fullscreen state */
83         ph=region_prepare_manage((WRegion*)scr, cwin, param,
84                                  MANAGE_REDIR_PREFER_YES);
85     }
86     
87     /* Check fullscreen mode */
88     if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp))
89         fs=tmp;
90
91     if(fs<0)
92         fs=netwm_check_initial_fullscreen(cwin, param->switchto);
93     
94     if(fs<0){
95         fs=clientwin_check_fullscreen_request(cwin, 
96                                               param->geom.w,
97                                               param->geom.h,
98                                               param->switchto);
99     }
100
101     if(fs>0){
102         /* Full-screen mode succesfull. */
103         if(pholder_target(ph)==(WRegion*)scr){
104             /* Discard useless placeholder. */
105             destroy_obj((Obj*)ph);
106             return TRUE;
107         }
108         assert(cwin->fs_pholder==NULL);
109         cwin->fs_pholder=ph;
110         return TRUE;
111     }
112         
113     if(ph==NULL)
114         return FALSE;
115     
116     /* Not in full-screen mode; use the placeholder to attach. */
117     
118     swf=(param->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
119     ok=pholder_attach(ph, swf, (WRegion*)cwin);
120     destroy_obj((Obj*)ph);
121     
122     return ok;
123 }
124
125
126 /*}}}*/
127
128
129 /*{{{ region_prepare_manage/region_manage_clientwin/etc. */
130
131
132 WPHolder *region_prepare_manage(WRegion *reg, const WClientWin *cwin,
133                                 const WManageParams *param, int redir)
134 {
135     WPHolder *ret=NULL;
136     CALL_DYN_RET(ret, WPHolder*, region_prepare_manage, reg, 
137                  (reg, cwin, param, redir));
138     return ret;
139 }
140
141
142 WPHolder *region_prepare_manage_default(WRegion *reg, const WClientWin *cwin,
143                                         const WManageParams *param, int redir)
144 {
145     WRegion *curr;
146     
147     if(redir==MANAGE_REDIR_STRICT_NO)
148         return NULL;
149     
150     curr=region_current(reg);
151     
152     if(curr==NULL)
153         return NULL;
154         
155     return region_prepare_manage(curr, cwin, param, MANAGE_REDIR_PREFER_YES);
156 }
157
158
159 WPHolder *region_prepare_manage_transient(WRegion *reg, 
160                                           const WClientWin *cwin,
161                                           const WManageParams *param,
162                                           int unused)
163 {
164     WPHolder *ret=NULL;
165     CALL_DYN_RET(ret, WPHolder*, region_prepare_manage_transient, reg, 
166                  (reg, cwin, param, unused));
167     return ret;
168 }
169
170
171 WPHolder *region_prepare_manage_transient_default(WRegion *reg, 
172                                                   const WClientWin *cwin,
173                                                   const WManageParams *param,
174                                                   int unused)
175 {
176     WRegion *mgr=REGION_MANAGER(reg);
177     
178     if(mgr!=NULL)
179         return region_prepare_manage_transient(mgr, cwin, param, unused);
180     else
181         return NULL;
182 }
183
184
185 bool region_manage_clientwin(WRegion *reg, WClientWin *cwin,
186                              const WManageParams *par, int redir)
187 {
188     bool ret;
189     WPHolder *ph=region_prepare_manage(reg, cwin, par, redir);
190     int swf=(par->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
191     
192     if(ph==NULL)
193         return FALSE;
194     
195     ret=pholder_attach(ph, swf, (WRegion*)cwin);
196     
197     destroy_obj((Obj*)ph);
198     
199     return ret;
200 }
201
202
203 /*}}}*/
204
205
206 /*{{{ Rescue */
207
208
209 static WRegion *iter_children(void *st)
210 {
211     WRegion **nextp=(WRegion**)st;
212     WRegion *next=*nextp;
213     *nextp=(next==NULL ? NULL : next->p_next);
214     return next;   
215 }
216
217
218 bool region_rescue_child_clientwins(WRegion *reg, WPHolder *ph)
219 {
220     WRegion *next=reg->children;
221     return region_rescue_some_clientwins(reg, ph, iter_children, &next);
222 }
223
224
225 bool region_rescue_some_clientwins(WRegion *reg, WPHolder *ph,
226                                    WRegionIterator *iter, void *st)
227 {
228     bool res=FALSE;
229     int fails=0;
230
231     reg->flags|=REGION_CWINS_BEING_RESCUED;
232     
233     while(TRUE){
234         WRegion *tosave=iter(st);
235         
236         if(tosave==NULL)
237             break;
238         
239         if(!OBJ_IS(tosave, WClientWin)){
240             if(!region_rescue_clientwins(tosave, ph))
241                 fails++;
242         }else{
243             if(!pholder_attach(ph, 0, tosave))
244                 fails++;
245         }
246     }
247     
248     reg->flags&=~REGION_CWINS_BEING_RESCUED;
249
250     return (fails==0);
251 }
252
253
254 bool region_rescue_clientwins(WRegion *reg, WPHolder *ph)
255 {
256     bool ret=FALSE;
257     CALL_DYN_RET(ret, bool, region_rescue_clientwins, reg, (reg, ph));
258     return ret;
259 }
260
261
262 /*}}}*/
263
264
265 /*{{{ Misc. */
266
267
268 ExtlTab manageparams_to_table(const WManageParams *mp)
269 {
270     ExtlTab t=extl_create_table();
271     extl_table_sets_b(t, "switchto", mp->switchto);
272     extl_table_sets_b(t, "jumpto", mp->jumpto);
273     extl_table_sets_b(t, "userpos", mp->userpos);
274     extl_table_sets_b(t, "dockapp", mp->dockapp);
275     extl_table_sets_b(t, "maprq", mp->maprq);
276     extl_table_sets_i(t, "gravity", mp->gravity);
277     extl_table_sets_rectangle(t, "geom", &(mp->geom));
278     extl_table_sets_o(t, "tfor", (Obj*)(mp->tfor));
279     
280     return t;
281 }
282
283
284 /*}}}*/