]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/clientwin.c
Update cfg_kludge_flash for Flash 10
[ion3.git] / ioncore / clientwin.c
index d80c37b8c73c86395d7879f6d06212f73f47eb2a..11ce2904b56c7d085c5a2924b2b596fa77fbd2f8 100644 (file)
@@ -1,12 +1,9 @@
 /*
  * ion/ioncore/clientwin.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2007
+ * Copyright (c) Tuomo Valkonen 1999-2009
  *
- * 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.
+ * See the included file LICENSE for details.
  */
 
 #include <string.h>
@@ -43,6 +40,7 @@
 #include "bindmaps.h"
 #include "return.h"
 #include "conf.h"
+#include "group.h"
 
 
 static void set_clientwin_state(WClientWin *cwin, int state);
@@ -94,15 +92,36 @@ static WSizePolicy get_sizepolicy_winprop(WClientWin *cwin,
 }
 
 
-#define SIZEHINT_PROPS (CLIENTWIN_PROP_MAXSIZE| \
-                        CLIENTWIN_PROP_MINSIZE| \
-                        CLIENTWIN_PROP_ASPECT| \
-                        CLIENTWIN_PROP_IGNORE_RSZINC)
+#define SIZEHINT_PROPS (CLIENTWIN_PROP_MAXSIZE|   \
+                        CLIENTWIN_PROP_MINSIZE|   \
+                        CLIENTWIN_PROP_ASPECT|    \
+                        CLIENTWIN_PROP_RSZINC|    \
+                        CLIENTWIN_PROP_I_MAXSIZE| \
+                        CLIENTWIN_PROP_I_MINSIZE| \
+                        CLIENTWIN_PROP_I_ASPECT|  \
+                        CLIENTWIN_PROP_I_RSZINC)
+
+
+#define DO_SZH(NAME, FLAG, IFLAG, SZHFLAG, W, H, C)  \
+    if(extl_table_is_bool_set(tab, "ignore_" NAME)){ \
+        cwin->flags|=IFLAG;                          \
+    }else if(extl_table_gets_t(tab, NAME, &tab2)){   \
+        if(extl_table_gets_i(tab2, "w", &i1) &&      \
+           extl_table_gets_i(tab2, "h", &i2)){       \
+            cwin->size_hints.W=i1;                   \
+            cwin->size_hints.H=i2;                   \
+            C                                        \
+            cwin->size_hints.flags|=SZHFLAG;         \
+            cwin->flags|=FLAG;                       \
+        }                                            \
+        extl_unref_table(tab2);                      \
+    }
 
 
 static void clientwin_get_winprops(WClientWin *cwin)
 {
     ExtlTab tab, tab2;
+    char *s;
     int i1, i2;
     
     tab=ioncore_get_winprop(cwin);
@@ -118,54 +137,31 @@ static void clientwin_get_winprops(WClientWin *cwin)
     if(extl_table_is_bool_set(tab, "acrobatic"))
         cwin->flags|=CLIENTWIN_PROP_ACROBATIC;
     
-    if(extl_table_gets_t(tab, "max_size", &tab2)){
-        if(extl_table_gets_i(tab2, "w", &i1) &&
-           extl_table_gets_i(tab2, "h", &i2)){
-            cwin->size_hints.max_width=i1;
-            cwin->size_hints.max_height=i2;
-            cwin->size_hints.flags|=PMaxSize;
-            cwin->flags|=CLIENTWIN_PROP_MAXSIZE;
-        }
-        extl_unref_table(tab2);
-    }
-
-    if(extl_table_gets_t(tab, "min_size", &tab2)){
-        if(extl_table_gets_i(tab2, "w", &i1) &&
-           extl_table_gets_i(tab2, "h", &i2)){
-            cwin->size_hints.min_width=i1;
-            cwin->size_hints.min_height=i2;
-            cwin->size_hints.flags|=PMinSize;
-            cwin->flags|=CLIENTWIN_PROP_MINSIZE;
-        }
-        extl_unref_table(tab2);
-    }
-
-    if(extl_table_gets_t(tab, "aspect", &tab2)){
-        if(extl_table_gets_i(tab2, "w", &i1) &&
-           extl_table_gets_i(tab2, "h", &i2)){
-            cwin->size_hints.min_aspect.x=i1;
-            cwin->size_hints.max_aspect.x=i1;
-            cwin->size_hints.min_aspect.y=i2;
-            cwin->size_hints.max_aspect.y=i2;
-            cwin->size_hints.flags|=PAspect;
-            cwin->flags|=CLIENTWIN_PROP_ASPECT;
-        }
-        extl_unref_table(tab2);
-    }
-    
-    if(extl_table_is_bool_set(tab, "ignore_resizeinc"))
-        cwin->flags|=CLIENTWIN_PROP_IGNORE_RSZINC;
-
+    DO_SZH("max_size", CLIENTWIN_PROP_MAXSIZE, CLIENTWIN_PROP_I_MAXSIZE,
+           PMaxSize, max_width, max_height, );
+           
+    DO_SZH("min_size", CLIENTWIN_PROP_MINSIZE, CLIENTWIN_PROP_I_MINSIZE,
+           PMinSize, min_width, min_height, );
+           
+    DO_SZH("resizeinc", CLIENTWIN_PROP_RSZINC, CLIENTWIN_PROP_I_RSZINC,
+           PResizeInc, width_inc, height_inc, );
+
+    DO_SZH("aspect", CLIENTWIN_PROP_ASPECT, CLIENTWIN_PROP_I_ASPECT,
+           PAspect, min_aspect.x, min_aspect.y, 
+           { cwin->size_hints.max_aspect.x=i1;
+             cwin->size_hints.max_aspect.y=i2;
+           });
+           
     if(extl_table_is_bool_set(tab, "ignore_cfgrq"))
         cwin->flags|=CLIENTWIN_PROP_IGNORE_CFGRQ;
 
-#if 0    
-    cwin->szplcy=get_sizepolicy_winprop(cwin, "sizepolicy", 
-                                        SIZEPOLICY_DEFAULT);
-    cwin->transient_szplcy=get_sizepolicy_winprop(cwin, 
-                                                  "transient_sizepolicy",
-                                                  DFLT_SZPLCY);
-#endif
+    if(extl_table_gets_s(tab, "orientation", &s)){
+        if(strcmp(s, "vertical")==0)
+            cwin->flags|=CLIENTWIN_PROP_O_VERT;
+        else if(strcmp(s, "horizontal")==0)
+            cwin->flags|=CLIENTWIN_PROP_O_HORIZ;
+        free(s);
+    }
 }
 
 
@@ -175,26 +171,37 @@ void clientwin_get_size_hints(WClientWin *cwin)
     
     xwindow_get_sizehints(cwin->win, &(cwin->size_hints));
     
-    if(cwin->flags&CLIENTWIN_PROP_MAXSIZE){
+    if(cwin->flags&CLIENTWIN_PROP_I_MAXSIZE){
+        cwin->size_hints.flags&=~PMaxSize;
+    }else if(cwin->flags&CLIENTWIN_PROP_MAXSIZE){
         cwin->size_hints.max_width=tmp.max_width;
         cwin->size_hints.max_height=tmp.max_height;
         cwin->size_hints.flags|=PMaxSize;
     }
-
-    if(cwin->flags&CLIENTWIN_PROP_MINSIZE){
+    
+    if(cwin->flags&CLIENTWIN_PROP_I_MINSIZE){
+        cwin->size_hints.flags&=~PMinSize;
+    }else if(cwin->flags&CLIENTWIN_PROP_MINSIZE){
         cwin->size_hints.min_width=tmp.min_width;
         cwin->size_hints.min_height=tmp.min_height;
         cwin->size_hints.flags|=PMinSize;
     }
     
-    if(cwin->flags&CLIENTWIN_PROP_ASPECT){
+    if(cwin->flags&CLIENTWIN_PROP_I_ASPECT){
+        cwin->size_hints.flags&=~PAspect;
+    }else if(cwin->flags&CLIENTWIN_PROP_ASPECT){
         cwin->size_hints.min_aspect=tmp.min_aspect;
         cwin->size_hints.max_aspect=tmp.max_aspect;
         cwin->size_hints.flags|=PAspect;
     }
     
-    if(cwin->flags&CLIENTWIN_PROP_IGNORE_RSZINC)
+    if(cwin->flags&CLIENTWIN_PROP_I_RSZINC){
         cwin->size_hints.flags&=~PResizeInc;
+    }else if(cwin->flags&CLIENTWIN_PROP_RSZINC){
+        cwin->size_hints.width_inc=tmp.width_inc;
+        cwin->size_hints.height_inc=tmp.height_inc;
+        cwin->size_hints.flags|=PResizeInc;
+    }
 }
 
 
@@ -314,8 +321,6 @@ static bool clientwin_init(WClientWin *cwin, WWindow *par, Window win,
     
     set_sane_gravity(cwin->win);
 
-    cwin->transient_for=None;
-    
     cwin->n_cmapwins=0;
     cwin->cmap=attr->colormap;
     cwin->cmaps=NULL;
@@ -443,7 +448,6 @@ WClientWin* ioncore_manage_clientwin(Window win, bool maprq)
 
     param.dockapp=FALSE;
     
-again:
     /* Is the window already being managed? */
     cwin=XWINDOW_REGION_OF_T(win, WClientWin);
     if(cwin!=NULL)
@@ -454,51 +458,88 @@ again:
      */
     xwindow_unmanaged_selectinput(win, StructureNotifyMask);
 
+    if(!XGetWindowAttributes(ioncore_g.dpy, win, &attr)){
+        if(maprq)
+            warn(TR("Window %#x disappeared."), win);
+        goto fail2;
+    }
     
     /* Is it a dockapp?
      */
     hints=XGetWMHints(ioncore_g.dpy, win);
-
-    if(hints!=NULL && hints->flags&StateHint)
-        init_state=hints->initial_state;
     
-    if(!param.dockapp && init_state==WithdrawnState && 
-       hints->flags&IconWindowHint && hints->icon_window!=None){
-        /* The dockapp might be displaying its "main" window if no
-         * wm that understands dockapps has been managing it.
-         */
-        if(!maprq)
-            XUnmapWindow(ioncore_g.dpy, win);
-        
-        xwindow_unmanaged_selectinput(win, 0);
-        
-        win=hints->icon_window;
+    if(hints!=NULL){
+        if(hints->flags&StateHint)
+            init_state=hints->initial_state;
+    
+        if(!param.dockapp && init_state==WithdrawnState && 
+           hints->flags&IconWindowHint && hints->icon_window!=None){
+            Window icon_win=hints->icon_window;
+            XWindowAttributes icon_attr;
+            
+            if(!XGetWindowAttributes(ioncore_g.dpy, icon_win, &icon_attr)){
+                if(maprq)
+                    warn(TR("Window %#x disappeared."), win);
+                XFree((void*)hints);
+                goto fail2;
+            }
+             
+            if(!maprq){
+                if(attr.map_state==IsViewable){
+                    /* The dockapp might be displaying its "main" window if no
+                     * wm that understands dockapps has been managing it.
+                     */
+                    XUnmapWindow(ioncore_g.dpy, win);
+                    param.dockapp=TRUE;
+                }else{
+                    /* Main window is unmapped on initial scan, but icon window
+                     * is mapped. Let's hope it's a dockapp left by e.g. us.
+                     */
+                    if(icon_attr.map_state==IsViewable)
+                        param.dockapp=TRUE;
+                }
+            }else{
+                param.dockapp=TRUE;
+            }
+
+            if(param.dockapp){
+                char **p=NULL;
+                int n=0;
+                
+                xwindow_unmanaged_selectinput(win, 0);
+                xwindow_unmanaged_selectinput(icon_win, StructureNotifyMask);
+                
+                /* Copy WM_CLASS as _ION_DOCKAPP_HACK */
+
+                p=xwindow_get_text_property(win, XA_WM_CLASS, &n);
+                
+                if(p!=NULL){
+                    xwindow_set_text_property(icon_win, ioncore_g.atom_dockapp_hack,
+                                              (const char **)p, n);
+                    XFreeStringList(p);
+                }else{
+                    const char *pdummy[2]={"unknowndockapp", "UnknownDockapp"};
+                    xwindow_set_text_property(icon_win, ioncore_g.atom_dockapp_hack,
+                                              pdummy, 2);
+                }
+                
+                win=icon_win;
+                attr=icon_attr;
+            }
+        }
         
-        /* It is a dockapp, do everything again from the beginning, now
-         * with the icon window.
-         */
-        param.dockapp=TRUE;
-        goto again;
-    }
-    
-    if(hints!=NULL)
         XFree((void*)hints);
-
-    if(!XGetWindowAttributes(ioncore_g.dpy, win, &attr)){
-        if(maprq)
-            warn(TR("Window %#x disappeared."), win);
-        goto fail2;
     }
     
-    attr.width=maxof(attr.width, 1);
-    attr.height=maxof(attr.height, 1);
-
     /* Do we really want to manage it? */
     if(!param.dockapp && (attr.override_redirect || 
         (!maprq && attr.map_state!=IsViewable))){
         goto fail2;
     }
 
+    attr.width=maxof(attr.width, 1);
+    attr.height=maxof(attr.height, 1);
+
     /* Find root window */
     FOR_ALL_ROOTWINS(rootwin){
         if(WROOTWIN_ROOT(rootwin)==attr.root)
@@ -520,14 +561,17 @@ again:
 
     param.geom=REGION_GEOM(cwin);
     param.maprq=maprq;
-    param.userpos=(cwin->size_hints.flags&USPosition);
-    param.switchto=(init_state!=IconicState && clientwin_get_switchto(cwin));
     param.jumpto=extl_table_is_bool_set(cwin->proptab, "jumpto");
+    param.switchto=(init_state!=IconicState && 
+                    (param.jumpto || clientwin_get_switchto(cwin)));
     param.gravity=(cwin->size_hints.flags&PWinGravity
                    ? cwin->size_hints.win_gravity
                    : ForgetGravity);
     param.tfor=clientwin_get_transient_for(cwin);
     
+    if(!extl_table_gets_b(cwin->proptab, "userpos", &param.userpos))
+        param.userpos=(cwin->size_hints.flags&USPosition);
+    
     if(cwin->flags&SIZEHINT_PROPS){
         /* If size hints have been messed with, readjust requested geometry
          * here. If programs themselves give incompatible geometries and
@@ -554,7 +598,11 @@ again:
     }
     
     if(postmanage_check(cwin, &attr)){
-        if(param.jumpto && ioncore_g.focus_next==NULL)
+        /* Check for focus_next==NULL does not play nicely with
+         * pointer_focus_hack.
+         */
+        /*if(param.jumpto && ioncore_g.focus_next==NULL)*/
+        if(param.jumpto && !region_manager_is_focusnext((WRegion*)cwin))
             region_goto((WRegion*)cwin);
         hook_call_o(clientwin_mapped_hook, (Obj*)cwin);
         return cwin;
@@ -691,7 +739,13 @@ static bool mrsh_u_extl(ExtlFn fn, void *param)
 
 static void clientwin_do_unmapped(WClientWin *cwin, Window win)
 {
-    region_dispose_((WRegion*)cwin);
+    cwin->flags|=CLIENTWIN_UNMAP_RQ;
+    
+    /* First try a graceful chain-dispose */
+    if(!region_rqdispose((WRegion*)cwin)){
+        /* But force dispose anyway */
+        region_dispose((WRegion*)cwin);
+    }
     
     hook_call(clientwin_unmapped_hook, &win, mrsh_u_c, mrsh_u_extl);
 }
@@ -737,8 +791,8 @@ static bool send_clientmsg(Window win, Atom a, Time stmp)
 
 
 /*EXTL_DOC
- * Attempt to kill (with XKillWindow) the client that owns the X
- * window correspoding to \var{cwin}.
+ * Attempt to kill (with \code{XKillWindow}) the client that owns 
+ * the X window correspoding to \var{cwin}.
  */
 EXTL_EXPORT_MEMBER
 void clientwin_kill(WClientWin *cwin)
@@ -747,7 +801,7 @@ void clientwin_kill(WClientWin *cwin)
 }
 
 
-bool clientwin_rqclose(WClientWin *cwin, bool relocate_ignored)
+void clientwin_rqclose(WClientWin *cwin, bool relocate_ignored)
 {
     /* Ignore relocate parameter -- client windows can always be 
      * destroyed by the application in any case, so way may just as
@@ -757,10 +811,8 @@ bool clientwin_rqclose(WClientWin *cwin, bool relocate_ignored)
     if(cwin->flags&CLIENTWIN_P_WM_DELETE){
         send_clientmsg(cwin->win, ioncore_g.atom_wm_delete, 
                        ioncore_get_timestamp());
-        return TRUE;
     }else{
         warn(TR("Client does not support the WM_DELETE protocol."));
-        return FALSE;
     }
 }
 
@@ -1010,6 +1062,16 @@ static void clientwin_size_hints(WClientWin *cwin, WSizeHints *hints_ret)
 }
 
 
+static int clientwin_orientation(WClientWin *cwin)
+{
+    return (cwin->flags&CLIENTWIN_PROP_O_VERT
+            ? REGION_ORIENTATION_VERTICAL
+            : (cwin->flags&CLIENTWIN_PROP_O_HORIZ
+               ? REGION_ORIENTATION_HORIZONTAL
+               : REGION_ORIENTATION_NONE));
+}
+
+
 /*}}}*/
 
 
@@ -1026,12 +1088,27 @@ EXTL_SAFE
 EXTL_EXPORT_MEMBER
 ExtlTab clientwin_get_ident(WClientWin *cwin)
 {
-    char **p=NULL, *wrole=NULL;
+    char **p=NULL, **p2=NULL, *wrole=NULL;
     int n=0, n2=0, n3=0, tmp=0;
+    Window tforwin=None;
     ExtlTab tab;
+    bool dockapp_hack=FALSE;
     
     p=xwindow_get_text_property(cwin->win, XA_WM_CLASS, &n);
-    wrole=xwindow_get_string_property(cwin->win, ioncore_g.atom_wm_window_role, &n2);
+    
+    p2=xwindow_get_text_property(cwin->win, ioncore_g.atom_dockapp_hack, &n2);
+    
+    dockapp_hack=(n2>0);
+    
+    if(p==NULL){
+        /* Some dockapps do actually have WM_CLASS, so use it. */
+        p=p2;
+        n=n2;
+        p2=NULL;
+    }
+    
+    wrole=xwindow_get_string_property(cwin->win, ioncore_g.atom_wm_window_role, 
+                                      &n3);
     
     tab=extl_create_table();
     if(n>=2 && p[1]!=NULL)
@@ -1041,8 +1118,18 @@ ExtlTab clientwin_get_ident(WClientWin *cwin)
     if(wrole!=NULL)
         extl_table_sets_s(tab, "role", wrole);
     
+    if(XGetTransientForHint(ioncore_g.dpy, cwin->win, &tforwin) 
+       && tforwin!=None){
+        extl_table_sets_b(tab, "is_transient", TRUE);
+    }
+    
+    if(dockapp_hack)
+        extl_table_sets_b(tab, "is_dockapp", TRUE);
+    
     if(p!=NULL)
         XFreeStringList(p);
+    if(p2!=NULL)
+        XFreeStringList(p2);
     if(wrole!=NULL)
         free(wrole);
     
@@ -1056,26 +1143,31 @@ ExtlTab clientwin_get_ident(WClientWin *cwin)
 /*{{{ ConfigureRequest */
 
 
-void clientwin_handle_configure_request(WClientWin *cwin,
-                                        XConfigureRequestEvent *ev)
+static bool check_fs_cfgrq(WClientWin *cwin, XConfigureRequestEvent *ev)
 {
-    if(ev->value_mask&CWBorderWidth)
-        cwin->orig_bw=ev->border_width;
-    
-    if(cwin->flags&CLIENTWIN_PROP_IGNORE_CFGRQ){
-        sendconfig_clientwin(cwin);
-        return;
-    }
-
     /* check full screen request */
     if((ev->value_mask&(CWWidth|CWHeight))==(CWWidth|CWHeight)){
-        bool sw=clientwin_fullscreen_may_switchto(cwin);
-        if(clientwin_check_fullscreen_request(cwin, ev->width, ev->height, sw))
-            return;
+        WRegion *grp=region_groupleader_of((WRegion*)cwin);
+        WScreen *scr=clientwin_fullscreen_chkrq(cwin, ev->width, ev->height);
+        
+        if(scr!=NULL && REGION_MANAGER(grp)!=(WRegion*)scr){
+            bool sw=clientwin_fullscreen_may_switchto(cwin);
+            
+            cwin->flags|=CLIENTWIN_FS_RQ;
+            
+            if(!region_fullscreen_scr(grp, scr, sw))
+                cwin->flags&=~CLIENTWIN_FS_RQ;
+                
+            return TRUE;
+        }
     }
 
-    cwin->flags|=CLIENTWIN_NEED_CFGNTFY;
+    return FALSE;
+}
 
+
+static bool check_normal_cfgrq(WClientWin *cwin, XConfigureRequestEvent *ev)
+{
     if(ev->value_mask&(CWX|CWY|CWWidth|CWHeight)){
         WRQGeomParams rq=RQGEOMPARAMS_INIT;
         int gdx=0, gdy=0;
@@ -1130,6 +1222,25 @@ void clientwin_handle_configure_request(WClientWin *cwin,
         }
         
         region_rqgeom((WRegion*)cwin, &rq, NULL);
+        
+        return TRUE;
+    }
+    
+    return FALSE;
+}
+
+
+void clientwin_handle_configure_request(WClientWin *cwin,
+                                        XConfigureRequestEvent *ev)
+{
+    if(ev->value_mask&CWBorderWidth)
+        cwin->orig_bw=ev->border_width;
+    
+    cwin->flags|=CLIENTWIN_NEED_CFGNTFY;
+
+    if(!(cwin->flags&CLIENTWIN_PROP_IGNORE_CFGRQ)){
+        if(!check_fs_cfgrq(cwin, ev))
+            check_normal_cfgrq(cwin, ev);
     }
 
     if(cwin->flags&CLIENTWIN_NEED_CFGNTFY){
@@ -1213,6 +1324,25 @@ static ExtlTab clientwin_get_configuration(WClientWin *cwin)
 }
 
 
+static void do_sm(ExtlTab tab)
+{
+    SMAddCallback *add_cb;
+    SMCfgCallback *cfg_cb;
+    WPHolder *ph;
+    
+    ioncore_get_sm_callbacks(&add_cb, &cfg_cb);
+    
+    if(add_cb!=NULL){
+        ph=ioncore_get_load_pholder();
+    
+        if(ph!=NULL){
+            if(!add_cb(ph, tab))
+                destroy_obj((Obj*)ph);
+        }
+    }
+}
+
+    
 WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
 {
     double wind=0;
@@ -1221,8 +1351,8 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
     WClientWin *cwin=NULL;
     XWindowAttributes attr;
     WRectangle rg;
-    bool got_chkc;
-
+    bool got_chkc=FALSE;
+    
     if(!extl_table_gets_d(tab, "windowid", &wind) ||
        !extl_table_gets_i(tab, "checkcode", &chkc)){
         return NULL;
@@ -1239,7 +1369,7 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
                                           &real_chkc);
     
     if(!got_chkc || real_chkc!=chkc){
-        ioncore_clientwin_load_missing();
+        do_sm(tab);
         return NULL;
     }
 
@@ -1250,19 +1380,15 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
         return NULL;
     }
     
+    if(attr.root!=region_root_of((WRegion*)par))
+        return NULL;
+        
     if(attr.override_redirect || 
        (ioncore_g.opmode==IONCORE_OPMODE_INIT && attr.map_state!=IsViewable)){
         warn(TR("Saved client window does not want to be managed."));
         return NULL;
     }
-
-    /*
-    attr.x=fp->g.x;
-    attr.y=fp->g.y;
-    attr.width=fp->g.w;
-    attr.height=fp->g.h;
-     */
-
+    
     cwin=create_clientwin(par, win, &attr);
     
     if(cwin==NULL)
@@ -1319,6 +1445,9 @@ static DynFunTab clientwin_dynfuntab[]={
     
     {region_size_hints, 
      clientwin_size_hints},
+     
+    {(DynFun*)region_orientation, 
+     (DynFun*)clientwin_orientation},
     
     {(DynFun*)region_rqclose, 
      (DynFun*)clientwin_rqclose},