* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out @ 2014-05-08 20:45 Juri Linkov 2014-05-09 6:28 ` Eli Zaretskii 0 siblings, 1 reply; 13+ messages in thread From: Juri Linkov @ 2014-05-08 20:45 UTC (permalink / raw) To: 17439 Some change a few months ago introduced a significant inconvenience. After switching to another application, the focus returns back to Emacs. It happens when using `mouse-avoidance-mode' customized to `banish'. This mode relies on `run-with-idle-timer' that moves the mouse cursor on a new input. This caused no problems in prior releases. However, now input events include a new event type `focus-out', so the mouse cursor is moved on switching from Emacs frame (and the new mouse cursor position puts the focus back due to specific configuration). This code illustrates the problem: (defun test () (message "%S" last-input-event)) (setq timer (run-with-idle-timer 0.1 t 'test)) On switching out it prints to *Messages*: (focus-in #<frame emacs@localhost 0x1121908>) (focus-out #<frame emacs@localhost 0x1121908>) This specific problem can be fixed by this patch: === modified file 'lisp/avoid.el' --- lisp/avoid.el 2014-01-31 06:42:29 +0000 +++ lisp/avoid.el 2014-05-08 20:39:59 +0000 @@ -343,7 +343,8 @@ (defun mouse-avoidance-ignore-p () (let ((modifiers (event-modifiers (car last-input-event)))) (or (memq (car last-input-event) '(mouse-movement scroll-bar-movement - select-window switch-frame)) + select-window switch-frame + focus-in focus-out)) (memq 'click modifiers) (memq 'double modifiers) (memq 'triple modifiers) PS: it seems there are other places that check only for `switch-frame', and not for new event types `focus-in' and `focus-out'. But maybe this problem occurs only in `run-with-idle-timer' because switching out doesn't emit the event on its own, i.e. `read-event' doesn't return it. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-08 20:45 bug#17439: 24.3.50; run-with-idle-timer runs on focus-out Juri Linkov @ 2014-05-09 6:28 ` Eli Zaretskii 2014-05-09 20:35 ` Juri Linkov 0 siblings, 1 reply; 13+ messages in thread From: Eli Zaretskii @ 2014-05-09 6:28 UTC (permalink / raw) To: Juri Linkov; +Cc: 17439 > From: Juri Linkov <juri@jurta.org> > Date: Thu, 08 May 2014 23:45:27 +0300 > > Some change a few months ago introduced a significant inconvenience. > After switching to another application, the focus returns back to Emacs. > It happens when using `mouse-avoidance-mode' customized to `banish'. > This mode relies on `run-with-idle-timer' that moves the mouse cursor > on a new input. This caused no problems in prior releases. > > However, now input events include a new event type `focus-out', > so the mouse cursor is moved on switching from Emacs frame > (and the new mouse cursor position puts the focus back > due to specific configuration). > > This code illustrates the problem: > > (defun test () (message "%S" last-input-event)) > (setq timer (run-with-idle-timer 0.1 t 'test)) > > On switching out it prints to *Messages*: > > (focus-in #<frame emacs@localhost 0x1121908>) > (focus-out #<frame emacs@localhost 0x1121908>) > > This specific problem can be fixed by this patch: Why did you add focus-in as well? Wouldn't you want the mouse moved when you are about to type? ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-09 6:28 ` Eli Zaretskii @ 2014-05-09 20:35 ` Juri Linkov 2014-05-10 6:16 ` Eli Zaretskii 0 siblings, 1 reply; 13+ messages in thread From: Juri Linkov @ 2014-05-09 20:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 17439 > Why did you add focus-in as well? When I tried to switch out with (defun test () (message "%S" last-input-event)) (setq timer (run-with-idle-timer 0.1 t 'test)) it prints to *Messages* both lines: (focus-in #<frame emacs@localhost 0x1121908>) (focus-out #<frame emacs@localhost 0x1121908>) `focus-in' is fired by the desktop window switcher that shows the list of desktop windows to switch. After selecting another window from the Window List, `focus-out' is fired eventually too. So when `focus-in' is not ignored in avoid.el then the mouse cursor will be moved after showing the Window List. But it seems this is not a problem because special mouse processing is disabled when the Window List is shown. > Wouldn't you want the mouse moved when you are about to type? Yes, it's better to move the mouse on focusing in than later on typing a key after switching. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-09 20:35 ` Juri Linkov @ 2014-05-10 6:16 ` Eli Zaretskii 2014-05-10 20:38 ` Juri Linkov 2014-05-11 20:19 ` Juri Linkov 0 siblings, 2 replies; 13+ messages in thread From: Eli Zaretskii @ 2014-05-10 6:16 UTC (permalink / raw) To: Juri Linkov; +Cc: 17439 > From: Juri Linkov <juri@jurta.org> > Cc: 17439@debbugs.gnu.org > Date: Fri, 09 May 2014 23:35:20 +0300 > > > Why did you add focus-in as well? > > When I tried to switch out with > > (defun test () (message "%S" last-input-event)) > (setq timer (run-with-idle-timer 0.1 t 'test)) > > it prints to *Messages* both lines: > > (focus-in #<frame emacs@localhost 0x1121908>) > (focus-out #<frame emacs@localhost 0x1121908>) > > `focus-in' is fired by the desktop window switcher > that shows the list of desktop windows to switch. > After selecting another window from the Window List, > `focus-out' is fired eventually too. > > So when `focus-in' is not ignored in avoid.el then the > mouse cursor will be moved after showing the Window List. > But it seems this is not a problem because special mouse > processing is disabled when the Window List is shown. > > > Wouldn't you want the mouse moved when you are about to type? > > Yes, it's better to move the mouse on focusing in > than later on typing a key after switching. So are you saying we should NOT ignore focus-in? If you still think focus-in should be ignored, then I think the above description (perhaps together with the window manager where it was observed) should be in the comments to the code. Thanks. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-10 6:16 ` Eli Zaretskii @ 2014-05-10 20:38 ` Juri Linkov 2014-05-11 20:19 ` Juri Linkov 1 sibling, 0 replies; 13+ messages in thread From: Juri Linkov @ 2014-05-10 20:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 17439 > So are you saying we should NOT ignore focus-in? If you still think > focus-in should be ignored, then I think the above description > (perhaps together with the window manager where it was observed) > should be in the comments to the code. After more testing without ignoring focus-in and with ignoring focus-out, often pressing and releasing Alt-Tab quickly generates both events focus-in and focus-out, and when having no time to show the Window List focus-in moves the mouse pointer and hides the selected window. So both events should be ignored, like `switch-frame' is already ignored when switching between Emacs frames. I'll add a comment about this. And there are more fixes necessary in avoid.el. This patch will ignore modifiers used together with mouse events: === modified file 'lisp/avoid.el' --- lisp/avoid.el 2014-01-01 07:43:34 +0000 +++ lisp/avoid.el 2014-05-10 20:36:19 +0000 @@ -347,7 +348,13 @@ (defun mouse-avoidance-ignore-p () (memq 'double modifiers) (memq 'triple modifiers) (memq 'drag modifiers) - (memq 'down modifiers))))))) + (memq 'down modifiers) + (memq 'meta modifiers) + (memq 'control modifiers) + (memq 'shift modifiers) + (memq 'hyper modifiers) + (memq 'super modifiers) + (memq 'alt modifiers))))))) (defun mouse-avoidance-banish () (if (not (mouse-avoidance-ignore-p)) And this patch fixes the customization of `mouse-avoidance-banish-position' (it can be tested by e.g. using `set-variable' on `mouse-avoidance-banish-position'): === modified file 'lisp/avoid.el' --- lisp/avoid.el 2014-01-01 07:43:34 +0000 +++ lisp/avoid.el 2014-05-10 20:36:19 +0000 @@ -129,9 +129,10 @@ (defcustom mouse-avoidance-banish-positi TOP-OR-BOTTOM-POS: Distance from top or bottom edge of frame or window." :group 'avoid :version "24.3" - :type '(alist :key-type symbol :value-type symbol) - :options '(frame-or-window side (side-pos integer) - top-or-bottom (top-or-bottom-pos integer))) + :type '(alist :key-type symbol :value-type (choice symbol integer)) + :options '((frame-or-window symbol) (side symbol) (side-pos integer) + (top-or-bottom symbol) (top-or-bottom-pos integer))) ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-10 6:16 ` Eli Zaretskii 2014-05-10 20:38 ` Juri Linkov @ 2014-05-11 20:19 ` Juri Linkov 2014-05-11 21:06 ` Stefan Monnier 1 sibling, 1 reply; 13+ messages in thread From: Juri Linkov @ 2014-05-11 20:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 17439 > So are you saying we should NOT ignore focus-in? If you still think > focus-in should be ignored, then I think the above description > (perhaps together with the window manager where it was observed) > should be in the comments to the code. Actually, the root of the problem is `raise-frame' in `mouse-avoidance-set-mouse-position' that brings an Emacs frame back to the front after switching. This is a better patch: === modified file 'lisp/avoid.el' --- lisp/avoid.el 2014-01-01 07:43:34 +0000 +++ lisp/avoid.el 2014-05-11 20:15:17 +0000 @@ -177,7 +178,21 @@ (defun mouse-avoidance-set-mouse-position ;; difficult to do, so we just raise the frame to avoid frame switches. ;; Returns t if it moved the mouse. (let ((f (selected-frame))) - (raise-frame f) + (unless (and (consp last-input-event) + (symbolp (car last-input-event)) + (memq (car last-input-event) + '( + ;; `run-with-idle-timer' generates the `focus-out' + ;; event on switching out from the current frame, + ;; but `raise-frame' brings the same frame back, + ;; so ignore `focus-out' here. + focus-out + ;; Some window managers generate the `focus-in' event + ;; when showing the Window List, but `raise-frame' forcibly + ;; switches to an Emacs frame when the Window List is active, + ;; so `focus-in' needs to be ignored here too. + focus-in))) + (raise-frame f)) (set-mouse-position f (car pos) (cdr pos)) t)) ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-11 20:19 ` Juri Linkov @ 2014-05-11 21:06 ` Stefan Monnier 2014-05-11 21:31 ` Juri Linkov 0 siblings, 1 reply; 13+ messages in thread From: Stefan Monnier @ 2014-05-11 21:06 UTC (permalink / raw) To: Juri Linkov; +Cc: 17439 > + (unless (and (consp last-input-event) > + (symbolp (car last-input-event)) > + (memq (car last-input-event) Aka (unless (memq (car-safe last-input-event) > + '( > + ;; `run-with-idle-timer' generates the `focus-out' Huh? `run-with-idle-timer' is not supposed to generate any event. > + ;; event on switching out from the current frame, > + ;; but `raise-frame' brings the same frame back, > + ;; so ignore `focus-out' here. > + focus-out Running mouse avoidance after focus-out does not seem very useful, so we should filter out focus-out elsewhere than here. > + ;; Some window managers generate the `focus-in' event > + ;; when showing the Window List, What means "showing the Window List"? > + ;; but `raise-frame' forcibly switches to an Emacs frame when the Window List is active, I don't know what this is talking about either. > + ;; so `focus-in' needs to be ignored here too. Shouldn't `switch-frame' be ignored for similar reasons, then? Stefan ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-11 21:06 ` Stefan Monnier @ 2014-05-11 21:31 ` Juri Linkov 2014-05-11 22:29 ` Stefan Monnier 0 siblings, 1 reply; 13+ messages in thread From: Juri Linkov @ 2014-05-11 21:31 UTC (permalink / raw) To: Stefan Monnier; +Cc: 17439 >> + (unless (and (consp last-input-event) >> + (symbolp (car last-input-event)) >> + (memq (car last-input-event) > > Aka (unless (memq (car-safe last-input-event) This is what I thought about, but decided to keep code consistency with `mouse-avoidance-ignore-p'. But `mouse-avoidance-ignore-p' could be optimized too. >> + '( >> + ;; `run-with-idle-timer' generates the `focus-out' > > Huh? `run-with-idle-timer' is not supposed to generate any event. It runs on `focus-out', as this short test demonstrates: (defun test () (message "%S" last-input-event)) (setq timer (run-with-idle-timer 0.1 t 'test)) It generates: (focus-in #<frame emacs@localhost 0x1121908>) (focus-out #<frame emacs@localhost 0x1121908>) >> + ;; event on switching out from the current frame, >> + ;; but `raise-frame' brings the same frame back, >> + ;; so ignore `focus-out' here. >> + focus-out > > Running mouse avoidance after focus-out does not seem very useful, so we > should filter out focus-out elsewhere than here. I'll move `focus-out' back to `mouse-avoidance-ignore-p' to not move the mouse pointer on `focus-out'. >> + ;; Some window managers generate the `focus-in' event >> + ;; when showing the Window List, > > What means "showing the Window List"? It depends on the desktop environment, but usually this is a list of windows shown after typing Alt-Tab. >> + ;; but `raise-frame' forcibly switches to an Emacs frame when the Window List is active, > > I don't know what this is talking about either. This is specific behavior observed at least in one window manager (Gnome 2), where typing Alt-Tab shows the Window List and generates the `focus-in' event in Emacs at the same time. >> + ;; so `focus-in' needs to be ignored here too. > > Shouldn't `switch-frame' be ignored for similar reasons, then? Currently `switch-frame' is ignored in `mouse-avoidance-ignore-p', so the mouse pointer is not moved when `switch-frame' is generated in a new frame after switching between Emacs frames. But maybe it should be handled like `focus-in', i.e. also to not ignore it in `mouse-avoidance-ignore-p' and to move the mouse pointer after switching between Emacs frames. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-11 21:31 ` Juri Linkov @ 2014-05-11 22:29 ` Stefan Monnier 2014-05-12 20:39 ` Juri Linkov 0 siblings, 1 reply; 13+ messages in thread From: Stefan Monnier @ 2014-05-11 22:29 UTC (permalink / raw) To: Juri Linkov; +Cc: 17439 >> Huh? `run-with-idle-timer' is not supposed to generate any event. > It runs on `focus-out', It does. But that doesn't mean that "`run-with-idle-timer' generates the `focus-out'". The `focus-out' event is generated by the window-manager plus Emacs's C code in response to some situation such as a user action. And after execution of the command bound to `focus-out', we run the idle timers. > (defun test () (message "%S" last-input-event)) > (setq timer (run-with-idle-timer 0.1 t 'test)) > It generates: > (focus-in #<frame emacs@localhost 0x1121908>) > (focus-out #<frame emacs@localhost 0x1121908>) Your code generates some output which mentions `focus-out' but it did not generate those events. >>> + ;; Some window managers generate the `focus-in' event >>> + ;; when showing the Window List, >> What means "showing the Window List"? > It depends on the desktop environment, but usually this is a list of windows > shown after typing Alt-Tab. Then I still don't understand: why would Emacs get a focus-in event when the window-manager shows the "Window List"? I'd maybe expect a focus-*out* event, since suddenly the focus might go from Emacs to the Window List. Or do you mean that Emacs gets a focus-in event when the user selects an Emacs frame in the window manager's Window List (maybe even if that selection is transient while looping through all windows)? >>> + ;; but `raise-frame' forcibly switches to an Emacs >>> frame when the Window List is active, Well, this behavior is a choice of the window-manager. While I'm very happy to call raise-frame less often (so I generally agree with the direction of the patch), you could argue that this might be a bug in the window-manager. > This is specific behavior observed at least in one window manager (Gnome 2), > where typing Alt-Tab shows the Window List and generates the `focus-in' event > in Emacs at the same time. OK, I think I understand. Please make the comment a bit more clear about the fact that the focus-in event might come even *while* (rather than *when*) the "Window List thingy to select a window" is active. > But maybe it should be handled like `focus-in', i.e. also > to not ignore it in `mouse-avoidance-ignore-p' and to move > the mouse pointer after switching between Emacs frames. I don't have a strong opinion either way, but it seems like they generally should be handled in the same way, since they occur in similar circumstances (one being when you focus-in from another frame of the same Emacs session, while the other is when you focus-in from some other process). Stefan ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-11 22:29 ` Stefan Monnier @ 2014-05-12 20:39 ` Juri Linkov 2014-05-13 19:33 ` Stefan Monnier 0 siblings, 1 reply; 13+ messages in thread From: Juri Linkov @ 2014-05-12 20:39 UTC (permalink / raw) To: Stefan Monnier; +Cc: 17439 >>>> + ;; but `raise-frame' forcibly switches to an Emacs frame >>>> when the Window List is active, > > Well, this behavior is a choice of the window-manager. While I'm very > happy to call raise-frame less often (so I generally agree with the > direction of the patch), you could argue that this might be a bug in the > window-manager. raise-frame causes more trouble, e.g. when another application is in full-screen mode, then they both fight for which of them should stay on the top, so typing a key in Emacs re-raises the selected Emacs frame, and then another application brings itself to the front. A comment in `mouse-avoidance-set-mouse-position' explains its rationale: ;; Ideally, should check if X,Y is in the current frame, and if not, ;; leave the mouse where it was. However, this is currently ;; difficult to do, so we just raise the frame to avoid frame switches. But actually such check already exists in `mouse-avoidance-ignore-p': (not (eq (car (mouse-position)) (selected-frame))) and the mouse pointer is not moved when it's outside of the selected frame. So I really see no problems with this patch: === modified file 'lisp/avoid.el' --- lisp/avoid.el 2014-01-01 07:43:34 +0000 +++ lisp/avoid.el 2014-05-12 20:31:28 +0000 @@ -52,9 +52,6 @@ ;; ;; - Using this code does slow Emacs down. "banish" mode shouldn't ;; be too bad, and on my workstation even "animate" is reasonable. -;; -;; - It ought to find out where any overlapping frames are and avoid them, -;; rather than always raising the frame. ;; Credits: ;; This code was helped by all those who contributed suggestions, @@ -172,12 +170,8 @@ (defun mouse-avoidance-point-position () (defun mouse-avoidance-set-mouse-position (pos) ;; Carefully set mouse position to given position (X . Y) - ;; Ideally, should check if X,Y is in the current frame, and if not, - ;; leave the mouse where it was. However, this is currently - ;; difficult to do, so we just raise the frame to avoid frame switches. ;; Returns t if it moved the mouse. (let ((f (selected-frame))) - (raise-frame f) (set-mouse-position f (car pos) (cdr pos)) t)) @@ -342,7 +336,7 @@ (defun mouse-avoidance-ignore-p () (let ((modifiers (event-modifiers (car last-input-event)))) (or (memq (car last-input-event) '(mouse-movement scroll-bar-movement - select-window switch-frame)) + select-window focus-out)) (memq 'click modifiers) (memq 'double modifiers) (memq 'triple modifiers) @@ -403,8 +403,6 @@ (defun mouse-avoidance-mode (&optional m * cat-and-mouse: Same as `animate'. * proteus: As `animate', but changes the shape of the mouse pointer too. -Whenever the mouse is moved, the frame is also raised. - \(See `mouse-avoidance-threshold' for definition of \"too close\", and `mouse-avoidance-nudge-dist' and `mouse-avoidance-nudge-var' for definition of \"random distance\".)" ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-12 20:39 ` Juri Linkov @ 2014-05-13 19:33 ` Stefan Monnier 2014-05-20 21:14 ` Juri Linkov 0 siblings, 1 reply; 13+ messages in thread From: Stefan Monnier @ 2014-05-13 19:33 UTC (permalink / raw) To: Juri Linkov; +Cc: 17439 > raise-frame causes more trouble, e.g. when another application is > in full-screen mode, then they both fight for which of them should stay > on the top, so typing a key in Emacs re-raises the selected Emacs frame, > and then another application brings itself to the front. Again sounds like a bug in the window-manager. > So I really see no problems with this patch: If that works, then by all means go for it. Stefan ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-13 19:33 ` Stefan Monnier @ 2014-05-20 21:14 ` Juri Linkov 2014-05-20 22:12 ` Juri Linkov 0 siblings, 1 reply; 13+ messages in thread From: Juri Linkov @ 2014-05-20 21:14 UTC (permalink / raw) To: Stefan Monnier; +Cc: 17439-done >> So I really see no problems with this patch: > > If that works, then by all means go for it. Installed (found no problems after more testing). ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#17439: 24.3.50; run-with-idle-timer runs on focus-out 2014-05-20 21:14 ` Juri Linkov @ 2014-05-20 22:12 ` Juri Linkov 0 siblings, 0 replies; 13+ messages in thread From: Juri Linkov @ 2014-05-20 22:12 UTC (permalink / raw) To: 17439 >>> So I really see no problems with this patch: >> >> If that works, then by all means go for it. > > Installed (found no problems after more testing). While looking at the mouse-related items in etc/TODO I noticed this in the section Bugs: **** (mouse-avoidance-mode 'banish) then minimize Emacs, will pop window back up on top of all others I guess this is fixed now and can be removed from etc/TODO? ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-05-20 22:12 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-05-08 20:45 bug#17439: 24.3.50; run-with-idle-timer runs on focus-out Juri Linkov 2014-05-09 6:28 ` Eli Zaretskii 2014-05-09 20:35 ` Juri Linkov 2014-05-10 6:16 ` Eli Zaretskii 2014-05-10 20:38 ` Juri Linkov 2014-05-11 20:19 ` Juri Linkov 2014-05-11 21:06 ` Stefan Monnier 2014-05-11 21:31 ` Juri Linkov 2014-05-11 22:29 ` Stefan Monnier 2014-05-12 20:39 ` Juri Linkov 2014-05-13 19:33 ` Stefan Monnier 2014-05-20 21:14 ` Juri Linkov 2014-05-20 22:12 ` Juri Linkov
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.