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 de lay]


From: martin rudalics
Subject: Re: address@hidden: mouse-autoselect-window needs a de lay]
Date: Fri, 07 Jul 2006 11:35:34 +0200
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

> One problem I see with this implementation is that it also waits for twice
> the delay.  The reason can be seen in the sequence of events when the mouse
> is moved to a new window:
>
> - handle-select-window calls autoselect-window-start.
>
> - autoselect-window-start sets autoselect-window-position to
> (mouse-position).  However, this position appears to be the position
> *before* the mouse movement.

It's the first row/column after the mouse has crossed the window border.
Try by yourself: Take two windows of fixed size one above the other and
move the mouse between them.  The cddrs of autoselect-window-position
calculated by autoselect-window-start should differ by one no matter
where mouse movement started or ended.  In any case `window-at' for
autoselect-window-position should always return the window you move to.

> - autoselect-window-start starts a timer to run autoselect-window-select
> after the specified delay.
>
> - when autoselect-window-select runs after the first timeout, it checks to
> see if autoselect-window-position is equal to (mouse-position), which cannot
> be true even if the mouse has not moved again.

If you move from the lower window to the upper window and stop movement
exactly at the mode line of the upper window (that is, if you move the
mouse by a few pixels only) it can be true.

> So, window selection does
> not occur, and it just sets autoselect-window-position to (mouse-position).
>
> - when autoselect-window-select runs after the second timeout, and the mouse
> has not moved, autoselect-window-position is equal to (mouse-position) and
> window selection occurs.

Hopefully.  In my experience, the timeout before the last can be
annoying too.  Sometimes I'm just off by one character.

> To be honest, I'd be quite happy with the feature if it did not try to
> detect for a quiescent mouse as it would still be a big improvement.  In
> that case I guess the implementation would not need to use (mouse-position)
> and the above problem would not occur.
>
> If it could be made to work, it would be a bonus (though perhaps should be
> an additional option, i.e., delay or delay with quiescence).

OK, I moved everything back to mouse.el and added a customizable
variable `mouse-autoselect-quiescent'.  Using a number as value for that
variable checks whether movement was restricted to that many chars
around the last position.  This leaves future users a number of choices.

> Of course, one
> simple hack/workaround would be to use (/ mouse-autoselect-window 2.0) for
> the timer delay,

That would be ugly.

> though I'd be interested to see why mouse-position returns
> what it does.

I think that `mouse-position' does the best it can.  Mice are
unpredictable ...

*** dispextern.h        Sun Jul  2 09:50:00 2006
--- dispextern.h        Wed Jul  5 11:45:28 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,2696 ----
  extern int help_echo_pos;
  extern struct frame *last_mouse_frame;
  extern int last_tool_bar_item;
! extern Lisp_Object mouse_autoselect_window;
  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   Wed Jul  5 12:02:28 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;


*** msdos.c     Sun Jul  2 12:09:26 2006
--- msdos.c     Wed Jul  5 12:02:46 2006
***************
*** 3381,3387 ****
            }

          /* Generate SELECT_WINDOW_EVENTs when needed.  */
!         if (mouse_autoselect_window)
            {
              mouse_window = window_from_coordinates (SELECTED_FRAME(),
                                                      mouse_last_x,
--- 3381,3387 ----
            }

          /* Generate SELECT_WINDOW_EVENTs when needed.  */
!         if (!NILP (mouse_autoselect_window))
            {
              mouse_window = window_from_coordinates (SELECTED_FRAME(),
                                                      mouse_last_x,

*** w32term.c   Sun Jul  2 09:50:02 2006
--- w32term.c   Wed Jul  5 12:02:08 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);

*** xdisp.c     Sun Jul  2 09:50:02 2006
--- xdisp.c     Fri Jul  7 10:46:38 2006
***************
*** 258,264 ****

  /* 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.  */
--- 258,264 ----

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

  /* 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.
--- 23933,23950 ----
  See `set-window-redisplay-end-trigger'.  */);
    Vredisplay_end_trigger_functions = Qnil;

!   DEFVAR_LISP ("mouse-autoselect-window", &mouse_autoselect_window,
!      doc: /* *Non-nil means autoselect window with mouse pointer.
! If nil, do not autoselect windows.  A number means delay autoselection by
! that many seconds: A window is selected iff Emacs can establish that the
! mouse has remained within that window for the time indicated by the delay
! \(see `mouse-autoselect-quiescent').   A delay of less than 0.1 seconds
! is automatically translated into a delay of 0.1 seconds.  Any other value
! means autoselection occurs instantaneously.
! 
! Autoselection does not unselect the minibuffer and selects the minibuffer
! iff it is active.  */);
!   mouse_autoselect_window = 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     Wed Jul  5 12:03:04 2006
***************
*** 6575,6581 ****
            {

              /* Generate SELECT_WINDOW_EVENTs when needed.  */
!             if (mouse_autoselect_window)
                {
                  Lisp_Object window;

--- 6575,6581 ----
            {

              /* Generate SELECT_WINDOW_EVENTs when needed.  */
!             if (!NILP (mouse_autoselect_window))
                {
                  Lisp_Object window;


*** cus-start.el        Sun Jul  2 09:49:56 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    Wed Jul  5 11:33:32 2006
--- mouse.el    Fri Jul  7 11:26:26 2006
***************
*** 1729,1734 ****
--- 1729,1829 ----
                            (overlay-start mouse-secondary-overlay)
                            (overlay-end mouse-secondary-overlay)))))))

+ (defvar mouse-autoselect-window-timer nil
+   "Timer used by timer-driven window selection.")
+ 
+ (defvar mouse-autoselect-window-position nil
+   "Last mouse position calculated during timer-driven window selection.")
+ 
+ (defvar mouse-autoselect-window-at nil
+   "Window at `mouse-autoselect-window-position'.")
+ 
+ (defcustom mouse-autoselect-quiescent nil
+   "Check mouse quiescence in timer-driven window selection.
+ A value of nil means that Emacs selects a window when the mouse has
+ remained in that window for `mouse-autoselect-window' seconds.  A number
+ has Emacs select the window iff the mouse has not moved by that many
+ characters for `mouse-autoselect-window' seconds.  Any other value means
+ Emacs selects the window iff the mouse position has not changed for at
+ least `mouse-autoselect-window' seconds.
+ 
+ Settings for this variable are honored iff `mouse-autoselect-window' has
+ a numeric value."
+   :type '(choice (const :tag "Off" nil)
+                (const :tag "On" t)
+                (integer :tag "Chars" 1))
+   :group 'display)
+ 
+ (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 ()
+   "Initiate timer-driven window selection.
+ This function is called when the mouse was moved and the variable
+ `mouse-autoselect-window' has a numeric value."
+   (mouse-autoselect-window-cancel)
+   (when (numberp mouse-autoselect-window)
+     ;; Avoid a non-sensical delay here: Use 0.1 secs as minimum.
+     (let ((delay (max mouse-autoselect-window 0.1)))
+       (setq mouse-autoselect-window-position (mouse-position))
+       (setq mouse-autoselect-window-at
+           (window-at (cadr mouse-autoselect-window-position)
+                      (cddr mouse-autoselect-window-position)
+                      (car mouse-autoselect-window-position)))
+       (setq mouse-autoselect-window-timer
+           (run-at-time t delay 'mouse-autoselect-window-select))
+       (add-hook 'pre-command-hook 'mouse-autoselect-window-cancel))))
+ 
+ (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))
+            (mouse-x-pos (cadr mouse-position))
+            (mouse-y-pos (cddr mouse-position))
+            (frame (car mouse-position))
+            (window (window-at mouse-x-pos mouse-y-pos frame)))
+       (cond
+        ((and window (not (eq window (selected-window)))
+              (or (and (not mouse-autoselect-quiescent)
+                       (eq window mouse-autoselect-window-at))
+                  (and (numberp mouse-autoselect-quiescent)
+                       (and (eq frame (car mouse-autoselect-window-position))
+                            (<= (abs (- mouse-x-pos
+                                        (cadr 
mouse-autoselect-window-position)))
+                                mouse-autoselect-quiescent)
+                            (<= (abs (- mouse-y-pos
+                                        (cddr 
mouse-autoselect-window-position)))
+                                mouse-autoselect-quiescent)))
+                  (equal mouse-position mouse-autoselect-window-position))
+              (or (not (window-minibuffer-p window))
+                  (eq window (active-minibuffer-window)))
+              (let ((edges (window-inside-edges window)))
+                (and (<= (nth 0 edges) mouse-x-pos)
+                     (<= mouse-x-pos (nth 2 edges))
+                     (<= (nth 1 edges) mouse-y-pos)
+                     (<= mouse-y-pos (nth 3 edges)))))
+         ;; mouse-position has stabilized in another window.
+         (mouse-autoselect-window-cancel)
+         (unless (window-minibuffer-p (selected-window))
+           (run-hooks 'mouse-leave-buffer-hook)
+           (select-window window)))
+        ((and window (eq window (selected-window)))
+         ;; mouse-position has stabilized in same window.
+         (mouse-autoselect-window-cancel))
+        (t
+         ;; mouse-position has not stabilized yet, record new position and
+         ;; window.
+         (setq mouse-autoselect-window-position mouse-position)
+         (setq mouse-autoselect-window-at window))))
+     (error nil)))
+ 
  
  (defcustom mouse-buffer-menu-maxlen 20
    "*Number of buffers in one pane (submenu) of the buffer menu.

*** window.el   Mon Jul  3 17:35:12 2006
--- window.el   Fri Jul  7 10:02:00 2006
***************
*** 777,792 ****
    "Handle select-window events."
    (interactive "e")
    (let ((window (posn-window (event-start event))))
!     (if (and (window-live-p window)
!            ;; Don't switch if we're currently in the minibuffer.
!            ;; This tries to work around problems where the minibuffer gets
!            ;; unselected unexpectedly, and where you then have to move
!            ;; your mouse all the way down to the minibuffer to select it.
!            (not (window-minibuffer-p (selected-window)))
!            ;; Don't switch to a minibuffer window unless it's active.
!            (or (not (window-minibuffer-p window))
!                (minibuffer-window-active-p window)))
!       (select-window window))))

  (define-key ctl-x-map "2" 'split-window-vertically)
  (define-key ctl-x-map "3" 'split-window-horizontally)
--- 777,796 ----
    "Handle select-window events."
    (interactive "e")
    (let ((window (posn-window (event-start event))))
!     (when (and (window-live-p window)
!              ;; Don't switch if we're currently in the minibuffer.
!              ;; This tries to work around problems where the minibuffer gets
!              ;; unselected unexpectedly, and where you then have to move
!              ;; your mouse all the way down to the minibuffer to select it.
!              (not (window-minibuffer-p (selected-window)))
!              ;; Don't switch to a minibuffer window unless it's active.
!              (or (not (window-minibuffer-p window))
!                  (minibuffer-window-active-p window)))
!       (if (numberp mouse-autoselect-window)
!         (mouse-autoselect-window-start)
!       (when mouse-autoselect-window
!         (run-hooks 'mouse-leave-buffer-hook))
!       (select-window window)))))

  (define-key ctl-x-map "2" 'split-window-vertically)
  (define-key ctl-x-map "3" 'split-window-horizontally)


reply via email to

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