[-- Attachment #1: Type: text/plain, Size: 784 bytes --] If I have a separate info frame beside my main emacs frame and the info frame is (set-frame-parameter nil 'unsplittable t) (set-window-dedicated-p nil t) and I switch to this info frame, eval the below code (M-:) and switch to an other app then my main emacs frame is raised automatically to the foreground when the timer runs. switch-to-buffer should not cause emacs bringing a frame to the foreground (and thereby interrupting the user) without the user asking for this behavior. GNU Emacs 27.1 (build 1, x86_64-w64-mingw32) of 2020-08-12 (run-with-timer 3 nil (lambda () (with-current-buffer "*test*" (erase-buffer)) (set-process-sentinel (start-process-shell-command "test" "*test*" "dir d:") (lambda (process event) (switch-to-buffer "*test*") (goto-char (point-min)) )))) [-- Attachment #2: Type: text/html, Size: 1611 bytes --]
[-- Attachment #1: Type: text/plain, Size: 297 bytes --] You don't even need the process, it's just a leftover from a test case. The bug also occurs if only switch-to-buffer is called, but this code must be run from the dedicated frame to get the unwanted raising effect of the other frame: (run-with-timer 3 nil (lambda () (switch-to-buffer "*test*"))) [-- Attachment #2: Type: text/html, Size: 475 bytes --]
> (run-with-timer > 3 nil > (lambda () > (switch-to-buffer "*test*"))) You are asking for the impossible. 'switch-to-buffer' with a dedicated window on an unsplittable frame will inevitably trigger 'pop-to-buffer' as documented in the Elisp manual: Sometimes, the selected window may not be suitable for displaying the buffer. This happens if the selected window is a minibuffer window, or if the selected window is strongly dedicated to its buffer (*note Dedicated Windows::). In such cases, the command normally tries to display the buffer in some other window, by invoking ‘pop-to-buffer’ (see below). And 'pop-to-buffer' makes a new frame because it cannot use the selected one, raises that frame and even requests input focus for it. I haven't much to recommend for how to handle such situations. You can try the following: - Make an invisible frame when you start running the timer, maybe giving it a non-nil ‘no-focus-on-map’ parameter. - Use 'display-buffer' to show *test* in that frame and make that frame visible, preferably using an 'inhibit-switch-frame' alist entry. In either case it will be up to your WM whether it will raise that frame and give it focus. Often it does both, "stealing" another application's focus. martin
>
> And 'pop-to-buffer' makes a new frame because it cannot use the selected
> one, raises that frame and even requests input focus for it.
There is no need to create a new frame, since the other frame exists in my case,
but if pop-to-buffer raises that automatically then it's understandable why
it comes to the foreground.
A possible solution for this can be checking if pop-to-buffer is called interactively
by the user. If so then it calls select-frame-set-input-focus like now, if not
then it calls select-frame instead.
>> And 'pop-to-buffer' makes a new frame because it cannot use the selected >> one, raises that frame and even requests input focus for it. > > There is no need to create a new frame, since the other frame exists in my case, > but if pop-to-buffer raises that automatically then it's understandable why > it comes to the foreground. > > A possible solution for this can be checking if pop-to-buffer is called interactively > by the user. If so then it calls select-frame-set-input-focus like now, if not > then it calls select-frame instead. Sorry but we can't do that. `switch-to-buffer' has to provide the window the next keystroke will be addressed to. That is carved in stone. I still don't understand why you insist on using `switch-to-buffer' here. Why don't you just call `display-buffer' if you don't want to edit that buffer anyway? martin
On Thursday, January 14, 2021 8:40 AM, martin rudalics <rudalics@gmx.at> wrote:
>
> Sorry but we can't do that.`switch-to-buffer' has to provide the window the next keystroke will be addressed to. That is carved in stone. I still don't understand why you insist on using`switch-to-buffer'
> here. Why don't you just call `display-buffer' if you don't want to
> edit that buffer anyway?
>
I'll try that, I only found it strange that if a background timer uses
switch-to-buffer and the frame is in in the background then why the frame
is raised. If it's not triggered by a user interaction then there is
no practical reason to bring the frame into the foreground, because the
user is using an other app, so he doesn't want to type into that frame
at that point. The frame should only switch to the buffer and remain in the
background, so when the user get backs to emacs then he can see the result
of the background process presented to him.
It sounds like a bug to me, but I accept if you say it's hard to implement
for some reason and I'll change my code to use an other method.
> I'll try that, I only found it strange that if a background timer uses > switch-to-buffer Timers should never use `switch-to-buffer'. If they want to draw attention to the object they want to display, they should use `pop-to-buffer'. Otherwise, `display-buffer' is the function to be preferred although if that needs a new frame, it will raise that frame too unless your WM prevents it. 'switch-to-buffer' is a user command and should not be called by any Lisp code. Unfortunately, it's done a hundred times in the Emacs code base and there's nothing we can reasonably do about that. > and the frame is in in the background then why the frame > is raised. If it's not triggered by a user interaction then there is > no practical reason to bring the frame into the foreground, because the > user is using an other app, so he doesn't want to type into that frame > at that point. The frame should only switch to the buffer and remain in the > background, so when the user get backs to emacs then he can see the result > of the background process presented to him. > > It sounds like a bug to me, but I accept if you say it's hard to implement > for some reason and I'll change my code to use an other method. It's by no means hard to implement (preventing a new frame from getting raised is much harder). But we cannot change the semantics of `switch-to-buffer' in this regard. As long as window managers permit us to do that, it will raise the frame it uses and give it focus. martin
>
> It's by no means hard to implement (preventing a new frame from getting
> raised is much harder). But we cannot change the semantics of
> `switch-to-buffer' in this regard. As long as window managers permit us
> to do that, it will raise the frame it uses and give it focus.
>
OK, the bug can be closed then if it's wontfix.
tags 45844 wontfix
close 45844
thanks
emacser <laszlomail@protonmail.com> writes:
>> It's by no means hard to implement (preventing a new frame from getting
>> raised is much harder). But we cannot change the semantics of
>> `switch-to-buffer' in this regard. As long as window managers permit us
>> to do that, it will raise the frame it uses and give it focus.
>>
>
> OK, the bug can be closed then if it's wontfix.
Done.