emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: address@hidden: mouse-autoselect-window needs a delay]


From: martin rudalics
Subject: Re: address@hidden: mouse-autoselect-window needs a delay]
Date: Mon, 03 Jul 2006 19:47:39 +0200
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

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'.
*** 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)))
  
  (defcustom mouse-buffer-menu-maxlen 20
    "*Number of buffers in one pane (submenu) of the buffer menu.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]