Subject: Re: bug#7875: point preserved incorrectly with minibuffer-frame

From: martin rudalics <[email-masked]>
Date: Fri, 21 Jan 2011 08:41:25 +0100

> When I do
 >
 >    % src/emacs -Q --eval '(setq default-frame-alist (quote ((minibuffer . nil))))'
 >    M-: (goto-char (point-min)) RET
 >
 > the cursor stays at EOB rather than going to BOB.  I suspect this is due
 > to the recent change with the Fset_window_configuration issue.

I have posted two possible fixes: Either you replace the code

   if (EQ (window, selected_window))
     return window;

in Fselect_window with

   if (EQ (window, selected_window))
     {
      inhibit_point_swap = 0;
      return window;
     }

or you try the attached patch.  If possible, try both fixes.

martin, who should think about a better solution
=== modified file 'src/window.c'
*** src/window.c	2011-01-15 23:16:57 +0000
--- src/window.c	2011-01-16 10:18:51 +0000
***************
*** 85,90 ****
--- 85,91 ----
                               int (* fn) (struct window *, void *),
                               void *);
  static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
+ static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
  
  /* This is the window in which the terminal's cursor should
     be left when nothing is being done with it.  This must
***************
*** 158,168 ****
  
  static int window_initialized;
  
- /* Set in `set-window-configuration' to prevent "swapping out point"
-    in the old selected window.  */
- 
- static int inhibit_point_swap;
- 
  /* Hook to run when window config changes.  */
  
  static Lisp_Object Qwindow_configuration_change_hook;
--- 159,164 ----
***************
*** 3550,3569 ****
    return Qnil;
  }
  
- /* Note that selected_window can be nil when this is called from
-    Fset_window_configuration.  */
  
! DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
!        doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
! If WINDOW is not already selected, make WINDOW's buffer current
! and make WINDOW the frame's selected window.  Return WINDOW.
! Optional second arg NORECORD non-nil means do not put this buffer
! at the front of the list of recently selected ones and do not
! make this window the most recently selected one.
  
! Note that the main editor command loop selects the buffer of the
! selected window before each command.  */)
!   (register Lisp_Object window, Lisp_Object norecord)
  {
    register struct window *w;
    register struct window *ow;
--- 3546,3560 ----
    return Qnil;
  }

! /* If select_window is called with inhibit_point_swap non-zero it will
!    not store point of the old selected window's buffer back into that
!    window's pointm slot.  This is needed by Fset_window_configuration to
!    avoid that the display routine is called with selected_window set to
!    Qnil causing a subsequent crash.  */
  
! static Lisp_Object
! select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
  {
    register struct window *w;
    register struct window *ow;
***************
*** 3603,3611 ****
    /* Store the current buffer's actual point into the
       old selected window.  It belongs to that window,
       and when the window is not selected, must be in the window.  */
!   if (inhibit_point_swap)
!     inhibit_point_swap = 0;
!   else
      {
        ow = XWINDOW (selected_window);
        if (! NILP (ow->buffer))
--- 3594,3600 ----
    /* Store the current buffer's actual point into the
       old selected window.  It belongs to that window,
       and when the window is not selected, must be in the window.  */
!   if (! inhibit_point_swap)
      {
        ow = XWINDOW (selected_window);
        if (! NILP (ow->buffer))
***************
*** 3639,3644 ****
--- 3628,3648 ----
    return window;
  }
  
+ DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
+        doc: /* Select WINDOW.  Most editing will apply to WINDOW's buffer.
+ If WINDOW is not already selected, make WINDOW's buffer current
+ and make WINDOW the frame's selected window.  Return WINDOW.
+ Optional second arg NORECORD non-nil means do not put this buffer
+ at the front of the list of recently selected ones and do not
+ make this window the most recently selected one.
+ 
+ Note that the main editor command loop selects the buffer of the
+ selected window before each command.  */)
+   (register Lisp_Object window, Lisp_Object norecord)
+ {
+   select_window (window, norecord, 0);
+ }
+ 
  static Lisp_Object
  select_window_norecord (Lisp_Object window)
  {
***************
*** 6167,6174 ****
  	 out point" in the old selected window using the buffer that
  	 has been restored into it.  We already swapped out that point
  	 from that window's old buffer.  */
!       inhibit_point_swap = 1;
!       Fselect_window (data->current_window, Qnil);
        XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window
  	= selected_window;
  
--- 6171,6177 ----
  	 out point" in the old selected window using the buffer that
  	 has been restored into it.  We already swapped out that point
  	 from that window's old buffer.  */
!       select_window (data->current_window, Qnil, 1);
        XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window
  	= selected_window;
  
***************
*** 7099,7106 ****
    window_scroll_preserve_hpos = -1;
    window_scroll_preserve_vpos = -1;
  
-   inhibit_point_swap = 0;
- 
    DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
  	       doc: /* Non-nil means call as function to display a help buffer.
  The function is called with one argument, the buffer to be displayed.
--- 7102,7107 ----