Package: emacs;
Reported by: Sean Devlin <spd <at> toadstyle.org>
Date: Sat, 28 Nov 2020 21:22:02 UTC
Severity: normal
Found in version 27.1
To reply to this bug, email your comments to 44933 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Sat, 28 Nov 2020 21:22:02 GMT) Full text and rfc822 format available.Sean Devlin <spd <at> toadstyle.org>
:bug-gnu-emacs <at> gnu.org
.
(Sat, 28 Nov 2020 21:22:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: bug-gnu-emacs <at> gnu.org Subject: 27.1; Ephemeral frame selection shrinks minibuffer Date: Sat, 28 Nov 2020 16:21:40 -0500
Hi folks, Selecting a different frame ephmerally (e.g. via `with-selected-frame` in a timer callback) shrinks the minibuffer. This is true whether or not the minibuffer is active. Reproduction steps: 1. Evaluate this form in the scratch buffer: (run-with-timer nil 13 (lambda () (with-selected-frame (next-frame)))) 2. Evaluate this form in the scratch buffer: (run-with-timer nil 11 (lambda () (window-resize (minibuffer-window) 10))) 3. Observe that the minibuffer grows and shrinks as the timers fire. You can run some completing read command (e.g. `M-x`) to see that the resizing happens whether or not the minibuffer is active. This is relevant for completing read implementations that resize the minibuffer to display a vertical list of candidates. I noticed the behavior while using selectrum (https://github.com/raxod502/selectrum) while I had a subprocess running under term in another frame. Since the `term-emulate-terminal` function selects windows in the background whenever the subprocess sends output, it was causing the selectrum minibuffer to shrink. I'm not sure what the correct behavior is here, but this was unexpected to me. I think that if the minibuffer is active, ephemeral frame or window selections should not affect its size. (I'm less certain about the inactive minibuffer case, but I think the size should stay the same there as well.) Thanks! In GNU Emacs 27.1 (build 1, x86_64-apple-darwin18.7.0, NS appkit-1671.60 Version 10.14.6 (Build 18G95)) of 2020-08-12 built on builder10-14.porkrind.org Windowing system distributor 'Apple', version 10.3.2022 System Description: macOS 11.0 Recent messages: Beginning of buffer [5 times] uncompressing window.el.gz...done Making completion list... Type C-x 1 to delete the help window, C-M-v to scroll help. t [2 times] Quit [3 times] [nil 24514 47830 650446 10 (closure (t) nil (window-resize (minibuffer-window) 10)) nil nil 0] [nil 24514 47883 629069 11 (closure (t) nil (let (... ...) (unwind-protect ... ... ...))) nil nil 0] End of buffer [6 times] Beginning of buffer [8 times] Configured using: 'configure --with-ns '--enable-locallisppath=/Library/Application Support/Emacs/${version}/site-lisp:/Library/Application Support/Emacs/site-lisp' --with-modules' Configured features: NOTIFY KQUEUE ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES THREADS JSON PDUMPER Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: Lisp Interaction Minor modes in effect: tooltip-mode: t global-eldoc-mode: t eldoc-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t line-number-mode: t transient-mark-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr cl-print debug backtrace cl-extra minibuf-eldef help-fns radix-tree help-mode emacsbug message rmc puny dired dired-loaddefs format-spec rfc822 mml easymenu mml-sec password-cache epa derived epg epg-config gnus-util rmail rmail-loaddefs text-property-search time-date subr-x seq byte-opt gv bytecomp byte-compile cconv mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils linum misearch multi-isearch jka-compr thingatpt find-func tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/ns-win ns-win ucs-normalize mule-util term/common-win tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote threads kqueue cocoa ns multi-tty make-network-process emacs) Memory information: ((conses 16 59777 30679) (symbols 48 6538 1) (strings 32 19388 2002) (string-bytes 1 586736) (vectors 16 11741) (vector-slots 8 146822 21486) (floats 8 40 48) (intervals 56 896 92) (buffers 1000 16))
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Sun, 29 Nov 2020 08:23:02 GMT) Full text and rfc822 format available.Message #8 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org>, 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Sun, 29 Nov 2020 09:22:00 +0100
> Selecting a different frame ephmerally (e.g. via `with-selected-frame` > in a timer callback) shrinks the minibuffer. This is true whether or not > the minibuffer is active. > > Reproduction steps: > > 1. Evaluate this form in the scratch buffer: > > (run-with-timer nil 13 (lambda () (with-selected-frame > (next-frame)))) > > 2. Evaluate this form in the scratch buffer: > > (run-with-timer nil 11 (lambda () (window-resize (minibuffer-window) > 10))) > > 3. Observe that the minibuffer grows and shrinks as the timers fire. Here I need two frames to observe 3. With one frame the minibuffer window grows continuously. > You can run some completing read command (e.g. `M-x`) to see that the > resizing happens whether or not the minibuffer is active. > > This is relevant for completing read implementations that resize the > minibuffer to display a vertical list of candidates. I noticed the > behavior while using selectrum (https://github.com/raxod502/selectrum) > while I had a subprocess running under term in another frame. Since the > `term-emulate-terminal` function selects windows in the background > whenever the subprocess sends output, it was causing the selectrum > minibuffer to shrink. > > I'm not sure what the correct behavior is here, but this was unexpected > to me. I think that if the minibuffer is active, ephemeral frame or > window selections should not affect its size. (I'm less certain about > the inactive minibuffer case, but I think the size should stay the same > there as well.) To my knowledge we have no means to select a frame "ephemerally". 'with-selected-frame', 'with-selected-window' are just as "hard" as 'select-frame' and 'select-window'. And so the only way to prevent switching frames from shrinking the previously selected frame's minibuffer window is to set 'resize-mini-windows' to nil. OTOH with 'resize-mini-windows' non-nil, re-selecting the previously selected frame when returning from a 'with-selected-frame' should size its minibuffer window back to its contents provided it is still active. But I'm never sure whether all these work as advertised. martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Sun, 29 Nov 2020 15:44:02 GMT) Full text and rfc822 format available.Message #11 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: martin rudalics <rudalics <at> gmx.at> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Sun, 29 Nov 2020 10:43:18 -0500
Hi Martin, > On Nov 29, 2020, at 3:22 AM, martin rudalics <rudalics <at> gmx.at> wrote: > > > Selecting a different frame ephmerally (e.g. via `with-selected-frame` > > in a timer callback) shrinks the minibuffer. This is true whether or not > > the minibuffer is active. > > > > Reproduction steps: > > > > 1. Evaluate this form in the scratch buffer: > > > > (run-with-timer nil 13 (lambda () (with-selected-frame > > (next-frame)))) > > > > 2. Evaluate this form in the scratch buffer: > > > > (run-with-timer nil 11 (lambda () (window-resize (minibuffer-window) > > 10))) > > > > 3. Observe that the minibuffer grows and shrinks as the timers fire. > > Here I need two frames to observe 3. With one frame the minibuffer > window grows continuously. Ah, you’re right. I had left this out of my reproduction steps. Sorry! > > > You can run some completing read command (e.g. `M-x`) to see that the > > resizing happens whether or not the minibuffer is active. > > > > This is relevant for completing read implementations that resize the > > minibuffer to display a vertical list of candidates. I noticed the > > behavior while using selectrum (https://github.com/raxod502/selectrum) > > while I had a subprocess running under term in another frame. Since the > > `term-emulate-terminal` function selects windows in the background > > whenever the subprocess sends output, it was causing the selectrum > > minibuffer to shrink. > > > > I'm not sure what the correct behavior is here, but this was unexpected > > to me. I think that if the minibuffer is active, ephemeral frame or > > window selections should not affect its size. (I'm less certain about > > the inactive minibuffer case, but I think the size should stay the same > > there as well.) > > To my knowledge we have no means to select a frame "ephemerally". > 'with-selected-frame', 'with-selected-window' are just as "hard" as > 'select-frame' and 'select-window'. And so the only way to prevent > switching frames from shrinking the previously selected frame's > minibuffer window is to set 'resize-mini-windows' to nil. OTOH with > 'resize-mini-windows' non-nil, re-selecting the previously selected frame > when returning from a 'with-selected-frame' should size its minibuffer > window back to its contents provided it is still active. But I'm never > sure whether all these work as advertised. I see, thank you. It looks like the default value for `resize-mini-windows` is `grow-only`. The docs for `resize-mini-windows` suggest it is used along with the text in the minibuffer to decide how to resize the window. I think this may be the issue, since my minibuffer has no text spanning multiple lines. In my reproduction, the minibuffer window is grown manually via `window-resize`. In the case of selectrum, the completing read candidates are displayed via overlay. I think this means that a resizing function that considers the buffer text only will resize these back down to a single line. I just tested, and binding `resize-mini-windows` to nil around the window selection in `term-emulate-terminal` does solve my problem. Does this seem like the right fix? I think it is surprising that output from a term process coming in the background should resize a minibuffer window (and especially an active one). Also, I see that `term-emulate-terminal` is calling `select-window` to perform its window selections. From my reading of the docs, I think it might make sense for it to pass `mark-for-redisplay` as the `norecord` argument. It doesn't seem like we should be modifying the buffer list or most recently selected window in this case, but we do want to redisplay the new output. I think the documentation should clarify that window selection can change window sizes as a side effect. The docs for selecting windows (https://www.gnu.org/software/emacs/manual/html_node/elisp/Selecting-Windows.html) do not mention that `select-window` can change minibuffer sizes. The docs for minibuffer windows (https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Windows.html) do mention these variables to control how minibuffer windows can be resized automatically, but they do not say what functions might try to do this automatic resizing. Finally, I wonder if `with-selected-window` (which `term-emulate-terminal` does not currently use) should bind `resize-mini-windows`. The docs say it is "the preferred way to temporarily work with" a selected window, so it does seem like automatic resizing is not in the spirit of the function. On the other hand, I don't know all the existing use cases; maybe this would break things. Thanks! > > martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Mon, 30 Nov 2020 09:06:02 GMT) Full text and rfc822 format available.Message #14 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Mon, 30 Nov 2020 10:04:54 +0100
> In my reproduction, the minibuffer window is grown manually via > `window-resize`. With 'resize-mini-windows' non-nil this usually has no visible effect because any such manual resizing is immediately undone by the automatic resizing scheme. > In the case of selectrum, the completing read > candidates are displayed via overlay. I think this means that a > resizing function that considers the buffer text only will resize > these back down to a single line. The routine that determines the window size (resize_mini_window in xdisp.c) should consider overlays as well (if they are in the right buffer). Anything else would be a bug. > I just tested, and binding `resize-mini-windows` to nil around the > window selection in `term-emulate-terminal` does solve my > problem. Does this seem like the right fix? I think it is surprising > that output from a term process coming in the background should resize > a minibuffer window (and especially an active one). If you look into the code of do_switch_frame (in frame.c) you will be able to spot if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); which means that currently even redisplay itself may resize the mini window every time it constructs a mode line or frame title. I can only offer two advices: (1) Avoid 'with-selected-window/frame' in timers and (2) make sure no redisplay happen _within_ such a form. > Also, I see that `term-emulate-terminal` is calling `select-window` to > perform its window selections. From my reading of the docs, I think it > might make sense for it to pass `mark-for-redisplay` as the `norecord` > argument. It doesn't seem like we should be modifying the buffer list > or most recently selected window in this case, but we do want to > redisplay the new output. I would have to understand the semantics of 'term-emulate-terminal' to answer that. Hopefully, someone else can chime in here. > I think the documentation should clarify that window selection can > change window sizes as a side effect. The docs for selecting windows > (https://www.gnu.org/software/emacs/manual/html_node/elisp/Selecting-Windows.html) > do not mention that `select-window` can change minibuffer sizes. The > docs for minibuffer windows > (https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Windows.html) > do mention these variables to control how minibuffer windows can be > resized automatically, but they do not say what functions might try to > do this automatic resizing. With the recently added 'minibuffer-follows-selected-frame' we now have an additional source of complications to consider. Maybe you could, as soon as the implementation of the latter has consolidated, play with the various values of 'resize-mini-windows' and suggest suitable fixes for the documentations of 'select-window' and 'select-frame'. Alternatively, we could consider skipping the resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); above for temporary window/frame selections (and at least for redisplay as I currently do here) but the consequences of such a step are not easily fathomable. > Finally, I wonder if `with-selected-window` (which > `term-emulate-terminal` does not currently use) should bind > `resize-mini-windows`. ... with the consequences I mentioned in the sentence before ... > The docs say it is "the preferred way to > temporarily work with" a selected window, so it does seem like > automatic resizing is not in the spirit of the function. On the other > hand, I don't know all the existing use cases; maybe this would break > things. Right. martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Mon, 30 Nov 2020 19:33:02 GMT) Full text and rfc822 format available.Message #17 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: martin rudalics <rudalics <at> gmx.at> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Mon, 30 Nov 2020 14:32:27 -0500
Hi Martin, > On Nov 30, 2020, at 4:04 AM, martin rudalics <rudalics <at> gmx.at> wrote: > > > In my reproduction, the minibuffer window is grown manually via > > `window-resize`. > > With 'resize-mini-windows' non-nil this usually has no visible effect > because any such manual resizing is immediately undone by the automatic > resizing scheme. I’m not sure I understand. Are you saying a program should not be able to grow the minibuffer window this way? Or just that it will be undone by the next resizing event? (Of course, this is a toy example, so I have no opinion on what the correct behavior should be. I’m just wondering.) > > > In the case of selectrum, the completing read > > candidates are displayed via overlay. I think this means that a > > resizing function that considers the buffer text only will resize > > these back down to a single line. > > The routine that determines the window size (resize_mini_window in > xdisp.c) should consider overlays as well (if they are in the right > buffer). Anything else would be a bug. I’ve been playing with this a bit (on a recent Emacs 28.0.50), and I’m not sure I understand the current behavior. For example, I have three frames open and I ran this code in the scratch buffer: (with-current-buffer (window-buffer (minibuffer-window)) (remove-overlays) (erase-buffer) (insert "this is some text") (let ((ov (make-overlay (point) (point) nil t t))) (overlay-put ov 'after-string "\none\ntwo\nthree"))) After moving the point, all I can see is the first line in the minibuffer: “this is some text”. This is true across all three frames. If I select the other frames by clicking on them, the frame that just lost focus will now show all four lines (i.e. including the overlay). The minibuffer windows on the other frames will stay at one line until I select them by clicking and then select some other frame. On the other hand, if I select frames by calling `other-frame` via a key binding, the behavior is slightly different: the minibuffer window on a frame expands to four lines as that frame loses focus, and the minibuffer window on the newly selected frame contracts back down to one line. Are all of these behaviors expected and correct? (Again, I have no opinion; I’m just trying to understand how things are meant to work.) > > > I just tested, and binding `resize-mini-windows` to nil around the > > window selection in `term-emulate-terminal` does solve my > > problem. Does this seem like the right fix? I think it is surprising > > that output from a term process coming in the background should resize > > a minibuffer window (and especially an active one). > > If you look into the code of do_switch_frame (in frame.c) you will be > able to spot > > if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) > resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); > > which means that currently even redisplay itself may resize the mini > window every time it constructs a mode line or frame title. I can only > offer two advices: (1) Avoid 'with-selected-window/frame' in timers and > (2) make sure no redisplay happen _within_ such a form. Interesting. I think this partially explains the behaviors I’m seeing above. To be clear, `term-emulate-terminal` is a process filter. I’m not sure if that’s exactly like a timer under the hood, but it does run without user interaction. > > > Also, I see that `term-emulate-terminal` is calling `select-window` to > > perform its window selections. From my reading of the docs, I think it > > might make sense for it to pass `mark-for-redisplay` as the `norecord` > > argument. It doesn't seem like we should be modifying the buffer list > > or most recently selected window in this case, but we do want to > > redisplay the new output. > > I would have to understand the semantics of 'term-emulate-terminal' to > answer that. Hopefully, someone else can chime in here. I can give a little information here, though someone else will surely know more. This function is the process filter for a term process, so it handles new output from the process. After doing so, it iterates over all the windows to see if any contain the process buffer. For any that are, it selects those windows and scrolls those windows appropriately. > > > I think the documentation should clarify that window selection can > > change window sizes as a side effect. The docs for selecting windows > > (https://www.gnu.org/software/emacs/manual/html_node/elisp/Selecting-Windows.html) > > do not mention that `select-window` can change minibuffer sizes. The > > docs for minibuffer windows > > (https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Windows.html) > > do mention these variables to control how minibuffer windows can be > > resized automatically, but they do not say what functions might try to > > do this automatic resizing. > > With the recently added 'minibuffer-follows-selected-frame' we now have > an additional source of complications to consider. Maybe you could, as > soon as the implementation of the latter has consolidated, play with the > various values of 'resize-mini-windows' and suggest suitable fixes for > the documentations of 'select-window' and 'select-frame'. Sure, I can do that. Is there a timeline for this or some place I can follow development progress? From testing the current implementation, it seems selectrum has a similar issue here: when I switch to a new frame, the minibuffer does follow, but the list of candidates is hidden until I enter a new input. > > Alternatively, we could consider skipping the > > resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); > > above for temporary window/frame selections (and at least for redisplay > as I currently do here) but the consequences of such a step are not > easily fathomable. > > > Finally, I wonder if `with-selected-window` (which > > `term-emulate-terminal` does not currently use) should bind > > `resize-mini-windows`. > > ... with the consequences I mentioned in the sentence before ... > > > The docs say it is "the preferred way to > > temporarily work with" a selected window, so it does seem like > > automatic resizing is not in the spirit of the function. On the other > > hand, I don't know all the existing use cases; maybe this would break > > things. > > Right. > > martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Tue, 01 Dec 2020 09:34:02 GMT) Full text and rfc822 format available.Message #20 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Tue, 1 Dec 2020 10:33:42 +0100
> I’m not sure I understand. Are you saying a program should not be able > to grow the minibuffer window this way? Or just that it will be undone > by the next resizing event? (Of course, this is a toy example, so I > have no opinion on what the correct behavior should be. I’m just > wondering.) With 'resize-mini-windows' non-nil, redisplay can resize a normal minibuffer window (the one at the bottom of a normal frame) any time thus overriding any manual resizing done by the user. With 'grow-only' it cannot auto-shrink it to some value above the minimum one, so if you make the window manually very large, redisplay can shrink it only when the minibuffer gets empty. Note that there is no "correct" behavior here, everything grew out of fixing inconveniences found in daily use. > I’ve been playing with this a bit (on a recent Emacs 28.0.50), and I’m not sure I understand the current behavior. > > For example, I have three frames open and I ran this code in the scratch buffer: > > (with-current-buffer (window-buffer (minibuffer-window)) > (remove-overlays) > (erase-buffer) > (insert "this is some text") > (let ((ov (make-overlay (point) (point) nil t t))) > (overlay-put ov 'after-string "\none\ntwo\nthree"))) > > After moving the point, all I can see is the first line in the minibuffer: “this is some text”. This is true across all three frames. > > If I select the other frames by clicking on them, the frame that just lost focus will now show all four lines (i.e. including the overlay). The minibuffer windows on the other frames will stay at one line until I select them by clicking and then select some other frame. > > On the other hand, if I select frames by calling `other-frame` via a key binding, the behavior is slightly different: the minibuffer window on a frame expands to four lines as that frame loses focus, and the minibuffer window on the newly selected frame contracts back down to one line. > > Are all of these behaviors expected and correct? (Again, I have no opinion; I’m just trying to understand how things are meant to work.) Your example is a bit contrived in the sense that just inserting text into a minibuffer that is not active is not something redisplay really cares about. Putting that overlay into a prompt and then switching frames is more realistic wrt what redisplay really cares about. > This function is the process filter for a term process, so it handles > new output from the process. After doing so, it iterates over all the > windows to see if any contain the process buffer. For any that are, it > selects those windows and scrolls those windows appropriately. I didn't read the code very attentively but let's make sure one thing: The behavior you see happens only when there are at least two frames so the (setq win (next-window win nil t)) in 'term-emulate-terminal' and the subsequent (select-window win) really get executed and the latter selects a _different_ frame thus causing the earlier mentioned if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); Maybe you could instrument 'term-emulate-terminal' and 'do_switch_frame' (debugging this is probably useless) so that they write something into a buffer and we can see the precise interleaving of steps leading to the behavior seen. >> With the recently added 'minibuffer-follows-selected-frame' we now have >> an additional source of complications to consider. Maybe you could, as >> soon as the implementation of the latter has consolidated, play with the >> various values of 'resize-mini-windows' and suggest suitable fixes for >> the documentations of 'select-window' and 'select-frame'. > > Sure, I can do that. Is there a timeline for this or some place I can follow development progress? You can try to follow the thread "Stop frames stealing eachothers' minibuffers!" on emacs-devel and you will see that we all are quite often surprised by how the various versions of Emacs handle switching from one minibuffer window to another. > From testing the current implementation, it seems selectrum has a > similar issue here: when I switch to a new frame, the minibuffer does > follow, but the list of candidates is hidden until I enter a new > input. I suppose "showing the list of candidates" is part of a minibuffer interaction and the initial prompt is shown correctly on its frame but disappears when moving to another frame via C-x 5 o. Right? martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Tue, 01 Dec 2020 20:33:01 GMT) Full text and rfc822 format available.Message #23 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: martin rudalics <rudalics <at> gmx.at> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Tue, 1 Dec 2020 15:32:48 -0500
[Message part 1 (text/plain, inline)]
Hi Martin, > On Dec 1, 2020, at 4:33 AM, martin rudalics <rudalics <at> gmx.at> wrote: > > > I’m not sure I understand. Are you saying a program should not be able > > to grow the minibuffer window this way? Or just that it will be undone > > by the next resizing event? (Of course, this is a toy example, so I > > have no opinion on what the correct behavior should be. I’m just > > wondering.) > > With 'resize-mini-windows' non-nil, redisplay can resize a normal > minibuffer window (the one at the bottom of a normal frame) any time > thus overriding any manual resizing done by the user. With 'grow-only' > it cannot auto-shrink it to some value above the minimum one, so if you > make the window manually very large, redisplay can shrink it only when > the minibuffer gets empty. Note that there is no "correct" behavior > here, everything grew out of fixing inconveniences found in daily use. I see, so redisplay could happen at any time, and redisplay can resize the minibuffer window (contingent on `resize-mini-windows`). I guess in the extreme case, any code could call the `redisplay` function explicitly. > > > I’ve been playing with this a bit (on a recent Emacs 28.0.50), and I’m not sure I understand the current behavior. > > > > For example, I have three frames open and I ran this code in the scratch buffer: > > > > (with-current-buffer (window-buffer (minibuffer-window)) > > (remove-overlays) > > (erase-buffer) > > (insert "this is some text") > > (let ((ov (make-overlay (point) (point) nil t t))) > > (overlay-put ov 'after-string "\none\ntwo\nthree"))) > > > > After moving the point, all I can see is the first line in the minibuffer: “this is some text”. This is true across all three frames. > > > > If I select the other frames by clicking on them, the frame that just lost focus will now show all four lines (i.e. including the overlay). The minibuffer windows on the other frames will stay at one line until I select them by clicking and then select some other frame. > > > > On the other hand, if I select frames by calling `other-frame` via a key binding, the behavior is slightly different: the minibuffer window on a frame expands to four lines as that frame loses focus, and the minibuffer window on the newly selected frame contracts back down to one line. > > > > Are all of these behaviors expected and correct? (Again, I have no opinion; I’m just trying to understand how things are meant to work.) > > Your example is a bit contrived in the sense that just inserting text > into a minibuffer that is not active is not something redisplay really > cares about. Putting that overlay into a prompt and then switching > frames is more realistic wrt what redisplay really cares about. Fair point, it’s definitely a contrived example. > > > This function is the process filter for a term process, so it handles > > new output from the process. After doing so, it iterates over all the > > windows to see if any contain the process buffer. For any that are, it > > selects those windows and scrolls those windows appropriately. > > I didn't read the code very attentively but let's make sure one thing: > The behavior you see happens only when there are at least two frames so > the > > (setq win (next-window win nil t)) > > in 'term-emulate-terminal' and the subsequent > > (select-window win) > > really get executed and the latter selects a _different_ frame thus > causing the earlier mentioned > > if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) > resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); > > Maybe you could instrument 'term-emulate-terminal' and 'do_switch_frame' > (debugging this is probably useless) so that they write something into a > buffer and we can see the precise interleaving of steps leading to the > behavior seen. Yeah, I think it does depend on having multiple frames. In the specific case where I first noticed the strange behavior, my setup was: Frame X with a window displaying a subprocess running under term Frame Y with a window displaying some other buffer Frame Y is selected Selectrum (https://github.com/raxod502/selectrum) is installed as the completing read implementation I invoked some command that performed a completing read via selectrum (e.g. `find-file` or similar) with the list of candidates displayed vertically below the prompt. While I was sitting with that prompt, the subprocess sent some output. This induced the temporary selection of frame X via the code in term, which caused the list of completing read candidates to disappear. Anyway, I’ll perform the instrumentation you suggest, so we can understand specifically what is happening. > > >> With the recently added 'minibuffer-follows-selected-frame' we now have > >> an additional source of complications to consider. Maybe you could, as > >> soon as the implementation of the latter has consolidated, play with the > >> various values of 'resize-mini-windows' and suggest suitable fixes for > >> the documentations of 'select-window' and 'select-frame'. > > > > Sure, I can do that. Is there a timeline for this or some place I can follow development progress? > > You can try to follow the thread "Stop frames stealing eachothers' > minibuffers!" on emacs-devel and you will see that we all are quite > often surprised by how the various versions of Emacs handle switching > from one minibuffer window to another. Thanks, I’ll check it out. > > > From testing the current implementation, it seems selectrum has a > > similar issue here: when I switch to a new frame, the minibuffer does > > follow, but the list of candidates is hidden until I enter a new > > input. > > I suppose "showing the list of candidates" is part of a minibuffer > interaction and the initial prompt is shown correctly on its frame but > disappears when moving to another frame via C-x 5 o. Right? Yes, exactly. I can try to make a video of this if it would help. Thanks! > > martin >
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Wed, 02 Dec 2020 07:46:01 GMT) Full text and rfc822 format available.Message #26 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Wed, 2 Dec 2020 08:45:15 +0100
> I see, so redisplay could happen at any time, and redisplay can resize > the minibuffer window (contingent on `resize-mini-windows`). I guess > in the extreme case, any code could call the `redisplay` function > explicitly. Yes. > Anyway, I’ll perform the instrumentation you suggest, so we can > understand specifically what is happening. I forgot to say that _all_ normal mini window resizing goes through 'window--resize-root-window-vertically' in window.el. So it will probably suffice to instrument just that function (in an already running Emacs only, else you have to rebuild because window.el is preloaded) and don't have to tinker with C code at all. martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Wed, 02 Dec 2020 07:53:02 GMT) Full text and rfc822 format available.Message #29 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Wed, 2 Dec 2020 08:52:49 +0100
> I forgot to say that _all_ normal mini window resizing goes through > 'window--resize-root-window-vertically' in window.el. So it will > probably suffice to instrument just that function (in an already running > Emacs only, else you have to rebuild because window.el is preloaded) and > don't have to tinker with C code at all. Imprecise again: The above covers only the automatic resizing triggered by redisplay (which is what we are interested in). Manual resizing the minibuffer window is done in 'window--resize-mini-window' (also in window.el) so if such manual resizing may happen in between you have to instrument that as well. martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Wed, 02 Dec 2020 18:25:02 GMT) Full text and rfc822 format available.Message #32 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: martin rudalics <rudalics <at> gmx.at> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Wed, 2 Dec 2020 13:24:24 -0500
Hi Martin, Thanks for all the helpful info! > On Dec 2, 2020, at 2:52 AM, martin rudalics <rudalics <at> gmx.at> wrote: > > > I forgot to say that _all_ normal mini window resizing goes through > > 'window--resize-root-window-vertically' in window.el. So it will > > probably suffice to instrument just that function (in an already running > > Emacs only, else you have to rebuild because window.el is preloaded) and > > don't have to tinker with C code at all. > > Imprecise again: The above covers only the automatic resizing triggered > by redisplay (which is what we are interested in). Manual resizing the > minibuffer window is done in 'window--resize-mini-window' (also in > window.el) so if such manual resizing may happen in between you have to > instrument that as well. I see, I’ll take a look at these functions. Thanks! > > martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Sat, 12 Dec 2020 20:24:01 GMT) Full text and rfc822 format available.Message #35 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: martin rudalics <rudalics <at> gmx.at> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Sat, 12 Dec 2020 15:23:17 -0500
[Message part 1 (text/plain, inline)]
Hi Martin, Thanks for waiting on this update. I instrumented the code in a couple key places and then exercised the bug. Attached is the log showing what happened. Basically, I put two calls to my log function around the window selection in ’term-emulate-terminal and one inside ‘window—resize-root-window-vertically. Next, I opened a term window running a script that prints some output every few seconds. I had one frame running the script under term, and I selected a second frame and invoked some completing read command. As before, the minibuffer window shrank when the script printed some output. You can find the start of each entry by searching for the regexp “^>>>>”. I wasn’t sure what to include in each entry, but I printed the selected frame, the selected window, that window’s buffer, and a backtrace. I can easily add more information and run the experiment again, if there’s something else you’d like to see. Thanks! > On Dec 2, 2020, at 1:24 PM, Sean Devlin <spd <at> toadstyle.org> wrote: > > Hi Martin, > > Thanks for all the helpful info! > >> On Dec 2, 2020, at 2:52 AM, martin rudalics <rudalics <at> gmx.at> wrote: >> >>> I forgot to say that _all_ normal mini window resizing goes through >>> 'window--resize-root-window-vertically' in window.el. So it will >>> probably suffice to instrument just that function (in an already running >>> Emacs only, else you have to rebuild because window.el is preloaded) and >>> don't have to tinker with C code at all. >> >> Imprecise again: The above covers only the automatic resizing triggered >> by redisplay (which is what we are interested in). Manual resizing the >> minibuffer window is done in 'window--resize-mini-window' (also in >> window.el) so if such manual resizing may happen in between you have to >> instrument that as well. > > I see, I’ll take a look at these functions. Thanks! > >> >> martin
[Message part 2 (text/html, inline)]
[redisplay-minibuffer.log (application/octet-stream, attachment)]
[Message part 4 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Sun, 13 Dec 2020 07:27:02 GMT) Full text and rfc822 format available.Message #38 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Sun, 13 Dec 2020 08:26:28 +0100
> I instrumented the code in a couple key places and then exercised the > bug. Attached is the log showing what happened. I'm afraid you forgot to attach the log. martin
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Sun, 13 Dec 2020 16:11:01 GMT) Full text and rfc822 format available.Message #41 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: Sean Devlin <spd <at> toadstyle.org> To: martin rudalics <rudalics <at> gmx.at> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Sun, 13 Dec 2020 11:10:23 -0500
[Message part 1 (text/plain, inline)]
Hmm, it seems to show up on the web site: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=44933#35. Maybe it is getting filtered out somewhere due to size or file extension or something? > On Dec 13, 2020, at 2:26 AM, martin rudalics <rudalics <at> gmx.at> wrote: > > > I instrumented the code in a couple key places and then exercised the > > bug. Attached is the log showing what happened. > > I'm afraid you forgot to attach the log. > > martin
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#44933
; Package emacs
.
(Mon, 14 Dec 2020 15:48:02 GMT) Full text and rfc822 format available.Message #44 received at 44933 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Sean Devlin <spd <at> toadstyle.org> Cc: 44933 <at> debbugs.gnu.org Subject: Re: bug#44933: 27.1; Ephemeral frame selection shrinks minibuffer Date: Mon, 14 Dec 2020 16:47:06 +0100
> Hmm, it seems to show up on the web site: > https://debbugs.gnu.org/cgi/bugreport.cgi?bug=44933#35. Maybe it is > getting filtered out somewhere due to size or file extension or > something? The attachment shows up in the source text but Thunderbird refuses to mention or show it here. Emacs has also problems showing it, some lines are over 4000 characters wide. I have no idea what makes these backtraces behave so unbridled. Maybe setting `backtrace-line-length' to something like 80 would help. Now the basic problem is that I can see only one 'window--resize-root-window-vertically' call and I'd like to see at least the one where that minibuffer window was enlarged before. So please try to either set `backtrace-line-length' or do not call 'backtrace' at all when logging and in 'window--resize-root-window-vertically' just before it says ;; Return the possibly adjusted DELTA. add a line putting into the log the values of 'delta' and 'pixel-delta' and in 'window--resize-mini-window' just before it says (unless (zerop delta) add a line putting into the log the value of 'delta'. Maybe then we can tell more. BTW from window--resize-root-window-vertically(#<window 3 on *redisplay-minibuffer-log*> 70 t) I conclude that the minibuffer window that gets resized is on a frame with only one other window - the one showing *redisplay-minibuffer-log* - right? Thanks, martin
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.