+++ /dev/null
-/*
- * ion/mod_panews/placement.h
- *
- * Copyright (c) Tuomo Valkonen 1999-2006.
- *
- * 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
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- */
-
-#include <limits.h>
-#include <math.h>
-#include <string.h>
-
-#include <libtu/minmax.h>
-#include <libtu/objp.h>
-#include <libextl/extl.h>
-#include <libmainloop/defer.h>
-
-#include <ioncore/common.h>
-#include <ioncore/global.h>
-#include <ioncore/clientwin.h>
-#include <ioncore/attach.h>
-#include <ioncore/manage.h>
-#include <ioncore/framep.h>
-#include <ioncore/names.h>
-#include <ioncore/resize.h>
-#include <mod_tiling/split.h>
-#include <mod_tiling/split-stdisp.h>
-#include "placement.h"
-#include "panews.h"
-#include "splitext.h"
-#include "unusedwin.h"
-
-
-WHook *panews_init_layout_alt=NULL;
-WHook *panews_make_placement_alt=NULL;
-
-
-/*{{{ create_frame_for */
-
-
-static WFrame *create_frame_for(WPaneWS *ws, WRegion *reg)
-{
- WWindow *par=REGION_PARENT(ws);
- WFitParams fp;
- WRectangle mg;
- WFrame *frame;
-
- if(par==NULL)
- return NULL;
-
- fp.g=REGION_GEOM(ws);
- fp.mode=REGION_FIT_BOUNDS;
-
- frame=(WFrame*)ws->tiling.create_frame_fn(par, &fp);
-
- if(frame==NULL)
- return NULL;
-
- frame->flags|=FRAME_DEST_EMPTY;
-
- mplex_managed_geom((WMPlex*)frame, &mg);
-
- fp.g.w=REGION_GEOM(reg).w+(REGION_GEOM(frame).w-mg.w);
- fp.g.h=REGION_GEOM(reg).h+(REGION_GEOM(frame).h-mg.h);
- fp.mode=REGION_FIT_EXACT;
-
- region_fitrep((WRegion*)frame, NULL, &fp);
-
- return (WFrame*)frame;
-}
-
-
-/*}}}*/
-
-
-/*{{{ Placement scan */
-
-
-static bool mrsh_layout_extl(ExtlFn fn, WPaneWSPlacementParams *p)
-{
- ExtlTab t=extl_create_table();
- bool ret=FALSE;
-
- extl_table_sets_o(t, "ws", (Obj*)p->ws);
- extl_table_sets_o(t, "frame", (Obj*)p->frame);
- extl_table_sets_o(t, "reg", (Obj*)p->reg);
- extl_table_sets_o(t, "specifier", (Obj*)p->specifier);
-
- extl_protect(NULL);
- extl_call(fn, "t", "b", t, &ret);
- extl_unprotect(NULL);
-
- if(ret){
- ret=FALSE;
-
- extl_table_gets_i(t, "res_w", &(p->res_w));
- extl_table_gets_i(t, "res_h", &(p->res_h));
-
- if(extl_table_gets_o(t, "res_node", (Obj**)&(p->res_node))){
- if(OBJ_IS(p->res_node, WSplitUnused)){
- if(!extl_table_gets_t(t, "res_config", &(p->res_config))){
- warn(TR("Malfunctioning placement hook; condition #%d."), 1);
- goto err;
- }
- }else if(!OBJ_IS(p->res_node, WSplitRegion)){
- warn(TR("Malfunctioning placement hook; condition #%d."), 2);
- goto err;
- }
- }
- }
-
- extl_unref_table(t);
-
- return ret;
-
-err:
- p->res_node=NULL;
- extl_unref_table(t);
- return FALSE;
-}
-
-
-static bool plainregionfilter(WSplit *node)
-{
- return (strcmp(OBJ_TYPESTR(node), "WSplitRegion")==0);
-}
-
-
-static bool fallback_filter(WSplit *node)
-{
- return (OBJ_IS(node, WSplitUnused) || plainregionfilter(node));
-}
-
-
-static bool fallback_layout(WPaneWSPlacementParams *p)
-{
- if(p->ws->tiling.split_tree==NULL)
- return FALSE;
-
- if(p->specifier!=NULL){
- p->res_node=(WSplit*)p->specifier;
- }else{
- p->res_node=split_current_todir(p->ws->tiling.split_tree, SPLIT_ANY,
- PRIMN_ANY, fallback_filter);
- }
-
- if(p->res_node!=NULL && OBJ_IS(p->res_node, WSplitUnused)){
- p->res_config=extl_create_table();
- if(p->res_config==extl_table_none() || p->frame==NULL)
- return FALSE;
- extl_table_sets_o(p->res_config, "reg", (Obj*)(p->frame));
- }
-
- return (p->res_node!=NULL);
-}
-
-
-/*}}}*/
-
-
-/*{{{ Split/replace unused code */
-
-
-static bool do_replace(WPaneWS *ws, WFrame *frame, WRegion *reg,
- WPaneWSPlacementParams *rs)
-{
- WSplit *u=rs->res_node;
- WSplit *node=tiling_load_node(&(ws->tiling), &(u->geom), rs->res_config);
-
- assert(OBJ_IS(u, WSplitUnused));
-
- if(node==NULL){
- warn(TR("Malfunctioning placement hook; condition #%d."), 3);
- return FALSE;
- }
-
- if(REGION_MANAGER(frame)!=(WRegion*)ws){
- warn(TR("Malfunctioning placement hook; condition #%d."), 4);
- destroy_obj((Obj*)node);
- return FALSE;
- }
-
- if(u->parent!=NULL)
- splitinner_replace(u->parent, u, node);
- else
- splittree_changeroot((WSplit*)u, node);
-
- u->parent=NULL;
- mainloop_defer_destroy((Obj*)u);
-
- if(ws->tiling.stdispnode!=NULL)
- split_regularise_stdisp(ws->tiling.stdispnode);
-
- if(ws->tiling.split_tree!=NULL)
- split_restack(ws->tiling.split_tree, ws->tiling.dummywin, Above);
-
- return TRUE;
-}
-
-/*}}}*/
-
-
-/*{{{ The main dynfun */
-
-
-static bool current_unused(WPaneWS *ws)
-{
- return OBJ_IS(tiling_current(&ws->tiling), WUnusedWin);
-}
-
-
-static WRegion *panews_get_target(WPaneWS *ws, WSplitUnused *specifier,
- WRegion *reg)
-{
- WRegion *target=NULL;
- WFrame *frame=create_frame_for(ws, reg);
- WSplit **tree=&(ws->tiling.split_tree);
- WPaneWSPlacementParams rs;
-
- assert(ws->tiling.split_tree!=NULL);
-
- rs.ws=ws;
- rs.frame=frame;
- rs.reg=reg;
- rs.specifier=specifier;
- rs.res_node=NULL;
- rs.res_config=extl_table_none();
- rs.res_w=-1;
- rs.res_h=-1;
-
- if(frame!=NULL){
- split_update_bounds(*tree, TRUE);
-
- assert(panews_make_placement_alt!=NULL);
-
- hook_call_p(panews_make_placement_alt, &rs,
- (WHookMarshallExtl*)mrsh_layout_extl);
- }
-
- if(rs.res_node==NULL && specifier==NULL)
- fallback_layout(&rs);
-
- if(rs.res_node!=NULL){
- /* Resize */
- if(rs.res_w>0 || rs.res_h>0){
- WRectangle grq=rs.res_node->geom;
- int gflags=REGION_RQGEOM_WEAK_ALL;
-
- if(rs.res_w>0){
- grq.w=rs.res_w;
- gflags&=~REGION_RQGEOM_WEAK_W;
- }
-
- if(rs.res_h>0){
- grq.h=rs.res_h;
- gflags&=~REGION_RQGEOM_WEAK_H;
- }
-
- splittree_rqgeom(rs.res_node, gflags, &grq, NULL);
- }
-
- if(OBJ_IS(rs.res_node, WSplitUnused)){
- if(frame!=NULL){
- if(do_replace(ws, frame, reg, &rs))
- target=(WRegion*)frame;
- }
- }else{
- assert(OBJ_IS(rs.res_node, WSplitRegion));
- target=((WSplitRegion*)rs.res_node)->reg;
- }
-
- extl_unref_table(rs.res_config);
- }
-
- if(frame!=NULL && target!=(WRegion*)frame)
- destroy_obj((Obj*)frame);
-
- if(target!=NULL && current_unused(ws))
- region_goto(target);
-
- return target;
-}
-
-
-WPHolder *panews_prepare_manage(WPaneWS *ws, const WClientWin *cwin,
- const WManageParams *param, int redir)
-{
- WRegion *target=panews_get_target(ws, NULL, (WRegion*)cwin);
- WPHolder *ph;
-
- if(target!=NULL){
- ph=region_prepare_manage(target, cwin, param, MANAGE_REDIR_PREFER_YES);
- if(ph!=NULL)
- return ph;
- }
-
- warn(TR("Ooops... could not find a region to attach client window to "
- "on workspace %s."), region_name((WRegion*)ws));
- return NULL;
-}
-
-
-bool panews_handle_unused_drop(WPaneWS *ws, WSplitUnused *specifier,
- WRegion *reg)
-{
- WRegion *target=panews_get_target(ws, specifier, reg);
-
- if(target==NULL || !OBJ_IS(target, WMPlex))
- return FALSE;
-
- return (mplex_attach_simple((WMPlex*)target, reg,
- MPLEX_ATTACH_SWITCHTO)!=NULL);
-}
-
-
-/*}}}*/
-