unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: martin rudalics <rudalics@gmx.at>
Cc: cyd@stupidchicken.com, simon.marshall@misys.com, emacs-devel@gnu.org
Subject: Re: [simon.marshall@misys.com: mouse-autoselect-window needs a	delay]
Date: Mon, 03 Jul 2006 19:47:39 +0200	[thread overview]
Message-ID: <44A9583B.1030408@gmx.at> (raw)
In-Reply-To: <E1FwGqQ-0007qp-Jt@fencepost.gnu.org>

[-- Attachment #1: Type: text/plain, Size: 925 bytes --]

Richard Stallman schrieb:
>     1. Suppose I have two windows - SW is the selected one and UW the
>     unselected one.  I move the mouse to the menubar as described in Simon's
>     original scenario.  UW should not be selected here.  However, I then
>     change my mind and move the mouse to UW.  I suppose that UW should be
>     selected now - agreed?
> 
> Yes.  The question is how to distinguish the two cases.  I thought
> someone people suggested using a time delay for that, right.
> 
>     2. Currently `mouse-leave-buffer-hook' is not run when autoselecting
>     a window.  I believe this is a bug that should be resolved - agreed?
> 
> Yes, I think so; this should exit an isearch.
> 
> 

The attached patch is a first approximation.  I've been able to test this
on Windows 98 only, hence I would be glad to hear if this works in a general
context too - simply customize the variable `mouse-autoselect-window'.

[-- Attachment #2: mouse-autoselect-window.patch --]
[-- Type: text/plain, Size: 15412 bytes --]

*** dispextern.h	Sun Jul  2 09:50:00 2006
--- dispextern.h	Sun Jul  2 11:35:22 2006
***************
*** 2690,2696 ****
  extern int help_echo_pos;
  extern struct frame *last_mouse_frame;
  extern int last_tool_bar_item;
! extern int mouse_autoselect_window;
  extern int unibyte_display_via_language_environment;

  extern void reseat_at_previous_visible_line_start P_ ((struct it *));
--- 2690,2697 ----
  extern int help_echo_pos;
  extern struct frame *last_mouse_frame;
  extern int last_tool_bar_item;
! extern Lisp_Object mouse_autoselect_window;
! extern Lisp_Object mouse_autoselect_window_function;
  extern int unibyte_display_via_language_environment;

  extern void reseat_at_previous_visible_line_start P_ ((struct it *));

*** macterm.c	Sun Jul  2 09:50:00 2006
--- macterm.c	Mon Jul  3 10:03:42 2006
***************
*** 10562,10568 ****
  		  else
  		    {
  		      /* Generate SELECT_WINDOW_EVENTs when needed.  */
! 		      if (mouse_autoselect_window)
  			{
  			  Lisp_Object window;

--- 10562,10568 ----
  		  else
  		    {
  		      /* Generate SELECT_WINDOW_EVENTs when needed.  */
! 		      if (!NILP (mouse_autoselect_window))
  			{
  			  Lisp_Object window;

***************
*** 10571,10589 ****
  							    mouse_pos.v,
  							    0, 0, 0, 0);

! 			  /* Window will be selected only when it is
! 			     not selected now and last mouse movement
! 			     event was not in it.  Minibuffer window
! 			     will be selected iff it is active.  */
! 			  if (WINDOWP (window)
! 			      && !EQ (window, last_window)
! 			      && !EQ (window, selected_window))
  			    {
  			      inev.kind = SELECT_WINDOW_EVENT;
  			      inev.frame_or_window = window;
  			    }
! 
! 			  last_window=window;
  			}
  		      if (!note_mouse_movement (f, &mouse_pos))
  			help_echo_string = previous_help_echo_string;
--- 10571,10596 ----
  							    mouse_pos.v,
  							    0, 0, 0, 0);

! 			  if (NUMBERP (mouse_autoselect_window))
! 			    /* Let mouse_autoselect_window_function handle this. */
  			    {
+ 			      if (!NILP (mouse_autoselect_window_function))
+ 				call2 (mouse_autoselect_window_function,
+ 				       last_window, window);
+ 			    }
+ 			  else if (WINDOWP (window)
+ 				   && !EQ (window, last_window)
+ 				   && !EQ (window, selected_window))
+ 			    /* Window will be selected only when it is
+ 			       not selected now and last mouse movement
+ 			       event was not in it.  Minibuffer window
+ 			       will be selected iff it is active.  */
+ 			    {
+ 			      call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
  			      inev.kind = SELECT_WINDOW_EVENT;
  			      inev.frame_or_window = window;
  			    }
! 			  last_window = window;
  			}
  		      if (!note_mouse_movement (f, &mouse_pos))
  			help_echo_string = previous_help_echo_string;

*** msdos.c	Sun Jul  2 12:09:26 2006
--- msdos.c	Mon Jul  3 10:03:46 2006
***************
*** 3387,3400 ****
  						      mouse_last_x,
  						      mouse_last_y,
  						      0, 0, 0, 0);
! 	      /* A window will be selected only when it is not
! 		 selected now, and the last mouse movement event was
! 		 not in it.  A minibuffer window will be selected iff
! 		 it is active.  */
! 	      if (WINDOWP (mouse_window)
! 		  && !EQ (mouse_window, last_mouse_window)
! 		  && !EQ (mouse_window, selected_window))
  		{
  		  event.kind = SELECT_WINDOW_EVENT;
  		  event.frame_or_window = mouse_window;
  		  event.arg = Qnil;
--- 3387,3408 ----
  						      mouse_last_x,
  						      mouse_last_y,
  						      0, 0, 0, 0);
! 	      if (NUMBERP (mouse_autoselect_window))
! 		/* Let mouse_autoselect_window_function handle this. */
  		{
+ 		  if (!NILP (mouse_autoselect_window_function))
+ 		    call2 (mouse_autoselect_window_function,
+ 			   last_window, mouse_window);
+ 		}
+ 	      else if (WINDOWP (mouse_window)
+ 		       && !EQ (mouse_window, last_mouse_window)
+ 		       && !EQ (mouse_window, selected_window))
+ 		/* A window will be selected only when it is not
+ 		   selected now, and the last mouse movement event was
+ 		   not in it.  A minibuffer window will be selected iff
+ 		   it is active.  */
+ 		{
+ 		  call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
  		  event.kind = SELECT_WINDOW_EVENT;
  		  event.frame_or_window = mouse_window;
  		  event.arg = Qnil;

*** w32term.c	Sun Jul  2 09:50:02 2006
--- w32term.c	Sun Jul  2 12:02:38 2006
***************
*** 4286,4292 ****
  	  if (f)
  	    {
  	      /* Generate SELECT_WINDOW_EVENTs when needed.  */
! 	      if (mouse_autoselect_window)
  		{
  		  Lisp_Object window;
  		  int x = LOWORD (msg.msg.lParam);
--- 4286,4292 ----
  	  if (f)
  	    {
  	      /* Generate SELECT_WINDOW_EVENTs when needed.  */
! 	      if (!NILP (mouse_autoselect_window))
  		{
  		  Lisp_Object window;
  		  int x = LOWORD (msg.msg.lParam);
***************
*** 4294,4312 ****

  		  window = window_from_coordinates (f, x, y, 0, 0, 0, 0);

! 		  /* Window will be selected only when it is not
! 		     selected now and last mouse movement event was
! 		     not in it.  Minibuffer window will be selected
! 		     iff it is active.  */
! 		  if (WINDOWP(window)
! 		      && !EQ (window, last_window)
! 		      && !EQ (window, selected_window))
  		    {
  		      inev.kind = SELECT_WINDOW_EVENT;
  		      inev.frame_or_window = window;
  		    }
! 
! 		  last_window=window;
  		}
  	      if (!note_mouse_movement (f, &msg.msg))
  		help_echo_string = previous_help_echo_string;
--- 4294,4319 ----

  		  window = window_from_coordinates (f, x, y, 0, 0, 0, 0);

! 		  if (NUMBERP (mouse_autoselect_window))
! 		    /* Let mouse_autoselect_window_function handle this. */
  		    {
+ 		      if (!NILP (mouse_autoselect_window_function))
+ 			call2 (mouse_autoselect_window_function,
+ 			       last_window, window);
+ 		    }
+ 		  else if (WINDOWP(window)
+ 			   && !EQ (window, last_window)
+ 			   && !EQ (window, selected_window))
+ 		    /* Window will be selected only when it is not
+ 		       selected now and last mouse movement event was
+ 		       not in it.  Minibuffer window will be selected
+ 		       iff it is active.  */
+ 		    {
+ 		      call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
  		      inev.kind = SELECT_WINDOW_EVENT;
  		      inev.frame_or_window = window;
  		    }
! 		  last_window = window;
  		}
  	      if (!note_mouse_movement (f, &msg.msg))
  		help_echo_string = previous_help_echo_string;

*** xdisp.c	Sun Jul  2 09:50:02 2006
--- xdisp.c	Mon Jul  3 19:29:14 2006
***************
*** 256,264 ****
  Lisp_Object Vfontification_functions;
  Lisp_Object Qfontification_functions;

! /* Non-zero means automatically select any window when the mouse
     cursor moves into it.  */
! int mouse_autoselect_window;

  /* Non-zero means draw tool bar buttons raised when the mouse moves
     over them.  */
--- 256,268 ----
  Lisp_Object Vfontification_functions;
  Lisp_Object Qfontification_functions;

! /* Non-nil means automatically select any window when the mouse
!    cursor moves into it.  If a number wait that many seconds before.  */
! Lisp_Object mouse_autoselect_window;
! 
! /* Function called to automatically select a window when the mouse
     cursor moves into it.  */
! Lisp_Object mouse_autoselect_window_function;

  /* Non-zero means draw tool bar buttons raised when the mouse moves
     over them.  */
***************
*** 23933,23941 ****
  See `set-window-redisplay-end-trigger'.  */);
    Vredisplay_end_trigger_functions = Qnil;

!   DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
!     doc: /* *Non-nil means autoselect window with mouse pointer.  */);
!   mouse_autoselect_window = 0;

    DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
      doc: /* *Non-nil means automatically resize tool-bars.
--- 23937,23958 ----
  See `set-window-redisplay-end-trigger'.  */);
    Vredisplay_end_trigger_functions = Qnil;

!   DEFVAR_LISP ("mouse-autoselect-window", &mouse_autoselect_window,
!     doc: /* *Non-nil means autoselect windows with mouse pointer.
! If nil, do not autoselect windows.  If t, autoselection occurs instantaneously. 
! A number means delay autoselection by that many seconds: A window is selected iff
! Emacs can establish that the mouse has remained in that window quiescent for the
! time indicated by the delay.  Note that autoselection does not occur before this
! delay has elapsed at least twice.  Hence, a delay of 0.5 secs means that a new
! window may be selected after 1, 1.5, 2, 2.5, ... seconds.  A delay of less than
! 0.1 seconds is automatically translated into a delay of 0.1 seconds.  */);
!   mouse_autoselect_window = Qnil;
! 
!   DEFVAR_LISP ("mouse-autoselect-window-function", &mouse_autoselect_window_function,
! 	       doc: /* If non-nil, function to run when autoselecting a new window.
! The function is called with two arguments, the window that has been left and the
! window that is entered.  */);
!   mouse_autoselect_window_function = Qnil;

    DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
      doc: /* *Non-nil means automatically resize tool-bars.

*** xterm.c	Sun Jul  2 12:10:00 2006
--- xterm.c	Mon Jul  3 10:03:50 2006
***************
*** 6583,6600 ****
                                                    event.xmotion.x, event.xmotion.y,
                                                    0, 0, 0, 0);

!                 /* Window will be selected only when it is not selected now and
!                    last mouse movement event was not in it.  Minibuffer window
!                    will be selected iff it is active.  */
!                 if (WINDOWP (window)
!                     && !EQ (window, last_window)
!                     && !EQ (window, selected_window))
!                   {
!                     inev.ie.kind = SELECT_WINDOW_EVENT;
!                     inev.ie.frame_or_window = window;
!                   }
! 
!                 last_window=window;
                }
              if (!note_mouse_movement (f, &event.xmotion))
  	      help_echo_string = previous_help_echo_string;
--- 6583,6608 ----
                                                    event.xmotion.x, event.xmotion.y,
                                                    0, 0, 0, 0);

! 		if (NUMBERP (mouse_autoselect_window))
! 		  /* Let mouse_autoselect_window_function handle this. */
! 		  {
! 		    if (!NILP (mouse_autoselect_window_function))
! 		      call2 (mouse_autoselect_window_function,
! 			     last_window, window);
! 		  }
! 		else if (WINDOWP(window)
! 			 && !EQ (window, last_window)
! 			 && !EQ (window, selected_window))
! 		  /* Window will be selected only when it is not
! 		     selected now and last mouse movement event was
! 		     not in it.  Minibuffer window will be selected
! 		     iff it is active.  */
! 		  {
! 		    call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
! 		    inev.ie.kind = SELECT_WINDOW_EVENT;
! 		    inev.ie.frame_or_window = window;
! 		  }
! 		last_window = window;
                }
              if (!note_mouse_movement (f, &event.xmotion))
  	      help_echo_string = previous_help_echo_string;

*** cus-start.el	Sun Jul  2 11:41:42 2006
--- cus-start.el	Sun Jul  2 11:40:24 2006
***************
*** 360,365 ****
--- 360,370 ----
  					    (other :tag "Unlimited" t)))
  	     (unibyte-display-via-language-environment mule boolean)
  	     (blink-cursor-alist cursor alist "22.1")
+              (mouse-autoselect-window display
+ 				      (choice (const :tag "Off" nil)
+ 					      (number :tag "Delay" 0.5)
+ 					      (const :tag "Immediate" t))
+ 				      "21.3")
  	     ;; xfaces.c
  	     (scalable-fonts-allowed display boolean)
  	     ;; xfns.c
***************
*** 369,375 ****
  	     (x-gtk-show-hidden-files menu boolean "22.1")
  	     (x-gtk-whole-detached-tool-bar x boolean "22.1")
  	     ;; xterm.c
-              (mouse-autoselect-window display boolean "21.3")
  	     (x-use-underline-position-properties display boolean "21.3")
  	     (x-stretch-cursor display boolean "21.1")))
        this symbol group type standard version native-p
--- 374,379 ----

*** mouse.el	Sun Jul  2 09:49:56 2006
--- mouse.el	Mon Jul  3 19:30:50 2006
***************
*** 1728,1733 ****
--- 1728,1793 ----
  			   (buffer-substring
  			    (overlay-start mouse-secondary-overlay)
  			    (overlay-end mouse-secondary-overlay)))))))
+ 
+ (defvar mouse-autoselect-window-timer nil
+   "Timer used by timer-driven window autoselection.")
+ 
+ (defvar mouse-autoselect-window-position nil
+   "Last mouse position calculated during timer-driven window autoselection.")
+ 
+ (defun mouse-autoselect-window-cancel ()
+   "Terminate timer-driven window autoselection."
+   (when (timerp mouse-autoselect-window-timer)
+     (cancel-timer mouse-autoselect-window-timer))
+   (remove-hook 'pre-command-hook 'mouse-autoselect-window-cancel))
+ 
+ (defun mouse-autoselect-window-start (last-window current-window)
+   "Initiate timer-driven window autoselection.
+ This function is called when the mouse was moved and the variable
+ `mouse-autoselect-window' has a numeric value.  LAST-WINDOW is the last
+ window where the mouse was seen.  CURRENT-WINDOW is the window where the
+ mouse now appears.  Both arguments are currently ignored."
+   (mouse-autoselect-window-cancel)
+   (let ((delay (max (if (numberp mouse-autoselect-window)
+ 			mouse-autoselect-window
+ 		      0.5)
+ 		    ;; Avoid a zero delay here, use 0.1 secs as minimum.
+ 		    0.1)))
+     ;; Reset `mouse-autoselect-window-position' to nil.  We can't set this to
+     ;; `mouse-position' immediately since we'd risk breaking active region
+     ;; highlighting and mode-line related functions.  As a consequence, a window
+     ;; can't be selected before `mouse-autoselect-window' has elapsed twice.
+     (setq mouse-autoselect-window-position nil)
+     (setq mouse-autoselect-window-timer
+ 	  (run-at-time t delay 'mouse-autoselect-window-select))
+     (add-hook 'pre-command-hook 'mouse-autoselect-window-cancel)))
+ 
+ (setq mouse-autoselect-window-function 'mouse-autoselect-window-start)
+ 
+ (defun mouse-autoselect-window-select ()
+   "Select window with timer-driven autoselection of windows.
+ Select window where the mouse appears provided the mouse has not moved
+ for at least `mouse-autoselect-window' seconds and the window is not yet
+ selected.  The minibuffer window is selected iff the minibuffer is
+ active."
+   (condition-case nil
+       (let ((mouse-position (mouse-position)))
+ 	(if (equal mouse-position mouse-autoselect-window-position)
+ 	    ;; mouse-position has stabilized, try to select a new window,
+ 	    ;; cancel timer-driven autoselection in any case.
+ 	    (let* ((window (window-at (cadr mouse-position)
+ 				      (cddr mouse-position)
+ 				      (car mouse-position))))
+ 	      (setq mouse-autoselect-window-position nil)
+ 	      (mouse-autoselect-window-cancel)
+ 	      (when (and window (not (eq window (selected-window)))
+ 			 (or (not (window-minibuffer-p window))
+ 			     (eq window (active-minibuffer-window))))
+ 		(run-hooks 'mouse-leave-buffer-hook)
+ 		(select-window window)))
+ 	  ;; mouse-position has not stabilized yet, record new position.
+ 	  (setq mouse-autoselect-window-position mouse-position)))
+     (error nil)))
  \f
  (defcustom mouse-buffer-menu-maxlen 20
    "*Number of buffers in one pane (submenu) of the buffer menu.


[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

  reply	other threads:[~2006-07-03 17:47 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-24 23:22 [simon.marshall@misys.com: mouse-autoselect-window needs a delay] Richard Stallman
2006-06-24 23:36 ` Chong Yidong
2006-06-28 17:25   ` Richard Stallman
2006-06-29 16:37     ` martin rudalics
2006-06-30 11:07       ` Richard Stallman
2006-07-03 17:47         ` martin rudalics [this message]
2006-06-26 11:37 ` Kim F. Storm
2006-06-26 15:30   ` Robert J. Chassell
2006-06-27 16:14   ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44A9583B.1030408@gmx.at \
    --to=rudalics@gmx.at \
    --cc=cyd@stupidchicken.com \
    --cc=emacs-devel@gnu.org \
    --cc=simon.marshall@misys.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).