* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly @ 2022-05-14 15:45 Christian Tanzer 2022-05-14 16:58 ` Eli Zaretskii 2022-05-15 9:28 ` martin rudalics 0 siblings, 2 replies; 29+ messages in thread From: Christian Tanzer @ 2022-05-14 15:45 UTC (permalink / raw) To: 55412 ============================================================================= ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one ;;; uses a frame-parameter in ':eval'. ;;; ;;; The following elisp snippet demonstrates the problem in an Emacs 28.1 ;;; instance started with 'emacs -Q' (defun title-suffix () (cdr (assoc 'title-suffix (frame-parameters (selected-frame))))) (defvar title-prefix "Test") (setq frame-title-format (list title-prefix '(:eval (title-suffix)) " %b")) ;;; The original frame should show a frame title of 'Test *scratch*' (set-frame-parameter (selected-frame) 'title-suffix "") ;;; The next frame created should show a frame title of 'Test-xxx *scratch*' (make-frame-command) (set-frame-parameter (selected-frame) 'title-suffix "-xxx") ;;; The third frame created should show a frame title of 'Test-yyy *scratch*' (make-frame-command) (set-frame-parameter (selected-frame) 'title-suffix "-yyy") ;;; In Emacs 27 and earlier, that is exactly what happens. Selecting a ;;; different frame doesn't change the titles of all other frames. ;;; In Emacs 28.1, all frames show the same frame title, with the last one ;;; selected determining which one is shown for the bunch of them. Changing to ;;; a different frame changes the titles of all frames to the title of the ;;; newly selected one. ========================================================================== In GNU Emacs 28.1 (build 1, aarch64-apple-darwin21.1.0, NS appkit-2113.00 Version 12.0.1 (Build 21A559)) of 2022-04-04 built on armbob.lan Windowing system distributor 'Apple', version 10.3.2113 System Description: macOS 12.3.1 Configured using: 'configure --with-ns '--enable-locallisppath=/Library/Application Support/Emacs/${version}/site-lisp:/Library/Application Support/Emacs/site-lisp' --with-modules' Configured features: ACL GMP GNUTLS JSON LIBXML2 MODULES NOTIFY KQUEUE NS PDUMPER THREADS TOOLKIT_SCROLL_BARS ZLIB Important settings: value of $EMACSLOADPATH: /Users/tanzer/.emacs.lib::/Applications/Emacs.app/Contents/Resources/site-lisp: value of $LC_CTYPE: UTF-8 value of $LC_MESSAGES: en_US.UTF-8 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 show-paren-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 indent-tabs-mode: t transient-mark-mode: t Load-path shadows: /Users/tanzer/.emacs.lib/custom hides /Applications/Emacs-28.1.app/Contents/Resources/lisp/custom /Users/tanzer/.emacs.lib/iso-transl hides /Applications/Emacs-28.1.app/Contents/Resources/lisp/international/iso-transl Features: (shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs rfc822 mml mml-sec epa derived epg rfc6068 epg-config gnus-util rmail rmail-loaddefs auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs password-cache json map 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 iso-transl tooltip eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode 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 lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax 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 emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice button loaddefs faces cus-face macroexp files window 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 51129 6052) (symbols 48 6554 1) (strings 32 18387 2569) (string-bytes 1 613674) (vectors 16 14168) (vector-slots 8 205987 11758) (floats 8 33 51) (intervals 56 234 0) (buffers 992 10)) ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-14 15:45 bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly Christian Tanzer @ 2022-05-14 16:58 ` Eli Zaretskii 2022-05-14 17:07 ` Eli Zaretskii ` (3 more replies) 2022-05-15 9:28 ` martin rudalics 1 sibling, 4 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-14 16:58 UTC (permalink / raw) To: tanzer, Alan Mackenzie; +Cc: 55412 > Date: Sat, 14 May 2022 15:45:10 -0000 > From: Christian Tanzer <tanzer@swing.co.at> > > ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one > ;;; uses a frame-parameter in ':eval'. > ;;; > ;;; The following elisp snippet demonstrates the problem in an Emacs 28.1 > ;;; instance started with 'emacs -Q' > > (defun title-suffix () > (cdr (assoc 'title-suffix (frame-parameters (selected-frame))))) > > (defvar title-prefix "Test") > (setq frame-title-format (list title-prefix '(:eval (title-suffix)) " %b")) > > ;;; The original frame should show a frame title of 'Test *scratch*' > (set-frame-parameter (selected-frame) 'title-suffix "") > > ;;; The next frame created should show a frame title of 'Test-xxx *scratch*' > (make-frame-command) > (set-frame-parameter (selected-frame) 'title-suffix "-xxx") > > ;;; The third frame created should show a frame title of 'Test-yyy *scratch*' > (make-frame-command) > (set-frame-parameter (selected-frame) 'title-suffix "-yyy") > > ;;; In Emacs 27 and earlier, that is exactly what happens. Selecting a > ;;; different frame doesn't change the titles of all other frames. > > ;;; In Emacs 28.1, all frames show the same frame title, with the last one > ;;; selected determining which one is shown for the bunch of them. Changing to > ;;; a different frame changes the titles of all frames to the title of the > ;;; newly selected one. Thank you for your report. Alan, this is due to one of the changes introduced for the minibuffer-follows-selected-frame feature. Specifically, commit 7c2ebf6 made a change in gui_consider_frame_title which causes this regression. If I revert a part of that commit shown below: diff --git a/src/xdisp.c b/src/xdisp.c index 6963935..9740e6b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12796,8 +12796,9 @@ gui_consider_frame_title (Lisp_Object frame) mode_line_noprop_buf; then display the title. */ record_unwind_protect (unwind_format_mode_line, format_mode_line_unwind_data - (NULL, current_buffer, Qnil, false)); + (f, current_buffer, selected_window, false)); + Fselect_window (f->selected_window, Qt); set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->contents)); fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; then the problem goes away. The log message of that commit says about this part: * src/xdisp.c (gui_consider_frame_title): Remove redundant Fselect_window, which caused an unwanted frame switch. Amend the arguments to format_mode_line_unwind_data to match. As you see, the call to select-window is not redundant, because without it the frame's title cannot reference the frame-parameters of that frame. Do you remember why the frame switch here was "unwanted"? What bad things happen if we restore the removed code? Thanks. ^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-14 16:58 ` Eli Zaretskii @ 2022-05-14 17:07 ` Eli Zaretskii 2022-05-15 9:48 ` Alan Mackenzie ` (2 subsequent siblings) 3 siblings, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-14 17:07 UTC (permalink / raw) To: acm; +Cc: 55412, tanzer > Cc: 55412@debbugs.gnu.org > Date: Sat, 14 May 2022 19:58:13 +0300 > From: Eli Zaretskii <eliz@gnu.org> > > If I revert a part of that commit shown below: Sorry for confusing wording. I meant to say If I revert a part of that commit _as_ shown below: That is, what was "shown below" was the _reverse_ of what commit 7c2ebf6 did. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-14 16:58 ` Eli Zaretskii 2022-05-14 17:07 ` Eli Zaretskii @ 2022-05-15 9:48 ` Alan Mackenzie 2022-05-15 10:16 ` Eli Zaretskii 2022-05-16 20:52 ` Alan Mackenzie 2022-05-20 20:39 ` Alan Mackenzie 3 siblings, 1 reply; 29+ messages in thread From: Alan Mackenzie @ 2022-05-15 9:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 55412, tanzer On Sat, May 14, 2022 at 19:58:13 +0300, Eli Zaretskii wrote: > > Date: Sat, 14 May 2022 15:45:10 -0000 > > From: Christian Tanzer <tanzer@swing.co.at> > > ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it > > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one > > ;;; uses a frame-parameter in ':eval'. > > ;;; > > ;;; The following elisp snippet demonstrates the problem in an Emacs 28.1 > > ;;; instance started with 'emacs -Q' > > (defun title-suffix () > > (cdr (assoc 'title-suffix (frame-parameters (selected-frame))))) > > (defvar title-prefix "Test") > > (setq frame-title-format (list title-prefix '(:eval (title-suffix)) " %b")) > > ;;; The original frame should show a frame title of 'Test *scratch*' > > (set-frame-parameter (selected-frame) 'title-suffix "") > > ;;; The next frame created should show a frame title of 'Test-xxx *scratch*' > > (make-frame-command) > > (set-frame-parameter (selected-frame) 'title-suffix "-xxx") > > ;;; The third frame created should show a frame title of 'Test-yyy *scratch*' > > (make-frame-command) > > (set-frame-parameter (selected-frame) 'title-suffix "-yyy") > > ;;; In Emacs 27 and earlier, that is exactly what happens. Selecting a > > ;;; different frame doesn't change the titles of all other frames. > > ;;; In Emacs 28.1, all frames show the same frame title, with the last one > > ;;; selected determining which one is shown for the bunch of them. Changing to > > ;;; a different frame changes the titles of all frames to the title of the > > ;;; newly selected one. > Thank you for your report. > Alan, this is due to one of the changes introduced for the > minibuffer-follows-selected-frame feature. Specifically, commit > 7c2ebf6 made a change in gui_consider_frame_title which causes this > regression. If I revert a part of that commit [as] shown below: > diff --git a/src/xdisp.c b/src/xdisp.c > index 6963935..9740e6b 100644 > --- a/src/xdisp.c > +++ b/src/xdisp.c > @@ -12796,8 +12796,9 @@ gui_consider_frame_title (Lisp_Object frame) > mode_line_noprop_buf; then display the title. */ > record_unwind_protect (unwind_format_mode_line, > format_mode_line_unwind_data > - (NULL, current_buffer, Qnil, false)); > + (f, current_buffer, selected_window, false)); > + Fselect_window (f->selected_window, Qt); > set_buffer_internal_1 > (XBUFFER (XWINDOW (f->selected_window)->contents)); > fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; > then the problem goes away. > The log message of that commit says about this part: > * src/xdisp.c (gui_consider_frame_title): Remove redundant Fselect_window, > which caused an unwanted frame switch. Amend the arguments to > format_mode_line_unwind_data to match. > As you see, the call to select-window is not redundant, because > without it the frame's title cannot reference the frame-parameters of > that frame. > Do you remember why the frame switch here was "unwanted"? What > bad things happen if we restore the removed code? I remember vaguely that that call to Fselect_window caused minibuffers to be switched between frames in an unwanted fashion. I've got detailed notes of what I did, still. I'll probably not have much chance to look at the bug today, but should do over the next few days. > Thanks. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-15 9:48 ` Alan Mackenzie @ 2022-05-15 10:16 ` Eli Zaretskii 0 siblings, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-15 10:16 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, tanzer > Date: Sun, 15 May 2022 09:48:37 +0000 > Cc: tanzer@swing.co.at, 55412@debbugs.gnu.org > From: Alan Mackenzie <acm@muc.de> > > > Do you remember why the frame switch here was "unwanted"? What > > bad things happen if we restore the removed code? > > I remember vaguely that that call to Fselect_window caused minibuffers to > be switched between frames in an unwanted fashion. If that is the problem, we could perhaps countermand it by binding some variable across the call. > I've got detailed notes of what I did, still. I'll probably not > have much chance to look at the bug today, but should do over the > next few days. TIA. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-14 16:58 ` Eli Zaretskii 2022-05-14 17:07 ` Eli Zaretskii 2022-05-15 9:48 ` Alan Mackenzie @ 2022-05-16 20:52 ` Alan Mackenzie 2022-05-17 13:25 ` Eli Zaretskii 2022-05-18 7:19 ` martin rudalics 2022-05-20 20:39 ` Alan Mackenzie 3 siblings, 2 replies; 29+ messages in thread From: Alan Mackenzie @ 2022-05-16 20:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 55412, tanzer, acm Hello, Eli. On Sat, May 14, 2022 at 19:58:13 +0300, Eli Zaretskii wrote: > > Date: Sat, 14 May 2022 15:45:10 -0000 > > From: Christian Tanzer <tanzer@swing.co.at> > > ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it > > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one > > ;;; uses a frame-parameter in ':eval'. > > ;;; > > ;;; The following elisp snippet demonstrates the problem in an Emacs 28.1 > > ;;; instance started with 'emacs -Q' [ .... ] > > ;;; In Emacs 27 and earlier, that is exactly what happens. Selecting a > > ;;; different frame doesn't change the titles of all other frames. > > ;;; In Emacs 28.1, all frames show the same frame title, with the last one > > ;;; selected determining which one is shown for the bunch of them. Changing to > > ;;; a different frame changes the titles of all frames to the title of the > > ;;; newly selected one. > Thank you for your report. > Alan, this is due to one of the changes introduced for the > minibuffer-follows-selected-frame feature. Specifically, commit > 7c2ebf6 made a change in gui_consider_frame_title which causes this > regression. If I revert a part of that commit as shown below: > diff --git a/src/xdisp.c b/src/xdisp.c > index 6963935..9740e6b 100644 > --- a/src/xdisp.c > +++ b/src/xdisp.c > @@ -12796,8 +12796,9 @@ gui_consider_frame_title (Lisp_Object frame) > mode_line_noprop_buf; then display the title. */ > record_unwind_protect (unwind_format_mode_line, > format_mode_line_unwind_data > - (NULL, current_buffer, Qnil, false)); > + (f, current_buffer, selected_window, false)); > + Fselect_window (f->selected_window, Qt); > set_buffer_internal_1 > (XBUFFER (XWINDOW (f->selected_window)->contents)); > fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; > then the problem goes away. Yes. It is clear that that Fselect_window call is needed. > The log message of that commit says about this part: > * src/xdisp.c (gui_consider_frame_title): Remove redundant Fselect_window, > which caused an unwanted frame switch. Amend the arguments to > format_mode_line_unwind_data to match. > As you see, the call to select-window is not redundant, because > without it the frame's title cannot reference the frame-parameters of > that frame. > Do you remember why the frame switch here was "unwanted"? What > bad things happen if we restore the removed code? I think I've managed to reconstruct why I made this part of the change. With the Fselect_window call in place: (i) When minibuffer-follows-selected-frame is nil, and the minibuffer is the current window before switching frames with C-x 5 o, it remains the current window on returning to the first frame. (ii) When minibuffer-follows-selected-frame is t (the default) and other circumstances are as in (i), the minibuffer is no longer the selected window on returning to the first frame. I wanted to fix this inconsistency, I think. Clearly, this inconsistency is less important than frame-title-format not working. May I suggest that one of us applies your patch immediately to the release branch. I will then attempt to find a less harmful way of fixing that inconsistency, and will take direction from you which branch it should be committed to. > Thanks. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-16 20:52 ` Alan Mackenzie @ 2022-05-17 13:25 ` Eli Zaretskii 2022-05-18 7:19 ` martin rudalics 1 sibling, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-17 13:25 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, tanzer, acm > Date: Mon, 16 May 2022 20:52:42 +0000 > Cc: tanzer@swing.co.at, 55412@debbugs.gnu.org, acm@muc.de > From: Alan Mackenzie <acm@muc.de> > > I think I've managed to reconstruct why I made this part of the change. > With the Fselect_window call in place: > (i) When minibuffer-follows-selected-frame is nil, and the minibuffer is > the current window before switching frames with C-x 5 o, it remains the > current window on returning to the first frame. > (ii) When minibuffer-follows-selected-frame is t (the default) and other > circumstances are as in (i), the minibuffer is no longer the selected > window on returning to the first frame. > I wanted to fix this inconsistency, I think. > > Clearly, this inconsistency is less important than frame-title-format not > working. May I suggest that one of us applies your patch immediately to > the release branch. I will then attempt to find a less harmful way of > fixing that inconsistency, and will take direction from you which branch > it should be committed to. Thanks, please go ahead and install the patch on the emacs-28 branch. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-16 20:52 ` Alan Mackenzie 2022-05-17 13:25 ` Eli Zaretskii @ 2022-05-18 7:19 ` martin rudalics 2022-05-18 11:35 ` Eli Zaretskii 1 sibling, 1 reply; 29+ messages in thread From: martin rudalics @ 2022-05-18 7:19 UTC (permalink / raw) To: Alan Mackenzie, Eli Zaretskii; +Cc: 55412, tanzer > With the Fselect_window call in place: > (i) When minibuffer-follows-selected-frame is nil, and the minibuffer is > the current window before switching frames with C-x 5 o, it remains the > current window on returning to the first frame. > (ii) When minibuffer-follows-selected-frame is t (the default) and other > circumstances are as in (i), the minibuffer is no longer the selected > window on returning to the first frame. > I wanted to fix this inconsistency, I think. > > Clearly, this inconsistency is less important than frame-title-format not > working. When I type M-:, save the expression to evaluate from some other frame, and the subsequent yank inserts that expression into a normal buffer instead of the minibuffer, the resulting behavior does not constitute a less important inconsistency but an annoying regression. This is one of the things that used to work "ever since". > May I suggest that one of us applies your patch immediately to > the release branch. I will then attempt to find a less harmful way of > fixing that inconsistency, and will take direction from you which branch > it should be committed to. In that case please default 'minibuffer-follows-selected-frame' to nil and then try to find a suitable solution. Or try the patch I posted. martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 7:19 ` martin rudalics @ 2022-05-18 11:35 ` Eli Zaretskii 2022-05-18 15:01 ` martin rudalics 0 siblings, 1 reply; 29+ messages in thread From: Eli Zaretskii @ 2022-05-18 11:35 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, acm, tanzer > Date: Wed, 18 May 2022 09:19:48 +0200 > Cc: 55412@debbugs.gnu.org, tanzer@swing.co.at > From: martin rudalics <rudalics@gmx.at> > > When I type M-:, save the expression to evaluate from some other frame, > and the subsequent yank inserts that expression into a normal buffer > instead of the minibuffer, the resulting behavior does not constitute a > less important inconsistency but an annoying regression. This is one of > the things that used to work "ever since". Can you tell more about the inconsistency you get in this scenario? I'm afraid I don't follow the description and therefore cannot try reproducing it myself. Thanks. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 11:35 ` Eli Zaretskii @ 2022-05-18 15:01 ` martin rudalics 2022-05-18 15:12 ` Alan Mackenzie 2022-05-18 15:49 ` Alan Mackenzie 0 siblings, 2 replies; 29+ messages in thread From: martin rudalics @ 2022-05-18 15:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 55412, acm, tanzer >> When I type M-:, save the expression to evaluate from some other frame, >> and the subsequent yank inserts that expression into a normal buffer >> instead of the minibuffer, the resulting behavior does not constitute a >> less important inconsistency but an annoying regression. This is one of >> the things that used to work "ever since". > > Can you tell more about the inconsistency you get in this scenario? > I'm afraid I don't follow the description and therefore cannot try > reproducing it myself. Suppose I want to calculate the sum of two numbers: number-1 is shown in a buffer on frame-1, number-2 is show in a buffer on frame-2. I start typing M-: (+ on frame-1 then I do C-x o, mark number-1, type M-w, C-x o and C-y to yank number-1 into the minibuffer. Then I add a space to the minibuffer, type C-x 5 o to go to frame-2, mark number-2, type M-w and C-x 5 o to get back to frame-1. Ever since, that last C-x 5 o got me to the minibuffer window. With the proposed change, that C-x 5 o will get me to the window of number-1 and I have to manually select the minibuffer window to yank number-2 there. martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 15:01 ` martin rudalics @ 2022-05-18 15:12 ` Alan Mackenzie 2022-05-18 15:49 ` Alan Mackenzie 1 sibling, 0 replies; 29+ messages in thread From: Alan Mackenzie @ 2022-05-18 15:12 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, tanzer, Eli Zaretskii Hello, Martin. On Wed, May 18, 2022 at 17:01:43 +0200, martin rudalics wrote: > >> When I type M-:, save the expression to evaluate from some other frame, > >> and the subsequent yank inserts that expression into a normal buffer > >> instead of the minibuffer, the resulting behavior does not constitute a > >> less important inconsistency but an annoying regression. This is one of > >> the things that used to work "ever since". > > > > Can you tell more about the inconsistency you get in this scenario? > > I'm afraid I don't follow the description and therefore cannot try > > reproducing it myself. > Suppose I want to calculate the sum of two numbers: number-1 is shown in > a buffer on frame-1, number-2 is show in a buffer on frame-2. I start > typing M-: (+ on frame-1 then I do C-x o, mark number-1, type M-w, C-x o > and C-y to yank number-1 into the minibuffer. Then I add a space to the > minibuffer, type C-x 5 o to go to frame-2, mark number-2, type M-w and > C-x 5 o to get back to frame-1. > Ever since, that last C-x 5 o got me to the minibuffer window. With the > proposed change, that C-x 5 o will get me to the window of number-1 and > I have to manually select the minibuffer window to yank number-2 there. I think I can see where the problem is. I've even found the patch where this problem was introduced. I'll see if I can get a patch to you this evening to fix it. > martin -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 15:01 ` martin rudalics 2022-05-18 15:12 ` Alan Mackenzie @ 2022-05-18 15:49 ` Alan Mackenzie 2022-05-18 16:03 ` Eli Zaretskii 2022-05-19 7:18 ` martin rudalics 1 sibling, 2 replies; 29+ messages in thread From: Alan Mackenzie @ 2022-05-18 15:49 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, tanzer, Eli Zaretskii, acm Hello, Martin and Eli. On Wed, May 18, 2022 at 17:01:43 +0200, martin rudalics wrote: > >> When I type M-:, save the expression to evaluate from some other frame, > >> and the subsequent yank inserts that expression into a normal buffer > >> instead of the minibuffer, the resulting behavior does not constitute a > >> less important inconsistency but an annoying regression. This is one of > >> the things that used to work "ever since". > > Can you tell more about the inconsistency you get in this scenario? > > I'm afraid I don't follow the description and therefore cannot try > > reproducing it myself. > Suppose I want to calculate the sum of two numbers: number-1 is shown in > a buffer on frame-1, number-2 is show in a buffer on frame-2. I start > typing M-: (+ on frame-1 then I do C-x o, mark number-1, type M-w, C-x o > and C-y to yank number-1 into the minibuffer. Then I add a space to the > minibuffer, type C-x 5 o to go to frame-2, mark number-2, type M-w and > C-x 5 o to get back to frame-1. > Ever since, that last C-x 5 o got me to the minibuffer window. With the > proposed change, that C-x 5 o will get me to the window of number-1 and > I have to manually select the minibuffer window to yank number-2 there. Please try the following patch, which may solve the above problem without hurting the bug fix. diff --git a/src/frame.c b/src/frame.c index ccac18d23c..7869726850 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1564,6 +1564,10 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) last_nonminibuf_frame = XFRAME (selected_frame); + if (EQ (f->selected_window, f->minibuffer_window) + && NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt))) + Fset_frame_selected_window (frame, Fframe_first_window (frame), Qnil); + Fselect_window (f->selected_window, norecord); /* We want to make sure that the next event generates a frame-switch diff --git a/src/frame.h b/src/frame.h index 0b8cdf62de..87c44dd22b 100644 --- a/src/frame.h +++ b/src/frame.h @@ -123,7 +123,8 @@ #define EMACS_FRAME_H /* This frame's selected window. Each frame has its own window hierarchy and one of the windows in it is selected within the frame. - The selected window of the selected frame is Emacs's selected window. */ + The selected window of the selected frame is Emacs's selected window. + This window may be the mini-window of the frame. */ Lisp_Object selected_window; /* This frame's selected window when run_window_change_functions was diff --git a/src/minibuf.c b/src/minibuf.c index 847e7be5ad..66aed0ad70 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -203,14 +203,6 @@ move_minibuffers_onto_frame (struct frame *of, bool for_deletion) zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window); if (for_deletion && XFRAME (MB_frame) != of) MB_frame = selected_frame; - if (!for_deletion - && MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) - { - Lisp_Object old_frame; - XSETFRAME (old_frame, of); - Fset_frame_selected_window (old_frame, - Fframe_first_window (old_frame), Qnil); - } } } diff --git a/src/xdisp.c b/src/xdisp.c index 6963935666..7e166121df 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12796,8 +12796,10 @@ gui_consider_frame_title (Lisp_Object frame) mode_line_noprop_buf; then display the title. */ record_unwind_protect (unwind_format_mode_line, format_mode_line_unwind_data - (NULL, current_buffer, Qnil, false)); + (f, current_buffer, selected_window, false) + /* (NULL, current_buffer, Qnil, false) */); + Fselect_window (f->selected_window, Qt); set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->contents)); fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; > martin -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 15:49 ` Alan Mackenzie @ 2022-05-18 16:03 ` Eli Zaretskii 2022-05-18 16:38 ` Alan Mackenzie 2022-05-19 7:18 ` martin rudalics 1 sibling, 1 reply; 29+ messages in thread From: Eli Zaretskii @ 2022-05-18 16:03 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, rudalics, acm, tanzer > Date: Wed, 18 May 2022 15:49:36 +0000 > Cc: Eli Zaretskii <eliz@gnu.org>, 55412@debbugs.gnu.org, tanzer@swing.co.at, > acm@muc.de > From: Alan Mackenzie <acm@muc.de> > > > Suppose I want to calculate the sum of two numbers: number-1 is shown in > > a buffer on frame-1, number-2 is show in a buffer on frame-2. I start > > typing M-: (+ on frame-1 then I do C-x o, mark number-1, type M-w, C-x o > > and C-y to yank number-1 into the minibuffer. Then I add a space to the > > minibuffer, type C-x 5 o to go to frame-2, mark number-2, type M-w and > > C-x 5 o to get back to frame-1. > > > Ever since, that last C-x 5 o got me to the minibuffer window. With the > > proposed change, that C-x 5 o will get me to the window of number-1 and > > I have to manually select the minibuffer window to yank number-2 there. > > Please try the following patch, which may solve the above problem > without hurting the bug fix. Thanks, but shouldn't this somehow depend on the value of minibuffer-follows-selected-frame? ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 16:03 ` Eli Zaretskii @ 2022-05-18 16:38 ` Alan Mackenzie 2022-05-18 16:51 ` Eli Zaretskii 0 siblings, 1 reply; 29+ messages in thread From: Alan Mackenzie @ 2022-05-18 16:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 55412, rudalics, tanzer Hello, Eli. On Wed, May 18, 2022 at 19:03:32 +0300, Eli Zaretskii wrote: > > Date: Wed, 18 May 2022 15:49:36 +0000 > > Cc: Eli Zaretskii <eliz@gnu.org>, 55412@debbugs.gnu.org, tanzer@swing.co.at, > > acm@muc.de > > From: Alan Mackenzie <acm@muc.de> > > > Suppose I want to calculate the sum of two numbers: number-1 is shown in > > > a buffer on frame-1, number-2 is show in a buffer on frame-2. I start > > > typing M-: (+ on frame-1 then I do C-x o, mark number-1, type M-w, C-x o > > > and C-y to yank number-1 into the minibuffer. Then I add a space to the > > > minibuffer, type C-x 5 o to go to frame-2, mark number-2, type M-w and > > > C-x 5 o to get back to frame-1. > > > Ever since, that last C-x 5 o got me to the minibuffer window. With the > > > proposed change, that C-x 5 o will get me to the window of number-1 and > > > I have to manually select the minibuffer window to yank number-2 there. > > Please try the following patch, which may solve the above problem > > without hurting the bug fix. > Thanks, but shouldn't this somehow depend on the value of > minibuffer-follows-selected-frame? I think it does. If minibuffer-follows-selected-frame is nil, when we return to a frame on which a minibuffer has been opened, the minibuffer will still be there, so there is no need to select a different window. If m-f-s-frame is t, and we have moved away from the frame on which a minibuffer was opened, that minibuffer will have moved to the new frame. It will either be terminated before we return to the original frame (in which case we select a window different from the now invalid mini-window), or the minibuffer returns to the original frame when we switch back. The critical criterion is whether there's a valid minibuffer in the mini-window of the frame we switch to. It doesn't really matter whether that minibuffer has moved between frames, or was always there. So, maybe this process is independent of minibuffer-follow-selected-frame. But I think it works. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 16:38 ` Alan Mackenzie @ 2022-05-18 16:51 ` Eli Zaretskii 2022-05-20 8:23 ` martin rudalics 0 siblings, 1 reply; 29+ messages in thread From: Eli Zaretskii @ 2022-05-18 16:51 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, rudalics, tanzer > Date: Wed, 18 May 2022 16:38:32 +0000 > Cc: rudalics@gmx.at, 55412@debbugs.gnu.org, tanzer@swing.co.at > From: Alan Mackenzie <acm@muc.de> > > > Thanks, but shouldn't this somehow depend on the value of > > minibuffer-follows-selected-frame? > > I think it does. If minibuffer-follows-selected-frame is nil, when we > return to a frame on which a minibuffer has been opened, the minibuffer > will still be there, so there is no need to select a different window. > > If m-f-s-frame is t, and we have moved away from the frame on which a > minibuffer was opened, that minibuffer will have moved to the new frame. > It will either be terminated before we return to the original frame (in > which case we select a window different from the now invalid > mini-window), or the minibuffer returns to the original frame when we > switch back. > > The critical criterion is whether there's a valid minibuffer in the > mini-window of the frame we switch to. It doesn't really matter whether > that minibuffer has moved between frames, or was always there. So, > maybe this process is independent of minibuffer-follow-selected-frame. > But I think it works. It would be good to have some of these explanations in comments there. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 16:51 ` Eli Zaretskii @ 2022-05-20 8:23 ` martin rudalics 2022-05-20 10:58 ` Eli Zaretskii 2022-05-20 11:33 ` Alan Mackenzie 0 siblings, 2 replies; 29+ messages in thread From: martin rudalics @ 2022-05-20 8:23 UTC (permalink / raw) To: Eli Zaretskii, Alan Mackenzie; +Cc: 55412, tanzer > It would be good to have some of these explanations in comments there. I understand that we want a quick solution for the present bug so it can be included in Emacs 28.2. But I still don't understand why nobody even cared to try the patch I sent earlier. With the current code, whenever there are at least two frames present, 'gui_consider_frame_title' calls via Fselect_window among others redisplay_other_windows Fredirect_frame_focus resize_mini_window move_minibuffers_onto_frame and sets last_nonminibuf_frame internal_last_event_frame Has anyone ever tried to understand the implications of all these? Why should redisplay indiscriminately set 'windows_or_buffers_changed' when recomputing the frame title? Why should we try to redirect frame focus which is already sufficiently hairy by itself so hardly anyone really understands what it does. Why should formatting the frame title try to resize a mini window or move minibuffers onto the selected frame? Why set last_nonminibuf_frame which might affect 'display-buffer' and apparently relies on some internal kludgery to set it precisely to the same value it had before title line formatting started. And why reset internal_last_event_frame which also appears complicated enough to not touch it unless you know precisely why and when. Similar things happen with mode lines display - unwind_format_mode_line apparently can call Fselect_window up to three times in a row with the implications sketched above. When trying to fix Bug#32777 I spent some time investigating these issues but never found out why on earth we should call routines like 'select-frame' and 'select-window' from redisplay. If there is any rationale for these, it should be explained in comments first before moving on to explain why moving minibuffers between frames can go awry. martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-20 8:23 ` martin rudalics @ 2022-05-20 10:58 ` Eli Zaretskii 2022-05-21 8:32 ` martin rudalics 2022-05-20 11:33 ` Alan Mackenzie 1 sibling, 1 reply; 29+ messages in thread From: Eli Zaretskii @ 2022-05-20 10:58 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, acm, tanzer > Date: Fri, 20 May 2022 10:23:17 +0200 > Cc: 55412@debbugs.gnu.org, tanzer@swing.co.at > From: martin rudalics <rudalics@gmx.at> > > > It would be good to have some of these explanations in comments there. > > I understand that we want a quick solution for the present bug so it can > be included in Emacs 28.2. But I still don't understand why nobody even > cared to try the patch I sent earlier. I don't think I understand what patch that is, but we could install different solutions on master and the release branches. In general, I prefer the old code to a new one, because the old code by definition keeps old behavior, and thus runs lower risks of breaking something. But I won't object installing what is deemed a better solution on master, even though it is riskier. > With the current code, whenever there are at least two frames > present, 'gui_consider_frame_title' calls via Fselect_window among > others > > redisplay_other_windows > > Fredirect_frame_focus > > resize_mini_window > > move_minibuffers_onto_frame > > and sets > > last_nonminibuf_frame > > internal_last_event_frame > > Has anyone ever tried to understand the implications of all these? Why would we need to do that? This code was there for many years, so its effects are by now a de-facto standard behavior of Emacs. We don't have human power and resources to revisit those decisions unless someone submits a bug report, or unless some deep refactoring or reimplementation of the code is taking place. > When trying to fix Bug#32777 I spent some time investigating these > issues but never found out why on earth we should call routines like > 'select-frame' and 'select-window' from redisplay. Well, now we know at least one reason: so that referencing frame-parameters would what Lisp programs expect. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-20 10:58 ` Eli Zaretskii @ 2022-05-21 8:32 ` martin rudalics 2022-05-21 8:35 ` Eli Zaretskii 0 siblings, 1 reply; 29+ messages in thread From: martin rudalics @ 2022-05-21 8:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 55412, acm, tanzer >> When trying to fix Bug#32777 I spent some time investigating these >> issues but never found out why on earth we should call routines like >> 'select-frame' and 'select-window' from redisplay. > > Well, now we know at least one reason: so that referencing > frame-parameters would what Lisp programs expect. I don't understand what you mean here. Please elaborate. martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-21 8:32 ` martin rudalics @ 2022-05-21 8:35 ` Eli Zaretskii 0 siblings, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-21 8:35 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, acm, tanzer > Date: Sat, 21 May 2022 10:32:41 +0200 > Cc: acm@muc.de, 55412@debbugs.gnu.org, tanzer@swing.co.at > From: martin rudalics <rudalics@gmx.at> > > >> When trying to fix Bug#32777 I spent some time investigating these > >> issues but never found out why on earth we should call routines like > >> 'select-frame' and 'select-window' from redisplay. > > > > Well, now we know at least one reason: so that referencing > > frame-parameters would what Lisp programs expect. > > I don't understand what you mean here. Please elaborate. See the OP's report: a :eval form in frame-title-format that references a frame-parameter assumes that the frame whose title is being evaluated is the selected-frame when the :eval form runs. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-20 8:23 ` martin rudalics 2022-05-20 10:58 ` Eli Zaretskii @ 2022-05-20 11:33 ` Alan Mackenzie 2022-05-20 12:10 ` Eli Zaretskii 2022-05-21 8:32 ` martin rudalics 1 sibling, 2 replies; 29+ messages in thread From: Alan Mackenzie @ 2022-05-20 11:33 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, tanzer, Eli Zaretskii Hello, Martin. On Fri, May 20, 2022 at 10:23:17 +0200, martin rudalics wrote: > > It would be good to have some of these explanations in comments there. > I understand that we want a quick solution for the present bug so it can > be included in Emacs 28.2. But I still don't understand why nobody even > cared to try the patch I sent earlier. My apologies for not being aware of it. Your post from last Sunday with the patch was before I was in the thread, and I missed, in your references to the patch, that it was a recent post in this thread. I've just spent about an hour perusing the patch, and have the following observations and questions. The patch is too large to go into the emacs-28 branch, so for a "quick safe fix", we'd still need the smaller patch I posted a small number of days ago, or something like it. with_window_selected is not re-entrant, since it uses a static data structure. Is this deliberate, or just a case of not yet making it re-entrant? I get nervous when I see "selected_frame = ...;" or "selected_window = ....;" outside of do_switch_frame or the corresponding window function, since it means selected_{frame,window} have been set without regard to all the other things which must be kept in synch with them. At the moment, all these "wild" settings of selected_frame are in xdisp.c, which I suppose has special reasons for them. with_window_selected would add another "wild" setting of selected_frame, this one outside of xdisp.c (in window.c) and I ask whether or not this is a good thing. I think the root of the problem your patch is trying to solve is that the same C code is used for implementing C-x 5 o and lower level, temporary, frame switches. If this is the case, a good way of proceeding would be to refactor do_switch_frame into a function appropriate for lower level C calls, and the remainder for C-x 5 o. For example, the call to move_minibuffers_onto_frame is clearly needed for C-x 5 o, but is a complicated nuisance for lower level C. With such a new extracted C function, we could replace the "selected_frame = ...;" in xdisp.c by calls to this function. Maybe. > With the current code, whenever there are at least two frames present, > 'gui_consider_frame_title' calls via Fselect_window among others > redisplay_other_windows > Fredirect_frame_focus > resize_mini_window > move_minibuffers_onto_frame > and sets > last_nonminibuf_frame > internal_last_event_frame Yes. It also clears f->select_mini_window_flag, which I posted a separate thread on emacs-devel about. Here I think the problem is the same as above: Fselect_window is a high level function for doing things like C-x o, but we really need a low level function with which we could do a controlled temporary switch to a different window, without the unwanted complications of move_minibuffers_onto_frame etc.. > Has anyone ever tried to understand the implications of all these? Why > should redisplay indiscriminately set 'windows_or_buffers_changed' when > recomputing the frame title? Why should we try to redirect frame focus > which is already sufficiently hairy by itself so hardly anyone really > understands what it does. Why should formatting the frame title try to > resize a mini window or move minibuffers onto the selected frame? I think my analysis above might point a way out of these problems. > Why set last_nonminibuf_frame which might affect 'display-buffer' and > apparently relies on some internal kludgery to set it precisely to the > same value it had before title line formatting started. And why reset > internal_last_event_frame which also appears complicated enough to not > touch it unless you know precisely why and when. > Similar things happen with mode lines display - unwind_format_mode_line > apparently can call Fselect_window up to three times in a row with the > implications sketched above. > When trying to fix Bug#32777 I spent some time investigating these > issues but never found out why on earth we should call routines like > 'select-frame' and 'select-window' from redisplay. If there is any > rationale for these, it should be explained in comments first before > moving on to explain why moving minibuffers between frames can go awry. I don't think redisplay should be calling Fselect_window or do_switch_frame at all. Instead we should call (not yet existing) lower level functions. > martin -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-20 11:33 ` Alan Mackenzie @ 2022-05-20 12:10 ` Eli Zaretskii 2022-05-21 8:32 ` martin rudalics 1 sibling, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-20 12:10 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, rudalics, tanzer > Date: Fri, 20 May 2022 11:33:45 +0000 > Cc: Eli Zaretskii <eliz@gnu.org>, 55412@debbugs.gnu.org, tanzer@swing.co.at > From: Alan Mackenzie <acm@muc.de> > > I don't think redisplay should be calling Fselect_window or > do_switch_frame at all. Instead we should call (not yet existing) lower > level functions. Assuming those hypothetical lower-level functions will do enough of Fselect_window to keep the semantics, I don't object. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-20 11:33 ` Alan Mackenzie 2022-05-20 12:10 ` Eli Zaretskii @ 2022-05-21 8:32 ` martin rudalics 2022-05-21 8:59 ` Eli Zaretskii 1 sibling, 1 reply; 29+ messages in thread From: martin rudalics @ 2022-05-21 8:32 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, tanzer, Eli Zaretskii > with_window_selected is not re-entrant, since it uses a static data > structure. Is this deliberate, or just a case of not yet making it > re-entrant? You mean Vwith_window_selected_vector. It's deliberate, just transferred here from 'format_mode_line_unwind_data' which did the same. Apparently the overhead for allocating a new vector during redisplay was deemed as too expensive for making this re-entrant. > I get nervous when I see "selected_frame = ...;" or "selected_window = > ....;" outside of do_switch_frame or the corresponding window function, > since it means selected_{frame,window} have been set without regard to > all the other things which must be kept in synch with them. At the > moment, all these "wild" settings of selected_frame are in xdisp.c, > which I suppose has special reasons for them. What concerns me is that xdisp.c sets selected_window and selected_frame in the first place (also due to my attempts to fix Bug#39977). My patch removes them all. This part of the redisplay code has been mended over and over again in the past years, adding all those "special reasons" you mention. > with_window_selected would add another "wild" setting of selected_frame, > this one outside of xdisp.c (in window.c) and I ask whether or not this > is a good thing. The canonical function to set selected_window is the static select_window_1 and that's in window.c (with_window_selected sets selected_window too but that's only a minor optimization). > I think the root of the problem your patch is trying to solve is that > the same C code is used for implementing C-x 5 o and lower level, > temporary, frame switches. If this is the case, a good way of > proceeding would be to refactor do_switch_frame into a function > appropriate for lower level C calls, and the remainder for C-x 5 o. For > example, the call to move_minibuffers_onto_frame is clearly needed for > C-x 5 o, but is a complicated nuisance for lower level C. With such a > new extracted C function, we could replace the "selected_frame = ...;" > in xdisp.c by calls to this function. Maybe. The redisplay code has to temporarily select a window also when there's only one frame around in which case do_switch_frame wouldn't enter the picture at all. with_window_selected handles both cases. > I don't think redisplay should be calling Fselect_window or > do_switch_frame at all. Instead we should call (not yet existing) lower > level functions. That's what with_window_selected and its unwind form have been designed for. Basically, any such code has to guarantee invariants like: - The selected frame's selected window is the selected window. - Code run within with_window_selected can rely on the fact that the selected window's buffer is current. Moreover, the code has to guarantee that selecting a window correctly sets up point from the window's point and stores the old point in the previously selected window#s point. And it obviously has to guarantee that the involved buffers, windows and frames are alive when switching to and back from them - things redisplay had always problems with (confer Bug#47244). Not reliably doing all these things in one place easily produces bugs that show up only in sessions that run for a long time and are consequently very difficult to debug. One major advantage of with_window_selected is that then one can debug functions like 'select-window', 'select-frame' or 'redirect-frame-focus' without being continuously hassled by redisplay which here accounts for nine out of ten calls of these functions at least and eventually caused me to abandon a number of fixes for say Bug#32777, Bug#39977, Bug#24500 and Bug#24803. martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-21 8:32 ` martin rudalics @ 2022-05-21 8:59 ` Eli Zaretskii 0 siblings, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-21 8:59 UTC (permalink / raw) To: martin rudalics; +Cc: 55412, acm, tanzer > Date: Sat, 21 May 2022 10:32:51 +0200 > Cc: Eli Zaretskii <eliz@gnu.org>, 55412@debbugs.gnu.org, tanzer@swing.co.at > From: martin rudalics <rudalics@gmx.at> > > > I get nervous when I see "selected_frame = ...;" or "selected_window = > > ....;" outside of do_switch_frame or the corresponding window function, > > since it means selected_{frame,window} have been set without regard to > > all the other things which must be kept in synch with them. At the > > moment, all these "wild" settings of selected_frame are in xdisp.c, > > which I suppose has special reasons for them. > > What concerns me is that xdisp.c sets selected_window and selected_frame > in the first place (also due to my attempts to fix Bug#39977). My patch > removes them all. Frankly, I don't understand why would we want that. AFAICT, that patch just moves those assignments to a single place, and what does that gain us, as counter-weight to potential breakage due to subtly different stuff the original code was doing? The new code also makes the temporary change in the selected window more heavy and expensive, which is not a good idea inside redisplay. Note that redisplay also changes the current buffer, and it does that independently of selecting a window. I'm not sure window.c is ready (or was designed) for such subtleties. > Moreover, the code has to guarantee that selecting a window correctly > sets up point from the window's point and stores the old point in the > previously selected window#s point. And it obviously has to guarantee > that the involved buffers, windows and frames are alive when switching > to and back from them - things redisplay had always problems with > (confer Bug#47244). Not reliably doing all these things in one place > easily produces bugs that show up only in sessions that run for a long > time and are consequently very difficult to debug. The general advantage of doing things in one place is well known, but I'm not sure this particular case lends itself well to such generalizations. IMNSHO, we are once again rocking a boat for no good reason (and no, the problems in bug#47244 do _not_ IMO justify this, because that bug can be fixed in other ways, as mentioned in that and related discussions several times). Bottom line, I'm not happy about this patch, sorry. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-18 15:49 ` Alan Mackenzie 2022-05-18 16:03 ` Eli Zaretskii @ 2022-05-19 7:18 ` martin rudalics 1 sibling, 0 replies; 29+ messages in thread From: martin rudalics @ 2022-05-19 7:18 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 55412, tanzer, Eli Zaretskii > Please try the following patch, which may solve the above problem > without hurting the bug fix. It solves the above problem here. Thanks, martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-14 16:58 ` Eli Zaretskii ` (2 preceding siblings ...) 2022-05-16 20:52 ` Alan Mackenzie @ 2022-05-20 20:39 ` Alan Mackenzie 2022-05-21 11:25 ` tanzer--- via Bug reports for GNU Emacs, the Swiss army knife of text editors 3 siblings, 1 reply; 29+ messages in thread From: Alan Mackenzie @ 2022-05-20 20:39 UTC (permalink / raw) To: Christian Tanzer, Eli Zaretskii; +Cc: 55412, martin rudalics, acm Hello, Christian and Eli. On Sat, May 14, 2022 at 19:58:13 +0300, Eli Zaretskii wrote: > > Date: Sat, 14 May 2022 15:45:10 -0000 > > From: Christian Tanzer <tanzer@swing.co.at> > > ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it > > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one > > ;;; uses a frame-parameter in ':eval'. [ .... ] > Thank you for your report. > Alan, this is due to one of the changes introduced for the > minibuffer-follows-selected-frame feature. Specifically, commit > 7c2ebf6 made a change in gui_consider_frame_title which causes this > regression. If I revert a part of that commit shown below: [ .... ] I have now committed the patch from Wednesday (slightly amended) to the emacs-28 branch at savannah. This should have fixed the bug. Christian, if downloading the latest version from the savannah server is inconvenient, please let me know, and I will send you the patch by email so that you can patch your own version of Emacs 28. [ .... ] > Thanks. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-20 20:39 ` Alan Mackenzie @ 2022-05-21 11:25 ` tanzer--- via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-05-21 12:35 ` Eli Zaretskii 2022-05-22 17:34 ` Alan Mackenzie 0 siblings, 2 replies; 29+ messages in thread From: tanzer--- via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-05-21 11:25 UTC (permalink / raw) To: Alan Mackenzie, Eli Zaretskii; +Cc: 55412, martin rudalics Hello Alan and Eli, Alan Mackenzie wrote at Fri, 20 May 2022 20:39:06 +0000: > On Sat, May 14, 2022 at 19:58:13 +0300, Eli Zaretskii wrote: > > > Date: Sat, 14 May 2022 15:45:10 -0000 > > > From: Christian Tanzer <tanzer@swing.co.at> > > > > ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it > > > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one > > > ;;; uses a frame-parameter in ':eval'. > > [ .... ] > > > Thank you for your report. > > > Alan, this is due to one of the changes introduced for the > > minibuffer-follows-selected-frame feature. Specifically, commit > > 7c2ebf6 made a change in gui_consider_frame_title which causes this > > regression. If I revert a part of that commit shown below: > > [ .... ] > > I have now committed the patch from Wednesday (slightly amended) to the > emacs-28 branch at savannah. This should have fixed the bug. Thank you. I was very impressed how fast you guys moved! > Christian, if downloading the latest version from the savannah server is > inconvenient, please let me know, and I will send you the patch by email > so that you can patch your own version of Emacs 28. Unfortunately, I'll have to wait for 28.2. But thanks for the offer nevertheless. I needed to move back to Emacs 27.2 because there are some other bugs in 28.1 that I have no idea how to properly report: - Emacs 28.1 most often crashes after loading a .emacs.desktop. It doesn't crash without a .emacs.desktop or with a simple one, but at the moment I cannot start 28.1 on any of my usual .emacs.desktop files without a crash. I suspect only a reboot will solve that. After the last reboot, I could start 28.1 once with a complex .emacs.desktop, for a second (simultaneous) Emacs instance with a different .emacs.desktop I had to use Emacs 27.2. Would it help to supply one of the crash dumps that macOS displayed and how would I submit such a bug report? - The second bug concerns .emacs.desktop.lock files. For some reason, 28.1 doesn't remove the lock file when exiting. Obviously, this isn't reproducible with `emacs -Q`. Again, how would I submit such a bug report? Thanks again and have a nice weekend, Christian PS: ATM, I'm not set up to compile Emacs myself as I temporarily moved into a very small house and don't have any Linux machine here. I'm not masochistic enough to setup up a compilation environment on the little Macbook I have (which is severly lacking on disc space). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-21 11:25 ` tanzer--- via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-05-21 12:35 ` Eli Zaretskii 2022-05-22 17:34 ` Alan Mackenzie 1 sibling, 0 replies; 29+ messages in thread From: Eli Zaretskii @ 2022-05-21 12:35 UTC (permalink / raw) To: tanzer; +Cc: 55412, acm, rudalics > Date: Sat, 21 May 2022 11:25:22 -0000 > From: tanzer@gg32.com > Cc: martin rudalics <rudalics@gmx.at>, 55412@debbugs.gnu.org > > I needed to move back to Emacs 27.2 because there are some other bugs > in 28.1 that I have no idea how to properly report: > > - Emacs 28.1 most often crashes after loading a .emacs.desktop. > > It doesn't crash without a .emacs.desktop or with a simple one, but > at the moment I cannot start 28.1 on any of my usual .emacs.desktop > files without a crash. I suspect only a reboot will solve that. > > After the last reboot, I could start 28.1 once with a complex > .emacs.desktop, for a second (simultaneous) Emacs instance with a > different .emacs.desktop I had to use Emacs 27.2. > > Would it help to supply one of the crash dumps that macOS displayed > and how would I submit such a bug report? > > - The second bug concerns .emacs.desktop.lock files. For some reason, > 28.1 doesn't remove the lock file when exiting. > > Obviously, this isn't reproducible with `emacs -Q`. Again, how would > I submit such a bug report? Yes, please submit bug reports for those issues with as much relevant support data as you can, including any relevant customizations. E.g., for desktop.el-related issues, please post the .emacs.desktop file that causes those issues. Thanks. FTR, Emacs 28 never crashed on me due to anything related to desktop.el, which I use all the time. I also never saw any problems with removing .emacs.desktop.lock with v28.1. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-21 11:25 ` tanzer--- via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-05-21 12:35 ` Eli Zaretskii @ 2022-05-22 17:34 ` Alan Mackenzie 1 sibling, 0 replies; 29+ messages in thread From: Alan Mackenzie @ 2022-05-22 17:34 UTC (permalink / raw) To: tanzer; +Cc: 55412-done, martin rudalics, Eli Zaretskii, acm Hello, Christian. On Sat, May 21, 2022 at 11:25:22 -0000, tanzer@gg32.com wrote: > Hello Alan and Eli, > Alan Mackenzie wrote at Fri, 20 May 2022 20:39:06 +0000: > > On Sat, May 14, 2022 at 19:58:13 +0300, Eli Zaretskii wrote: > > I have now committed the patch from Wednesday (slightly amended) to the > > emacs-28 branch at savannah. This should have fixed the bug. > Thank you. I was very impressed how fast you guys moved! OK, thanks! I'm now closing the bug with this post. > I needed to move back to Emacs 27.2 because there are some other bugs > in 28.1 that I have no idea how to properly report: [ .... ] I'm sorry about these, and hope we manage to get them fixed, too! > Thanks again and have a nice weekend, You too! > Christian > PS: ATM, I'm not set up to compile Emacs myself as I temporarily moved > into a very small house and don't have any Linux machine here. I'm > not masochistic enough to setup up a compilation environment on > the little Macbook I have (which is severly lacking on disc space). OK. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly 2022-05-14 15:45 bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly Christian Tanzer 2022-05-14 16:58 ` Eli Zaretskii @ 2022-05-15 9:28 ` martin rudalics 1 sibling, 0 replies; 29+ messages in thread From: martin rudalics @ 2022-05-15 9:28 UTC (permalink / raw) To: tanzer, 55412 [-- Attachment #1: Type: text/plain, Size: 1730 bytes --] > ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one > ;;; uses a frame-parameter in ':eval'. > ;;; > ;;; The following elisp snippet demonstrates the problem in an Emacs 28.1 > ;;; instance started with 'emacs -Q' > > (defun title-suffix () > (cdr (assoc 'title-suffix (frame-parameters (selected-frame))))) > > (defvar title-prefix "Test") > (setq frame-title-format (list title-prefix '(:eval (title-suffix)) " %b")) > > ;;; The original frame should show a frame title of 'Test *scratch*' > (set-frame-parameter (selected-frame) 'title-suffix "") > > ;;; The next frame created should show a frame title of 'Test-xxx *scratch*' > (make-frame-command) > (set-frame-parameter (selected-frame) 'title-suffix "-xxx") > > ;;; The third frame created should show a frame title of 'Test-yyy *scratch*' > (make-frame-command) > (set-frame-parameter (selected-frame) 'title-suffix "-yyy") > > ;;; In Emacs 27 and earlier, that is exactly what happens. Selecting a > ;;; different frame doesn't change the titles of all other frames. > > ;;; In Emacs 28.1, all frames show the same frame title, with the last one > ;;; selected determining which one is shown for the bunch of them. Changing to > ;;; a different frame changes the titles of all frames to the title of the > ;;; newly selected one. Could you try the attached patch? Its purpose is to solve a more general problem in this area and I had to scrape it out from my sources so there are most likely dragons around. But AFAICT it does not exhibit the problem you see, tested with a GNUstep build on old stable Debian. Thanks, martin [-- Attachment #2: with-window-selected.diff --] [-- Type: text/x-patch, Size: 20132 bytes --] diff --git a/src/window.c b/src/window.c index a87b4834aa..7f616bc5ac 100644 --- a/src/window.c +++ b/src/window.c @@ -607,6 +607,121 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap) set_point_from_marker (XWINDOW (window)->pointm); } + +/** Temporarily select a window with minimum overhead. */ + +static Lisp_Object Vwith_window_selected_vector; + +static Lisp_Object +with_window_selected_unwind_data (Lisp_Object window) +{ + Lisp_Object vector, buffer; + struct frame *f = WINDOW_XFRAME (XWINDOW (window)); + + vector = Vwith_window_selected_vector; + Vwith_window_selected_vector = Qnil; + + if (NILP (vector)) + vector = make_nil_vector (4); + + /* Current buffer. To be restored if still alive. */ + XSETBUFFER (buffer, current_buffer); + ASET (vector, 0, buffer); + /* Selected window. To be restored if still alive. */ + ASET (vector, 1, selected_window); + /* Selected window of WINDOW's frame. To be restored if still + alive. */ + ASET (vector, 2, f->selected_window); + /* For a TTY frame save its top-frame. To be restored if still + alive. */ + if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) + ASET (vector, 3, FRAME_TTY (f)->top_frame); + else + ASET (vector, 3, Qnil); + + return vector; +} + + +static void +unwind_with_window_selected (Lisp_Object vector) +{ + Lisp_Object buffer = AREF (vector, 0); + Lisp_Object window = AREF (vector, 1); + Lisp_Object frame_selected_window = AREF (vector, 2); + Lisp_Object top_frame = AREF (vector, 3); + + /* Restore things iff the window is still alive. */ + if (WINDOW_LIVE_P (window)) + { + struct window *w = XWINDOW (window); + Lisp_Object frame = WINDOW_FRAME (w); + struct frame *f = XFRAME (frame); + + /* Restore the frame's selected window if it's still alive. */ + if (WINDOW_LIVE_P (frame_selected_window)) + WINDOW_XFRAME (XWINDOW (frame_selected_window))->selected_window + = frame_selected_window; + + /* Make w->contents current before calling select_window_1 because + the latter sets PT from w->pointm. */ + set_buffer_internal_1 (XBUFFER (w->contents)); + select_window_1 (window, false); + + if (FRAMEP (top_frame) && FRAME_LIVE_P (XFRAME (top_frame))) + selected_frame = top_frame; + else + selected_frame = frame; + + f->selected_window = window; + } + + /* Restore current buffer if it's still alive. */ + if (BUFFER_LIVE_P (XBUFFER (buffer))) + set_buffer_internal_1 (XBUFFER (buffer)); + + Vwith_window_selected_vector = vector; +} + + +/** Canonical form to run something with WINDOW temporarily selected. + Note: This does not pop the unwind-protect stack and subsequently + call unwind_with_window_selected. Callers have to provide the + corresponding unbind_to form themselves. **/ +void +with_window_selected (Lisp_Object window) +{ + if (!EQ (window, selected_window) + || current_buffer != XBUFFER (XWINDOW (selected_window)->contents)) + { + struct window *w = XWINDOW (window); + Lisp_Object frame = WINDOW_FRAME (w); + struct frame *f = XFRAME (frame); + struct window *ow = XWINDOW (selected_window); + + record_unwind_protect (unwind_with_window_selected, + with_window_selected_unwind_data (window)); + + set_buffer_internal_1 (XBUFFER (w->contents)); + + if (BUFFERP (ow->contents)) + set_marker_both (ow->pointm, ow->contents, + BUF_PT (XBUFFER (ow->contents)), + BUF_PT_BYTE (XBUFFER (ow->contents))); + + selected_window = window; + + if (!NILP (XWINDOW (window)->pointm)) + set_point_from_marker (XWINDOW (window)->pointm); + + selected_frame = frame; + f->selected_window = window; + if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) + FRAME_TTY (f)->top_frame = frame; + } +} + + DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, doc: /* Select WINDOW which must be a live window. Also make WINDOW's frame the selected frame and WINDOW that frame's @@ -8151,6 +8266,9 @@ init_window_once (void) minibuf_selected_window = Qnil; staticpro (&minibuf_selected_window); + Vwith_window_selected_vector = Qnil; + staticpro (&Vwith_window_selected_vector); + pdumper_do_now_and_after_late_load (init_window_once_for_pdumper); } diff --git a/src/window.h b/src/window.h index 7f7de58846..67f4bbd9e0 100644 --- a/src/window.h +++ b/src/window.h @@ -1192,6 +1192,7 @@ #define CHECK_LIVE_WINDOW(WINDOW) \ extern void temp_output_buffer_show (Lisp_Object); extern void replace_buffer_in_windows (Lisp_Object); extern void replace_buffer_in_windows_safely (Lisp_Object); +extern void with_window_selected (Lisp_Object); /* This looks like a setter, but it is a bit special. */ extern void wset_buffer (struct window *, Lisp_Object); extern bool window_outdated (struct window *); diff --git a/src/xdisp.c b/src/xdisp.c index 5ff54b2884..840437f76a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12967,20 +12967,17 @@ #define MODE_LINE_NOPROP_LEN(start) \ static Lisp_Object Vmode_line_unwind_vector; static Lisp_Object -format_mode_line_unwind_data (struct frame *target_frame, - struct buffer *obuf, - Lisp_Object owin, - bool save_proptrans) +format_mode_line_unwind_data (bool save_proptrans) { - Lisp_Object vector, tmp; + Lisp_Object vector; /* Reduce consing by keeping one vector in - Vwith_echo_area_save_vector. */ + Vmode_line_unwind_vector. */ vector = Vmode_line_unwind_vector; Vmode_line_unwind_vector = Qnil; if (NILP (vector)) - vector = make_nil_vector (12); + vector = make_nil_vector (6); ASET (vector, 0, make_fixnum (mode_line_target)); ASET (vector, 1, make_fixnum (MODE_LINE_NOPROP_LEN (0))); @@ -12989,44 +12986,12 @@ format_mode_line_unwind_data (struct frame *target_frame, ASET (vector, 4, mode_line_string_face); ASET (vector, 5, mode_line_string_face_prop); - if (obuf) - XSETBUFFER (tmp, obuf); - else - tmp = Qnil; - ASET (vector, 6, tmp); - ASET (vector, 7, owin); - if (target_frame) - { - Lisp_Object buffer = XWINDOW (target_frame->selected_window)->contents; - struct buffer *b = XBUFFER (buffer); - struct buffer *cb = current_buffer; - - /* Similarly to `with-selected-window', if the operation selects - a window on another frame, we must restore that frame's - selected window, and (for a tty) the top-frame. */ - ASET (vector, 8, target_frame->selected_window); - if (FRAME_TERMCAP_P (target_frame)) - ASET (vector, 9, FRAME_TTY (target_frame)->top_frame); - - /* If we select a window on another frame, make sure that that - selection does not leave its buffer's point modified when - unwinding (Bug#32777). */ - ASET (vector, 10, buffer); - current_buffer = b; - ASET (vector, 11, build_marker (current_buffer, PT, PT_BYTE)); - current_buffer = cb; - } - return vector; } static void unwind_format_mode_line (Lisp_Object vector) { - Lisp_Object old_window = AREF (vector, 7); - Lisp_Object target_frame_window = AREF (vector, 8); - Lisp_Object old_top_frame = AREF (vector, 9); - mode_line_target = XFIXNUM (AREF (vector, 0)); mode_line_noprop_ptr = mode_line_noprop_buf + XFIXNUM (AREF (vector, 1)); mode_line_string_list = AREF (vector, 2); @@ -13035,55 +13000,9 @@ unwind_format_mode_line (Lisp_Object vector) mode_line_string_face = AREF (vector, 4); mode_line_string_face_prop = AREF (vector, 5); - /* Select window before buffer, since it may change the buffer. */ - if (WINDOW_LIVE_P (old_window)) - { - /* If the operation that we are unwinding had selected a window - on a different frame, reset its frame-selected-window. For a - text terminal, reset its top-frame if necessary. */ - if (WINDOW_LIVE_P (target_frame_window)) - { - Lisp_Object frame - = WINDOW_FRAME (XWINDOW (target_frame_window)); - - if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window)))) - Fselect_window (target_frame_window, Qt); - - if (!NILP (old_top_frame) && !EQ (old_top_frame, frame)) - Fselect_frame (old_top_frame, Qt); - } - - Fselect_window (old_window, Qt); - - /* Restore point of target_frame_window's buffer (Bug#32777). - But do this only after old_window has been reselected to - avoid that the window point of target_frame_window moves. */ - if (WINDOW_LIVE_P (target_frame_window)) - { - Lisp_Object buffer = AREF (vector, 10); - - if (BUFFER_LIVE_P (XBUFFER (buffer))) - { - struct buffer *cb = current_buffer; - - current_buffer = XBUFFER (buffer); - set_point_from_marker (AREF (vector, 11)); - ASET (vector, 11, Qnil); - current_buffer = cb; - } - } - } - - if (!NILP (AREF (vector, 6))) - { - set_buffer_internal_1 (XBUFFER (AREF (vector, 6))); - ASET (vector, 6, Qnil); - } - Vmode_line_unwind_vector = vector; } - /* Store a single character C for the frame title in mode_line_noprop_buf. Re-allocate mode_line_noprop_buf if necessary. */ @@ -13195,15 +13114,11 @@ gui_consider_frame_title (Lisp_Object frame) Bug#34317. */ specbind (Qinhibit_redisplay, Qt); - /* Switch to the buffer of selected window of the frame. Set up - mode_line_target so that display_mode_element will output into - mode_line_noprop_buf; then display the title. */ + with_window_selected (f->selected_window); + record_unwind_protect (unwind_format_mode_line, - format_mode_line_unwind_data - (NULL, current_buffer, Qnil, false)); + format_mode_line_unwind_data (false)); - set_buffer_internal_1 - (XBUFFER (XWINDOW (f->selected_window)->contents)); fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; mode_line_target = MODE_LINE_TITLE; @@ -13497,69 +13412,6 @@ update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run) Tab-bars ***********************************************************************/ -/* Restore WINDOW as the selected window and its frame as the selected - frame. If WINDOW is dead but the selected frame is live, make the - latter's selected window the selected window. If both, WINDOW and - the selected frame, are dead, assign selected frame and window from - some arbitrary live frame. Abort if no such frame can be found. */ -static void -restore_selected_window (Lisp_Object window) -{ - if (WINDOW_LIVE_P (window)) - /* If WINDOW is live, make it the selected window and its frame's - selected window and set the selected frame to its frame. */ - { - selected_window = window; - selected_frame = XWINDOW (window)->frame; - FRAME_SELECTED_WINDOW (XFRAME (selected_frame)) = window; - } - else if (FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame))) - /* If WINDOW is dead but the selected frame is still live, make the - latter's selected window the selected one. */ - selected_window = FRAME_SELECTED_WINDOW (XFRAME (selected_frame)); - else - /* If WINDOW and the selected frame are dead, choose some live, - non-child and non-tooltip frame as the new selected frame and - make its selected window the selected window. */ - { - Lisp_Object tail; - Lisp_Object frame UNINIT; - - FOR_EACH_FRAME (tail, frame) - { - struct frame *f = XFRAME (frame); - - if (!FRAME_PARENT_FRAME (f) && !FRAME_TOOLTIP_P (f)) - { - selected_frame = frame; - selected_window = FRAME_SELECTED_WINDOW (f); - - return; - } - } - - /* Abort if we cannot find a live frame. */ - emacs_abort (); - } -} - -/* Restore WINDOW, if live, as its frame's selected window. */ -static void -restore_frame_selected_window (Lisp_Object window) -{ - if (WINDOW_LIVE_P (window)) - /* If WINDOW is live, make it its frame's selected window. If that - frame is the selected frame, make WINDOW the selected window as - well. */ - { - Lisp_Object frame = XWINDOW (window)->frame; - - FRAME_SELECTED_WINDOW (XFRAME (frame)) = window; - if (EQ (frame, selected_frame)) - selected_window = window; - } -} - /* Update the tab-bar item list for frame F. This has to be done before we start to fill in any display lines. Called from prepare_menu_bars. If SAVE_MATCH_DATA, we must save @@ -13582,11 +13434,8 @@ update_tab_bar (struct frame *f, bool save_match_data) if (do_update) { - Lisp_Object window; - struct window *w; - - window = FRAME_SELECTED_WINDOW (f); - w = XWINDOW (window); + Lisp_Object window = FRAME_SELECTED_WINDOW (f); + struct window *w = XWINDOW (window); /* If the user has switched buffers or windows, we need to recompute to reflect the new bindings. But we'll @@ -13600,16 +13449,10 @@ update_tab_bar (struct frame *f, bool save_match_data) || update_mode_lines || window_buffer_changed (w)) { - struct buffer *prev = current_buffer; specpdl_ref count = SPECPDL_INDEX (); Lisp_Object new_tab_bar; int new_n_tab_bar; - /* Set current_buffer to the buffer of the selected - window of the frame, so that we get the right local - keymaps. */ - set_buffer_internal_1 (XBUFFER (w->contents)); - /* Save match data, if we must. */ if (save_match_data) record_unwind_save_match_data (); @@ -13621,20 +13464,8 @@ update_tab_bar (struct frame *f, bool save_match_data) specbind (Qoverriding_local_map, Qnil); } - /* We must temporarily set the selected frame to this frame - before calling tab_bar_items, because the calculation of - the tab-bar keymap uses the selected frame (see - `tab-bar-make-keymap' in tab-bar.el). */ - eassert (EQ (selected_window, - /* Since we only explicitly preserve selected_frame, - check that selected_window would be redundant. */ - XFRAME (selected_frame)->selected_window)); #ifdef HAVE_WINDOW_SYSTEM - Lisp_Object frame; - record_unwind_protect (restore_selected_window, selected_window); - XSETFRAME (frame, f); - selected_frame = frame; - selected_window = FRAME_SELECTED_WINDOW (f); + with_window_selected (window); #endif /* Build desired tab-bar items from keymaps. */ @@ -13657,7 +13488,6 @@ update_tab_bar (struct frame *f, bool save_match_data) } unbind_to (count, Qnil); - set_buffer_internal_1 (prev); } } } @@ -14495,11 +14325,8 @@ update_tool_bar (struct frame *f, bool save_match_data) if (do_update) { - Lisp_Object window; - struct window *w; - - window = FRAME_SELECTED_WINDOW (f); - w = XWINDOW (window); + Lisp_Object window = FRAME_SELECTED_WINDOW (f); + struct window *w = XWINDOW (window); /* If the user has switched buffers or windows, we need to recompute to reflect the new bindings. But we'll @@ -14513,16 +14340,10 @@ update_tool_bar (struct frame *f, bool save_match_data) || update_mode_lines || window_buffer_changed (w)) { - struct buffer *prev = current_buffer; specpdl_ref count = SPECPDL_INDEX (); - Lisp_Object frame, new_tool_bar; + Lisp_Object new_tool_bar; int new_n_tool_bar; - /* Set current_buffer to the buffer of the selected - window of the frame, so that we get the right local - keymaps. */ - set_buffer_internal_1 (XBUFFER (w->contents)); - /* Save match data, if we must. */ if (save_match_data) record_unwind_save_match_data (); @@ -14534,18 +14355,7 @@ update_tool_bar (struct frame *f, bool save_match_data) specbind (Qoverriding_local_map, Qnil); } - /* We must temporarily set the selected frame to this frame - before calling tool_bar_items, because the calculation of - the tool-bar keymap uses the selected frame (see - `tool-bar-make-keymap' in tool-bar.el). */ - eassert (EQ (selected_window, - /* Since we only explicitly preserve selected_frame, - check that selected_window would be redundant. */ - XFRAME (selected_frame)->selected_window)); - record_unwind_protect (restore_selected_window, selected_window); - XSETFRAME (frame, f); - selected_frame = frame; - selected_window = FRAME_SELECTED_WINDOW (f); + with_window_selected (window); /* Build desired tool-bar items from keymaps. */ new_tool_bar @@ -14567,7 +14377,6 @@ update_tool_bar (struct frame *f, bool save_match_data) } unbind_to (count, Qnil); - set_buffer_internal_1 (prev); } } } @@ -26075,15 +25884,8 @@ redisplay_mode_lines (Lisp_Object window, bool force) static int display_mode_lines (struct window *w) { - Lisp_Object old_selected_window = selected_window; - Lisp_Object new_frame = w->frame; - specpdl_ref count = SPECPDL_INDEX (); int n = 0; - record_unwind_protect (restore_selected_window, selected_window); - record_unwind_protect - (restore_frame_selected_window, XFRAME (new_frame)->selected_window); - if (window_wants_mode_line (w)) { Lisp_Object window; @@ -26101,12 +25903,6 @@ display_mode_lines (struct window *w) wset_mode_line_help_echo (w, Qnil); } - selected_frame = new_frame; - /* FIXME: If we were to allow the mode-line's computation changing the buffer - or window's point, then we'd need select_window_1 here as well. */ - XSETWINDOW (selected_window, w); - XFRAME (new_frame)->selected_window = selected_window; - /* These will be set while the mode line specs are processed. */ line_number_displayed = false; w->column_number_displayed = -1; @@ -26115,7 +25911,7 @@ display_mode_lines (struct window *w) { Lisp_Object window_mode_line_format = window_parameter (w, Qmode_line_format); - struct window *sel_w = XWINDOW (old_selected_window); + struct window *sel_w = XWINDOW (selected_window); /* Select mode line face based on the real selected window. */ display_mode_line (w, @@ -26150,8 +25946,6 @@ display_mode_lines (struct window *w) ++n; } - unbind_to (count, Qnil); - if (n > 0) w->must_be_updated_p = true; return n; @@ -26167,6 +25961,7 @@ display_mode_lines (struct window *w) static int display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) { + Lisp_Object window; struct it it; struct face *face; specpdl_ref count = SPECPDL_INDEX (); @@ -26191,9 +25986,11 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) made up of many separate strings. */ it.paragraph_embedding = L2R; + XSETWINDOW (window, w); + with_window_selected (window); + record_unwind_protect (unwind_format_mode_line, - format_mode_line_unwind_data (NULL, NULL, - Qnil, false)); + format_mode_line_unwind_data (false)); /* Temporarily make frame's keyboard the current kboard so that kboard-local variables in the mode_line_format will get the right @@ -26931,7 +26728,6 @@ DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line, struct it it; int len; struct window *w; - struct buffer *old_buffer = NULL; int face_id; bool no_props = FIXNUMP (face); specpdl_ref count = SPECPDL_INDEX (); @@ -26964,17 +26760,15 @@ DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line, : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID : DEFAULT_FACE_ID; - old_buffer = current_buffer; + with_window_selected (window); /* Save things including mode_line_proptrans_alist, and set that to nil so that we don't alter the outer value. */ record_unwind_protect (unwind_format_mode_line, - format_mode_line_unwind_data - (XFRAME (WINDOW_FRAME (w)), - old_buffer, selected_window, true)); + format_mode_line_unwind_data (true)); mode_line_proptrans_alist = Qnil; - Fselect_window (window, Qt); + /* This should be covered by 'unwind_with_window_selected'. */ set_buffer_internal_1 (XBUFFER (buffer)); init_iterator (&it, w, -1, -1, NULL, face_id); ^ permalink raw reply related [flat|nested] 29+ messages in thread
end of thread, other threads:[~2022-05-22 17:34 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-05-14 15:45 bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly Christian Tanzer 2022-05-14 16:58 ` Eli Zaretskii 2022-05-14 17:07 ` Eli Zaretskii 2022-05-15 9:48 ` Alan Mackenzie 2022-05-15 10:16 ` Eli Zaretskii 2022-05-16 20:52 ` Alan Mackenzie 2022-05-17 13:25 ` Eli Zaretskii 2022-05-18 7:19 ` martin rudalics 2022-05-18 11:35 ` Eli Zaretskii 2022-05-18 15:01 ` martin rudalics 2022-05-18 15:12 ` Alan Mackenzie 2022-05-18 15:49 ` Alan Mackenzie 2022-05-18 16:03 ` Eli Zaretskii 2022-05-18 16:38 ` Alan Mackenzie 2022-05-18 16:51 ` Eli Zaretskii 2022-05-20 8:23 ` martin rudalics 2022-05-20 10:58 ` Eli Zaretskii 2022-05-21 8:32 ` martin rudalics 2022-05-21 8:35 ` Eli Zaretskii 2022-05-20 11:33 ` Alan Mackenzie 2022-05-20 12:10 ` Eli Zaretskii 2022-05-21 8:32 ` martin rudalics 2022-05-21 8:59 ` Eli Zaretskii 2022-05-19 7:18 ` martin rudalics 2022-05-20 20:39 ` Alan Mackenzie 2022-05-21 11:25 ` tanzer--- via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-05-21 12:35 ` Eli Zaretskii 2022-05-22 17:34 ` Alan Mackenzie 2022-05-15 9:28 ` martin rudalics
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).