/*
* ion/ioncore/manage.c
*
- * Copyright (c) Tuomo Valkonen 1999-2006.
+ * Copyright (c) Tuomo Valkonen 1999-2007.
*
* Ion is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
#include "pointer.h"
#include "netwm.h"
#include "extlconv.h"
+#include "return.h"
+#include "conf.h"
+#include "group-ws.h"
/*{{{ Add */
FOR_ALL_SCREENS(scr){
if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin))
continue;
- if(REGION_IS_ACTIVE(scr)){
- found=scr;
- if(!respectpos)
- break;
- }
-
- if(rectangle_contains(®ION_GEOM(scr), param->geom.x, param->geom.y)){
- found=scr;
- if(respectpos)
- break;
+
+ if(!OBJ_IS(scr, WRootWin)){
+ /* The root window itself is only a fallback */
+
+ if(REGION_IS_ACTIVE(scr)){
+ found=scr;
+ if(!respectpos)
+ break;
+ }
+
+ if(rectangle_contains(®ION_GEOM(scr),
+ param->geom.x, param->geom.y)){
+ found=scr;
+ if(respectpos)
+ break;
+ }
}
if(found==NULL)
}
+/*extern WRegion *ioncore_newly_created;*/
+
+
+static WPHolder *try_target(WClientWin *cwin, const WManageParams *param,
+ const char *target)
+{
+ WRegion *r=ioncore_lookup_region(target, NULL);
+
+ if(r==NULL)
+ return NULL;
+
+ return region_prepare_manage(r, cwin, param, MANAGE_REDIR_PREFER_NO);
+}
+
+
+static bool handle_target_winprops(WClientWin *cwin, const WManageParams *param,
+ WScreen *scr, WPHolder **ph_ret)
+{
+ char *layout=NULL, *target=NULL;
+ WPHolder *ph=NULL;
+ bool mgd=FALSE;
+
+ if(extl_table_gets_s(cwin->proptab, "target", &target))
+ ph=try_target(cwin, param, target);
+
+ if(ph==NULL && extl_table_gets_s(cwin->proptab, "new_group", &layout)){
+ ExtlTab lo=ioncore_get_layout(layout);
+
+ free(layout);
+
+ if(lo!=extl_table_none()){
+ WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;
+ int mask=MPLEX_ATTACH_SWITCHTO;
+ WRegion *reg;
+
+ if(param->switchto)
+ par.flags|=MPLEX_ATTACH_SWITCHTO;
+
+ /*ioncore_newly_created=(WRegion*)cwin;*/
+
+ reg=mplex_attach_new_(&scr->mplex, &par, mask, lo);
+
+ extl_unref_table(lo);
+
+ /*ioncore_newly_created=NULL;*/
+
+ mgd=(region_manager((WRegion*)cwin)!=NULL);
+
+ if(reg!=NULL && !mgd){
+ if(target!=NULL)
+ ph=try_target(cwin, param, target);
+
+ if(ph==NULL){
+ ph=region_prepare_manage(reg, cwin, param,
+ MANAGE_REDIR_PREFER_YES);
+
+ if(ph==NULL)
+ destroy_obj((Obj*)reg);
+ }
+ }
+ }
+ }
+
+ if(target!=NULL)
+ free(target);
+
+ *ph_ret=ph;
+
+ return mgd;
+}
+
+
bool clientwin_do_manage_default(WClientWin *cwin,
const WManageParams *param)
{
int swf;
bool ok, tmp;
- /* Check if param->tfor or any of its managers want to manage cwin. */
- if(param->tfor!=NULL){
- assert(param->tfor!=cwin);
- ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin,
- param, 0);
- }
-
/* Find a suitable screen */
scr=clientwin_find_suitable_screen(cwin, param);
if(scr==NULL){
return FALSE;
}
+ if(handle_target_winprops(cwin, param, scr, &ph))
+ return TRUE;
+
+ /* Check if param->tfor or any of its managers want to manage cwin. */
+ if(ph==NULL && param->tfor!=NULL){
+ assert(param->tfor!=cwin);
+ ph=region_prepare_manage_transient((WRegion*)param->tfor, cwin,
+ param, 0);
+ }
+
if(ph==NULL){
/* Find a placeholder for non-fullscreen state */
ph=region_prepare_manage((WRegion*)scr, cwin, param,
MANAGE_REDIR_PREFER_YES);
- }
-
- /* Check fullscreen mode */
- if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp))
- fs=tmp;
- if(fs<0)
- fs=netwm_check_initial_fullscreen(cwin, param->switchto);
+ /* Check fullscreen mode. (This is intentionally not done
+ * for transients and windows with target winprops.)
+ */
+ if(extl_table_gets_b(cwin->proptab, "fullscreen", &tmp))
+ fs=tmp;
+
+ if(fs<0)
+ fs=netwm_check_initial_fullscreen(cwin, param->switchto);
- if(fs<0){
- fs=clientwin_check_fullscreen_request(cwin,
- param->geom.w,
- param->geom.h,
- param->switchto);
+ if(fs<0){
+ fs=clientwin_check_fullscreen_request(cwin,
+ param->geom.w,
+ param->geom.h,
+ param->switchto);
+ }
}
if(fs>0){
destroy_obj((Obj*)ph);
return TRUE;
}
- assert(cwin->fs_pholder==NULL);
- cwin->fs_pholder=ph;
+
+ if(!region_do_set_return((WRegion*)cwin, ph))
+ destroy_obj((Obj*)ph);
+
return TRUE;
}