4 * Copyright (c) Tuomo Valkonen 1999-2007.
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.
12 #include <libtu/objp.h>
13 #include <libextl/extl.h>
19 #include "fullscreen.h"
31 WScreen *clientwin_find_suitable_screen(WClientWin *cwin,
32 const WManageParams *param)
34 WScreen *scr=NULL, *found=NULL;
35 bool respectpos=(param->tfor!=NULL || param->userpos);
38 if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin))
41 if(!OBJ_IS(scr, WRootWin)){
42 /* The root window itself is only a fallback */
44 if(REGION_IS_ACTIVE(scr)){
50 if(rectangle_contains(®ION_GEOM(scr),
51 param->geom.x, param->geom.y)){
66 /*extern WRegion *ioncore_newly_created;*/
69 static WPHolder *try_target(WClientWin *cwin, const WManageParams *param,
72 WRegion *r=ioncore_lookup_region(target, NULL);
77 return region_prepare_manage(r, cwin, param, MANAGE_REDIR_PREFER_NO);
81 static bool handle_target_winprops(WClientWin *cwin, const WManageParams *param,
82 WScreen *scr, WPHolder **ph_ret)
84 char *layout=NULL, *target=NULL;
88 if(extl_table_gets_s(cwin->proptab, "target", &target))
89 ph=try_target(cwin, param, target);
91 if(ph==NULL && extl_table_gets_s(cwin->proptab, "new_group", &layout)){
92 ExtlTab lo=ioncore_get_layout(layout);
96 if(lo!=extl_table_none()){
97 WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;
98 int mask=MPLEX_ATTACH_SWITCHTO;
102 par.flags|=MPLEX_ATTACH_SWITCHTO;
104 /*ioncore_newly_created=(WRegion*)cwin;*/
106 reg=mplex_attach_new_(&scr->mplex, &par, mask, lo);
108 extl_unref_table(lo);
110 /*ioncore_newly_created=NULL;*/
112 mgd=(region_manager((WRegion*)cwin)!=NULL);
114 if(reg!=NULL && !mgd){
116 ph=try_target(cwin, param, target);
119 ph=region_prepare_manage(reg, cwin, param,
120 MANAGE_REDIR_PREFER_YES);
123 destroy_obj((Obj*)reg);
138 bool clientwin_do_manage_default(WClientWin *cwin,
139 const WManageParams *param)
141 WRegion *r=NULL, *r2;
148 /* Find a suitable screen */
149 scr=clientwin_find_suitable_screen(cwin, param);
151 warn(TR("Unable to find a screen for a new client window."));
155 if(handle_target_winprops(cwin, param, scr, &ph))
158 /* Check if param->tfor or any of its managers want to manage cwin. */
159 if(ph==NULL && param->tfor!=NULL){
160 assert(param->tfor!=cwin);
161 ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin,
166 /* Find a placeholder for non-fullscreen state */
167 ph=region_prepare_manage((WRegion*)scr, cwin, param,
168 MANAGE_REDIR_PREFER_YES);
170 /* Check fullscreen mode. (This is intentionally not done
171 * for transients and windows with target winprops.)
173 if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp))
177 fs=netwm_check_initial_fullscreen(cwin, param->switchto);
180 fs=clientwin_check_fullscreen_request(cwin,
188 /* Full-screen mode succesfull. */
189 if(pholder_target(ph)==(WRegion*)scr){
190 /* Discard useless placeholder. */
191 destroy_obj((Obj*)ph);
195 if(!region_do_set_return((WRegion*)cwin, ph))
196 destroy_obj((Obj*)ph);
204 /* Not in full-screen mode; use the placeholder to attach. */
206 swf=(param->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
207 ok=pholder_attach(ph, swf, (WRegion*)cwin);
208 destroy_obj((Obj*)ph);
217 /*{{{ region_prepare_manage/region_manage_clientwin/etc. */
220 WPHolder *region_prepare_manage(WRegion *reg, const WClientWin *cwin,
221 const WManageParams *param, int redir)
224 CALL_DYN_RET(ret, WPHolder*, region_prepare_manage, reg,
225 (reg, cwin, param, redir));
230 WPHolder *region_prepare_manage_default(WRegion *reg, const WClientWin *cwin,
231 const WManageParams *param, int redir)
235 if(redir==MANAGE_REDIR_STRICT_NO)
238 curr=region_current(reg);
243 return region_prepare_manage(curr, cwin, param, MANAGE_REDIR_PREFER_YES);
247 WPHolder *region_prepare_manage_transient(WRegion *reg,
248 const WClientWin *cwin,
249 const WManageParams *param,
253 CALL_DYN_RET(ret, WPHolder*, region_prepare_manage_transient, reg,
254 (reg, cwin, param, unused));
259 WPHolder *region_prepare_manage_transient_default(WRegion *reg,
260 const WClientWin *cwin,
261 const WManageParams *param,
264 WRegion *mgr=REGION_MANAGER(reg);
267 return region_prepare_manage_transient(mgr, cwin, param, unused);
273 bool region_manage_clientwin(WRegion *reg, WClientWin *cwin,
274 const WManageParams *par, int redir)
277 WPHolder *ph=region_prepare_manage(reg, cwin, par, redir);
278 int swf=(par->switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
283 ret=pholder_attach(ph, swf, (WRegion*)cwin);
285 destroy_obj((Obj*)ph);
297 static WRegion *iter_children(void *st)
299 WRegion **nextp=(WRegion**)st;
300 WRegion *next=*nextp;
301 *nextp=(next==NULL ? NULL : next->p_next);
306 bool region_rescue_child_clientwins(WRegion *reg, WPHolder *ph)
308 WRegion *next=reg->children;
309 return region_rescue_some_clientwins(reg, ph, iter_children, &next);
313 bool region_rescue_some_clientwins(WRegion *reg, WPHolder *ph,
314 WRegionIterator *iter, void *st)
319 reg->flags|=REGION_CWINS_BEING_RESCUED;
322 WRegion *tosave=iter(st);
327 if(!OBJ_IS(tosave, WClientWin)){
328 if(!region_rescue_clientwins(tosave, ph))
331 if(!pholder_attach(ph, 0, tosave))
336 reg->flags&=~REGION_CWINS_BEING_RESCUED;
342 bool region_rescue_clientwins(WRegion *reg, WPHolder *ph)
345 CALL_DYN_RET(ret, bool, region_rescue_clientwins, reg, (reg, ph));
356 ExtlTab manageparams_to_table(const WManageParams *mp)
358 ExtlTab t=extl_create_table();
359 extl_table_sets_b(t, "switchto", mp->switchto);
360 extl_table_sets_b(t, "jumpto", mp->jumpto);
361 extl_table_sets_b(t, "userpos", mp->userpos);
362 extl_table_sets_b(t, "dockapp", mp->dockapp);
363 extl_table_sets_b(t, "maprq", mp->maprq);
364 extl_table_sets_i(t, "gravity", mp->gravity);
365 extl_table_sets_rectangle(t, "geom", &(mp->geom));
366 extl_table_sets_o(t, "tfor", (Obj*)(mp->tfor));