From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: What is restore_window_configuration in read_minibuf (minibuf.c) for? Date: Tue, 20 Apr 2021 13:38:11 +0000 Message-ID: References: <53b9bf3a-bbf2-64e9-f71d-2ac7eb00ae16@gmx.at> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="15327"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: martin rudalics Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Apr 20 15:40:45 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lYqcO-0003nc-Cm for ged-emacs-devel@m.gmane-mx.org; Tue, 20 Apr 2021 15:40:44 +0200 Original-Received: from localhost ([::1]:38766 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lYqcN-0005Os-E6 for ged-emacs-devel@m.gmane-mx.org; Tue, 20 Apr 2021 09:40:43 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39796) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lYqa6-0004ZM-3Y for emacs-devel@gnu.org; Tue, 20 Apr 2021 09:38:23 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:46350 helo=mail.muc.de) by eggs.gnu.org with smtp (Exim 4.90_1) (envelope-from ) id 1lYqa2-0008Ci-5W for emacs-devel@gnu.org; Tue, 20 Apr 2021 09:38:21 -0400 Original-Received: (qmail 66006 invoked by uid 3782); 20 Apr 2021 13:38:12 -0000 Original-Received: from acm.muc.de (p4fe15986.dip0.t-ipconnect.de [79.225.89.134]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Tue, 20 Apr 2021 15:38:12 +0200 Original-Received: (qmail 3071 invoked by uid 1000); 20 Apr 2021 13:38:11 -0000 Content-Disposition: inline In-Reply-To: <53b9bf3a-bbf2-64e9-f71d-2ac7eb00ae16@gmx.at> X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de Received-SPF: pass client-ip=193.149.48.1; envelope-from=acm@muc.de; helo=mail.muc.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:268204 Archived-At: Hello, Martin. On Mon, Apr 19, 2021 at 18:02:48 +0200, martin rudalics wrote: > > So what seems needed is an extra &optional parameter to > > set-window-configuration, DONT-SET-MINIWINDOW which would inhibit the > > restoration of the mini-window. The call from unwinding a minibuffer > > would pass a non-nil value for this argument. Messy, but I haven't got > > any better ideas. > > What do you think? > You could probably also set the minibuffer window(s) separately to > whatever you want after the configuration has been restored. It's messy > in either case. I've gone ahead with my original suggestion. Also, I've added some proper error handling for a "can't happen" case in read_minibuf_unwind, at that place where the loop around frames caused a crash when there were tooltip frames involved. The error occurs if that loop doesn't find the expired minibuffer in any frame. If there are no objections, I intend to commit the following soon, which fixes the bug: diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index c32d711f12..82d2ce4757 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -5877,7 +5877,7 @@ Window Configurations @xref{Window Parameters}. @end defun -@defun set-window-configuration configuration &optional dont-set-frame +@defun set-window-configuration configuration &optional dont-set-frame dont-set-miniwindow This function restores the configuration of windows and buffers as specified by @var{configuration}, for the frame that @var{configuration} was created for, regardless of whether that frame @@ -5885,8 +5885,12 @@ Window Configurations that was previously returned by @code{current-window-configuration} for that frame. Normally the function also selects the frame which is recorded in the configuration, but if @var{dont-set-frame} is -non-@code{nil}, it leaves selected the frame which was current at the -start of the function. +non-@code{nil}, it leaves selected the frame which was already +selected at the start of the function. + +Normally the function restores the saved minibuffer (if any), but if +@var{dont-set-miniwindow} is non-@code{nil}, the minibuffer current +at the start of the function (if any) remains in the mini-window. If the frame from which @var{configuration} was saved is dead, all this function does is to restore the value of the variable diff --git a/etc/NEWS b/etc/NEWS index 3e5767c953..6cf1a98e5d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2660,9 +2660,11 @@ one to another in the init file. The same user option also controls whether the function 'read-answer' accepts short answers. +++ -** 'set-window-configuration' now takes an optional 'dont-set-frame' -parameter which, when non-nil, instructs the function not to select -the frame recorded in the configuration. +** 'set-window-configuration' now takes two optional parameters, +'dont-set-frame' and 'dont-set-miniwindow'. The first of these, when +non-nil, instructs the function not to select the frame recorded in +the configuration. The second prevents the current minibuffer being +replaced by the one stored in the configuration. +++ ** 'define-globalized-minor-mode' now takes a ':predicate' parameter. diff --git a/src/keyboard.c b/src/keyboard.c index 266ebaa5fd..5db45ce8e5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2121,7 +2121,7 @@ read_char_help_form_unwind (void) Lisp_Object window_config = XCAR (help_form_saved_window_configs); help_form_saved_window_configs = XCDR (help_form_saved_window_configs); if (!NILP (window_config)) - Fset_window_configuration (window_config, Qnil); + Fset_window_configuration (window_config, Qnil, Qnil); } #define STOP_POLLING \ diff --git a/src/minibuf.c b/src/minibuf.c index b823224a5f..db62ae0eea 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -660,17 +660,14 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, record_unwind_protect_void (minibuffer_unwind); record_unwind_protect (restore_window_configuration, - Fcons (Qt, Fcurrent_window_configuration (Qnil))); + list3 (Fcurrent_window_configuration (Qnil), Qt, Qt)); /* If the minibuffer window is on a different frame, save that frame's configuration too. */ if (!EQ (mini_frame, selected_frame)) record_unwind_protect (restore_window_configuration, - Fcons (/* Arrange for the frame later to be - switched back to the calling - frame. */ - Qnil, - Fcurrent_window_configuration (mini_frame))); + list3 (Fcurrent_window_configuration (mini_frame), + Qnil, Qt)); /* If the minibuffer is on an iconified or invisible frame, make it visible now. */ @@ -1071,13 +1068,13 @@ read_minibuf_unwind (void) goto found; } } - return; /* expired minibuffer not found. Maybe we should output an - error, here. */ + exp_MB_frame = Qnil; /* "Can't happen." */ found: - if (!EQ (exp_MB_frame, saved_selected_frame)) + if (!EQ (exp_MB_frame, saved_selected_frame) + && !NILP (exp_MB_frame)) do_switch_frame (exp_MB_frame, 0, 0, Qt); /* This also sets - minibuff_window */ + minibuf_window */ /* To keep things predictable, in case it matters, let's be in the minibuffer when we reset the relevant variables. Don't depend on @@ -1187,7 +1184,8 @@ read_minibuf_unwind (void) } /* Restore the selected frame. */ - if (!EQ (exp_MB_frame, saved_selected_frame)) + if (!EQ (exp_MB_frame, saved_selected_frame) + && !NILP (exp_MB_frame)) do_switch_frame (saved_selected_frame, 0, 0, Qt); } @@ -1202,6 +1200,7 @@ minibuffer_unwind (void) Lisp_Object window; Lisp_Object entry; + if (NILP (exp_MB_frame)) return; /* "Can't happen." */ f = XFRAME (exp_MB_frame); window = f->minibuffer_window; w = XWINDOW (window); diff --git a/src/window.c b/src/window.c index a22fab2444..5134c3df63 100644 --- a/src/window.c +++ b/src/window.c @@ -6881,19 +6881,22 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config } DEFUN ("set-window-configuration", Fset_window_configuration, - Sset_window_configuration, 1, 2, 0, + Sset_window_configuration, 1, 3, 0, doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. CONFIGURATION must be a value previously returned by `current-window-configuration' (which see). Normally, this function selects the frame of the CONFIGURATION, but if DONT-SET-FRAME is non-nil, it leaves selected the frame which was -current at the start of the function. +current at the start of the function. If DONT-SET-MINIWINDOW is non-nil, +the mini-window of the frame doesn't get set to the corresponding element +of CONFIGURATION. If CONFIGURATION was made from a frame that is now deleted, only frame-independent values can be restored. In this case, the return value is nil. Otherwise the value is t. */) - (Lisp_Object configuration, Lisp_Object dont_set_frame) + (Lisp_Object configuration, Lisp_Object dont_set_frame, + Lisp_Object dont_set_miniwindow) { register struct save_window_data *data; struct Lisp_Vector *saved_windows; @@ -7104,8 +7107,10 @@ the return value is nil. Otherwise the value is t. */) } } - if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) - /* If saved buffer is alive, install it. */ + if ((NILP (dont_set_miniwindow) || !MINI_WINDOW_P (w)) + && BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) + /* If saved buffer is alive, install it, unless it's a + minibuffer we explicitly prohibit. */ { wset_buffer (w, p->buffer); w->start_at_line_beg = !NILP (p->start_at_line_beg); @@ -7258,9 +7263,11 @@ void restore_window_configuration (Lisp_Object configuration) { if (CONSP (configuration)) - Fset_window_configuration (XCDR (configuration), XCAR (configuration)); + Fset_window_configuration (XCAR (configuration), + XCAR (XCDR (configuration)), + XCAR (XCDR (XCDR (configuration)))); else - Fset_window_configuration (configuration, Qnil); + Fset_window_configuration (configuration, Qnil, Qnil); } > martin -- Alan Mackenzie (Nuremberg, Germany).