Subject: FVWM: Here's a patch for WarpTowindow and FocusOnly functions

From: Brady Montz <[email-masked]>
Date: Fri, 19 Apr 1996 11:56:34 -0700 (MST)

This adds two functions: WarpToWindow and FocusOnly.

WarpToWindow takes two arguments. It moves the viewport to the page containing
the window, then it raises the window, then it warps the cursor to the
specified location in the window. 

WarpToWindow 20 30 moves the cursor the the sport in the window which is 20% 
of the width and 30% of the height. 

WarpToWindow 20p 30p moves the cursor to the pixel (20, 30) in the window.

I used the GetTwoARguments function to parse the arguments, and it doesn't
allow you to mix bwetween pixel and percent types, so you can do something
like: WarpToWindow 20p 90.

If you give it no arguments, it warps to the upper left hand corner, and
giving it a negative argument results in no warping of the cursor at all, so
it just moves the the right page and raises the window.

FocusOnly is pretty simple, and it just changes the focus.

The current Focus function is still there, but this function works fine for me
to get the current Focus behavior:

AddToFunc "MyFocus"
+		"I" WarpToWindow
+		"I" FocusOnly

The only problem I forsee is that the current focus function checks whether
the window is a ClickToFocus window before deciding whether to warp the
cursor, and you obviously lose this now. I think that most people either only
use ClickToFocus all the time, or never, or only for windows that don't ever
need the focus (that's what I do) so this might not be a big problem.

Let me know what you think. I wrote this just this morning, so I expect
problems. Seems to work for me though. Apply the patch in the fvwm-2.0.42
directory.

diff -cr fvwm/builtins.c fvwm-patched/builtins.c
*** fvwm/builtins.c	Wed Apr 10 10:38:25 1996
--- fvwm-patched/builtins.c	Fri Apr 19 11:28:56 1996
***************
*** 145,172 ****
    return FALSE;
  }
  
- 
- 
- 
  /**************************************************************************
   *
!  * Moves focus to specified window 
   *
!  *************************************************************************/
! void FocusOn(FvwmWindow *t,int DeIconifyOnly)
  {
  #ifndef NON_VIRTUAL
    int dx,dy;
    int cx,cy;
  #endif
!   int x,y;
! 
!   if(t == (FvwmWindow *)0)
      return;
  
!   if(t->Desk != Scr.CurrentDesk)
    {
!     changeDesks(0,t->Desk);
    }
  
  #ifndef NON_VIRTUAL
--- 145,171 ----
    return FALSE;
  }
  
  /**************************************************************************
   *
!  * Warps pointer to a specified window
   *
!  **************************************************************************/
! 
! void WarpOn(FvwmWindow *t, int warp_x, int x_unit, int warp_y, 
! 	    int y_unit)
  {
  #ifndef NON_VIRTUAL
    int dx,dy;
    int cx,cy;
  #endif
!   int x, y;
!   
!   if (t == (FvwmWindow *)0 || (t->flags & ICONIFIED && t->icon_w == None))
      return;
  
!   if (t->Desk != Scr.CurrentDesk)
    {
!     changeDesks (0, t->Desk);
    }
  
  #ifndef NON_VIRTUAL
***************
*** 187,204 ****
    MoveViewport(dx,dy,True);
  #endif
  
    if(t->flags & ICONIFIED)
    {
!     x = t->icon_xl_loc + t->icon_w_width/2;
!     y = t->icon_y_loc + t->icon_p_height + ICON_HEIGHT/2;
    }
    else
    {
!     x = t->frame_x;
!     y = t->frame_y;
    }
-   if(!(t->flags & ClickToFocus))
-     XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, x+2,y+2);
    RaiseWindow(t);
    KeepOnTop();
  
--- 186,211 ----
    MoveViewport(dx,dy,True);
  #endif
  
+ 
    if(t->flags & ICONIFIED)
    {
!     x = t->icon_xl_loc + t->icon_w_width/2 + 2;
!     y = t->icon_y_loc + t->icon_p_height + ICON_HEIGHT/2 + 2;
    }
    else
    {
!     if (x_unit != Scr.MyDisplayWidth)
!       x = t->frame_x + 2 + warp_x;
!     else
!       x = t->frame_x + 2 + (t->frame_width - 4) * warp_x / 100;
!     if (y_unit != Scr.MyDisplayHeight) 
!       y = t->frame_y + 2 + warp_y;
!     else
!       y = t->frame_y + 2 + (t->frame_height - 4) * warp_y / 100;
!   }
!   if (warp_x >= 0 && warp_y >= 0) {
!     XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, x, y);
    }
    RaiseWindow(t);
    KeepOnTop();
  
***************
*** 207,216 ****
       (t->frame_x >Scr.MyDisplayWidth)||(t->frame_y>Scr.MyDisplayHeight))
    {
      SetupFrame(t,0,0,t->frame_width, t->frame_height,False);
!     if(!(t->flags & ClickToFocus))
!       XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, 2,2);
    }
    UngrabEm();
    SetFocus(t->w,t,0);
  }
  
--- 214,243 ----
       (t->frame_x >Scr.MyDisplayWidth)||(t->frame_y>Scr.MyDisplayHeight))
    {
      SetupFrame(t,0,0,t->frame_width, t->frame_height,False);
!     XWarpPointer(dpy, None, Scr.Root, 0, 0, 0, 0, 2,2);
    }
    UngrabEm();
+ }
+ 
+ /**************************************************************************
+  *
+  * Moves focus to specified window 
+  *
+  *************************************************************************/
+ void FocusOn(FvwmWindow *t,int DeIconifyOnly, int FocusOnly)
+ {
+ #ifndef NON_VIRTUAL
+   int dx,dy;
+   int cx,cy;
+ #endif
+   int x,y;
+ 
+   if(t == (FvwmWindow *)0)
+     return;
+   
+   if (!FocusOnly) {
+     WarpOn (t, 0, 0, 0, 0);
+   }
    SetFocus(t->w,t,0);
  }
  
***************
*** 747,761 ****
  
    if(val1 != 0)
    {
!     FocusOn((FvwmWindow *)val1,0);
      if (((FvwmWindow *)(val1))->flags & ICONIFIED)
      {
        DeIconify((FvwmWindow *)val1);
!       FocusOn((FvwmWindow *)val1,0);
      }
    }
  }

  void focus_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		unsigned long context, char *action, int *Module)
--- 774,801 ----
  
    if(val1 != 0)
    {
!     FocusOn((FvwmWindow *)val1,0,0);
      if (((FvwmWindow *)(val1))->flags & ICONIFIED)
      {
        DeIconify((FvwmWindow *)val1);
!       FocusOn((FvwmWindow *)val1,0,0);
      }
    }
  }
        
+ void warpwindow_func(XEvent *eventp, Window w, FvwmWindow *tmp_win,
+ 		     unsigned long context, char *action, int *Module)
+ {
+   int val1_unit, val2_unit, n;
+   int val1, val2;
+ 
+   n = GetTwoArguments (action, &val1, &val2, &val1_unit, &val2_unit);
+   
+   if (n == 2)
+     WarpOn (tmp_win, val1, val1_unit, val2, val2_unit);
+   else
+     WarpOn (tmp_win, 0, 0, 0, 0);
+ }
  
  void focus_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		unsigned long context, char *action, int *Module)
***************
*** 763,771 ****
    if (DeferExecution(eventp,&w,&tmp_win,&context,SELECT,ButtonRelease))
      return;
  
!   FocusOn(tmp_win,0);
  }

  void popup_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		unsigned long context, char *action,int *Module)
--- 803,819 ----
    if (DeferExecution(eventp,&w,&tmp_win,&context,SELECT,ButtonRelease))
      return;
  
!   FocusOn(tmp_win,0,0);
  }
  
+ void focusonly_func (XEvent *eventp,Window w,FvwmWindow *tmp_win,
+ 		     unsigned long context, char *action, int *Module)
+ {
+   if (DeferExecution(eventp,&w,&tmp_win,&context,SELECT,ButtonRelease))
+     return;
+   
+   FocusOn(tmp_win,0,1);
+ }
  
  void popup_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		unsigned long context, char *action,int *Module)
diff -cr fvwm/functions.c fvwm-patched/functions.c
*** fvwm/functions.c	Thu Mar 28 08:24:23 1996
--- fvwm-patched/functions.c	Fri Apr 19 11:26:01 1996
***************
*** 54,59 ****
--- 54,60 ----
    {"Exec",         exec_function,    F_EXEC,                FUNC_NO_WINDOW},
    {"ExecUseSHELL", exec_setup,       F_EXEC_SETUP,          FUNC_NO_WINDOW},
    {"Focus",        focus_func,       F_FOCUS,               FUNC_NEEDS_WINDOW},
+   {"FocusOnly",    focusonly_func,   F_FOCUSONLY,           FUNC_NEEDS_WINDOW},
    {"Function",     ComplexFunction,  F_FUNCTION,            FUNC_NO_WINDOW},
    {"GotoPage",     goto_page_func,   F_GOTO_PAGE,           FUNC_NO_WINDOW},
    {"HilightColor", SetHiColor,       F_HICOLOR,             FUNC_NO_WINDOW},
***************
*** 98,103 ****
--- 99,105 ----
    {"Title",        Nop_func,         F_TITLE,               FUNC_TITLE},
    {"Titlestyle",   SetTitleStyle,    F_TITLESTYLE,          FUNC_NO_WINDOW},
    {"Wait",         wait_func,        F_WAIT,                FUNC_NO_WINDOW},
+   {"WarpToWindow", warpwindow_func,  F_WARPTOWINDOW,        FUNC_NEEDS_WINDOW},
    {"WindowFont",   LoadWindowFont,   F_WINDOWFONT,          FUNC_NO_WINDOW},
    {"WindowList",   do_windowList,    F_WINDOWLIST,          FUNC_NO_WINDOW},
    {"WindowsDesk",  changeWindowsDesk,F_CHANGE_WINDOWS_DESK, FUNC_NEEDS_WINDOW},
diff -cr fvwm/icons.c fvwm-patched/icons.c
*** fvwm/icons.c	Thu Apr 11 08:37:37 1996
--- fvwm-patched/icons.c	Fri Apr 19 11:21:40 1996
***************
*** 736,742 ****
      }
  
    if(tmp_win->flags & ClickToFocus)
!     FocusOn(tmp_win,1);
  
    KeepOnTop();
  
--- 736,742 ----
      }
  
    if(tmp_win->flags & ClickToFocus)
!     FocusOn(tmp_win,1,0);
  
    KeepOnTop();
  
diff -cr fvwm/misc.h fvwm-patched/misc.h
*** fvwm/misc.h	Thu Apr  4 16:47:30 1996
--- fvwm-patched/misc.h	Fri Apr 19 11:25:31 1996
***************
*** 274,280 ****
  void KeepOnTop(void);
  void show_panner(void);
  void WaitForButtonsUp(void);
! void FocusOn(FvwmWindow *t,int DeIconifyOnly);
  Bool PlaceWindow(FvwmWindow *tmp_win, unsigned long flags,int Desk);
  void free_window_names (FvwmWindow *tmp, Bool nukename, Bool nukeicon);
  
--- 274,280 ----
  void KeepOnTop(void);
  void show_panner(void);
  void WaitForButtonsUp(void);
! void FocusOn(FvwmWindow *t,int DeIconifyOnly, int FocusOnly);
  Bool PlaceWindow(FvwmWindow *tmp_win, unsigned long flags,int Desk);
  void free_window_names (FvwmWindow *tmp, Bool nukename, Bool nukeicon);
  
***************
*** 381,387 ****
--- 381,391 ----
  	       unsigned long context,char *action, int *Module);
  void raise_it_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		   unsigned long context, char *action, int *Module);
+ void warpwindow_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+ 		unsigned long context, char *action, int *Module);
  void focus_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
+ 		unsigned long context, char *action, int *Module);
+ void focusonly_func(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  		unsigned long context, char *action, int *Module);
  void SendDataToModule(XEvent *eventp,Window w,FvwmWindow *tmp_win,
  			unsigned long context, char *action,int *Module);
diff -cr fvwm/parse.h fvwm-patched/parse.h
*** fvwm/parse.h	Thu Mar 28 08:24:48 1996
--- fvwm-patched/parse.h	Fri Apr 19 11:26:29 1996
***************
*** 85,90 ****
--- 85,92 ----
  #define F_RAISELOWER            108
  #define F_MAXIMIZE              109
  #define F_FOCUS                 110
+ #define F_WARPTOWINDOW          111
+ #define F_FOCUSONLY             112
  
  /* Functions for use by modules only! */
  #define F_SEND_WINDOW_LIST     1000
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Nobutaka Suzuki <[email-masked]>
Date: Sat, 20 Apr 1996 16:12:36 +0900

bradym> This adds two functions: WarpToWindow and FocusOnly.
...snip...
bradym> FocusOnly is pretty simple, and it just changes the focus.

FocusOnly would be useful for the problem that FvwmPager
terminates with BadMatch error as well, I think. With the
following patch to MoveWindow() in x_pager.c, FocusOnly should be
executed *after* WindowDesk (on line 1417 of x_pager.c) so
BadMatch error might be avoided.   
----
Nobutaka Suzuki <[email-masked]> 
 Graduate School of Information Science
 Nara Institute of Science and Technology

--- x_pager.c.orig	Mon Mar 25 02:33:47 1996
+++ x_pager.c	Sat Apr 20 15:26:38 1996
@@ -1438,9 +1438,9 @@
       if(Scr.CurrentDesk == t->desk)
 	{
 	  if(t->flags & ICONIFIED)
-	    XSetInputFocus (dpy, t->icon_w, RevertToParent, Event->xbutton.time); 
+            SendInfo(fd,"FocusOnly",t->icon_w);
 	  else
-	    XSetInputFocus (dpy, t->w, RevertToParent, Event->xbutton.time);
+            SendInfo(fd,"FocusOnly",t->w);
 	}
     }
 }

---

From: Grant Beattie <[email-masked]>
Date: Sun, 21 Apr 1996 19:50:56 +1000 (EST)

Hi everyone,

I've turned off auto-placement in ~/.fvwm2rc, but it still 
auto-positions windows. Here's the relevant bits:

############################################################################
# WINDOW Placement
#
# SmartPlacement makes new windows pop-up in blank regions of screen 
# Style "*" SmartPlacement

# If SmartPlacement fails, this places it randomly instead of making you do it
# Style "*" RandomPlacement

It seems to be using random placement, BTW.

>From the config, I would have thought this turns random AND smart 
placement off...

any ideas?

-<*>-   Grant Beattie - http://www.cbl.com.au/~gb/   -<*>-
-                  Mariah is my Hero and                 -
-                will Always Be My Baby...               -
-<*>-                                                -<*>-

---

From: Austin Donnelly <[email-masked]>
Date: Sun, 21 Apr 96 16:11 BST

> auto-positions windows. Here's the relevant bits:

You need to say:

Style "*" SmartPlacement, ActivePlacement

Chuck: can you make ActivePlacement the default, this isn't the first
time this question has come up.

Austin

---

From: Todd Tyrone Fries <[email-masked]>
Date: Sun, 21 Apr 1996 15:19:22 -0600 (MDT)

> time this question has come up.

Here is a thought.  Perhaps it could be configurable somehow what the default,
compiled-in defaults are.  Like have a file tiat is a config file, called
internal.fvwmrc, and then have a script change each line to the function calls
put in the ?fvwm.c? file (no source avail at this moment), and output it to
internal_defs.h, and then just #include that file ...

This would be a no brainer and I could submit patches if anyone is interested.
-- 
Todd Fries

---

From: Kai Grossjohann <[email-masked]>
Date: 22 Apr 1996 11:07:01 +0200

>>>>> On Fri, 19 Apr 1996 11:56:34 -0700 (MST), Brady Montz
>>>>> <[email-masked]> said:

  Brady> [...] I think that most people either only use ClickToFocus
  Brady> all the time, or never, or only for windows that don't ever
  Brady> need the focus (that's what I do) so this might not be a big
  Brady> problem.

FWIW, I use ClickToFocus for Netscrape windows because their handling
of popup windows (such as the file selector box that comes up after
Alt-S) is broken; the problem can be circumvented by using
ClickToFocus.

kai
--
There ain't no cure for the summertime blues.

---

From: Chris Rode <[email-masked]>
Date: Mon, 22 Apr 1996 12:18:44 CDT

Kai Grossjohann <[email-masked]> wrote:

}FWIW, I use ClickToFocus for Netscrape windows because their handling
}of popup windows (such as the file selector box that comes up after
}Alt-S) is broken; the problem can be circumvented by using
}ClickToFocus.

	Looking through the fvwm2 manpage, ClickToFocus is nowhere to
	be found.  perhaps it should be added in the Style section...?

--chris.

--
chris rode - [email-masked]                -- Help Room Consultant
http://www.public.iastate.edu/~crode/         -- 138 Durham Center, 294-1314
"why don't we just have a stupidity    depeche mode, erasure, moby, new order,
 tax? just tax the stupid people!"     pet shop boys and recoil rock my world.