Function: delete-other-windows-internal

delete-other-windows-internal is an interactive function defined in window.c.

Signature

(delete-other-windows-internal &optional WINDOW ROOT)

Documentation

Make WINDOW fill its frame.

Only the frame WINDOW is on is affected. WINDOW must be a valid window and defaults to the selected one.

Optional argument ROOT, if non-nil, must specify an internal window such that WINDOW is in its window subtree. If this is the case, replace ROOT by WINDOW and leave alone any windows not part of ROOT's subtree.

When WINDOW is live try to reduce display jumps by keeping the text previously visible in WINDOW in the same place on the frame. Doing this depends on the value of (window-start WINDOW), so if calling this function in a program gives strange scrolling, make sure the window-start value is reasonable when this function is called.

Key Bindings

Source Code

// Defined in /usr/src/emacs/src/window.c
// Skipping highlighting due to helpful-max-highlight.
{
  struct window *w = decode_valid_window (window);
  struct window *r, *s;
  Lisp_Object frame = w->frame;
  struct frame *f = XFRAME (frame);
  Lisp_Object sibling, pwindow, delta;
  Lisp_Object swindow UNINIT;
  ptrdiff_t startpos UNINIT, startbyte UNINIT;
  int top UNINIT;
  int new_top;
  bool resize_failed = false;

  XSETWINDOW (window, w);

  if (NILP (root))
    /* ROOT is the frame's root window.  */
    {
      root = FRAME_ROOT_WINDOW (f);
      r = XWINDOW (root);
    }
  else
    /* ROOT must be an ancestor of WINDOW.  */
    {
      r = decode_valid_window (root);
      pwindow = XWINDOW (window)->parent;
      while (!NILP (pwindow))
	if (EQ (pwindow, root))
	  break;
	else
	  pwindow = XWINDOW (pwindow)->parent;
      if (!EQ (pwindow, root))
	error ("Specified root is not an ancestor of specified window");
    }

  if (EQ (window, root))
    /* A noop.  */
    return Qnil;
  /* I don't understand the "top > 0" part below.  If we deal with a
     standalone minibuffer it would have been caught by the preceding
     test.  */
  else if (MINI_WINDOW_P (w)) /* && top > 0) */
    error ("Can't expand minibuffer to full frame");

  if (BUFFERP (w->contents))
    {
      startpos = marker_position (w->start);
      startbyte = marker_byte_position (w->start);
      top = (WINDOW_TOP_EDGE_LINE (w)
	     - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))));
      /* Make sure WINDOW is the frame's selected window.  */
      if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
	{
	  if (EQ (selected_frame, frame))
	    Fselect_window (window, Qnil);
	  else
	    /* Do not clear f->select_mini_window_flag here.  If the
	       last selected window on F was an active minibuffer, we
	       want to return to it on a later Fselect_frame.  */
	    fset_selected_window (f, window);
	}
    }
  else
    {
      /* See if the frame's selected window is a part of the window
	 subtree rooted at WINDOW, by finding all the selected window's
	 parents and comparing each one with WINDOW.  If it isn't we
	 need a new selected window for this frame.  */
      swindow = FRAME_SELECTED_WINDOW (f);
      while (true)
	{
	  pwindow = swindow;
	  while (!NILP (pwindow) && !EQ (window, pwindow))
	    pwindow = XWINDOW (pwindow)->parent;

	  if (EQ (window, pwindow))
	    /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
	       as the new selected window.  */
	    break;
	  else
	    /* Else try the previous window of SWINDOW.  */
	    swindow = Fprevious_window (swindow, Qlambda, Qnil);
	}

      if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
	{
	  if (EQ (selected_frame, frame))
	    Fselect_window (swindow, Qnil);
	  else
	    fset_selected_window (f, swindow);
	}
    }

  block_input ();
  if (!FRAME_INITIAL_P (f))
    {
      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);

      /* We are going to free the glyph matrices of WINDOW, and with
	 that we might lose any information about glyph rows that have
	 some of their glyphs highlighted in mouse face.  (These rows
	 are marked with a mouse_face_p flag.)  If WINDOW
	 indeed has some glyphs highlighted in mouse face, signal to
	 frame's up-to-date hook that mouse highlight was overwritten,
	 so that it will arrange for redisplaying the highlight.  */
      if (EQ (hlinfo->mouse_face_window, window))
	reset_mouse_highlight (hlinfo);
    }
  free_window_matrices (r);

  fset_redisplay (f);
  Vwindow_list = Qnil;

  if (!WINDOW_LEAF_P (w))
    {
      /* Resize child windows vertically.  */
      XSETINT (delta, r->pixel_height - w->pixel_height);
      w->pixel_top = r->pixel_top;
      w->top_line = r->top_line;
      resize_root_window (window, delta, Qnil, Qnil, Qt);
      if (window_resize_check (w, false))
	window_resize_apply (w, false);
      else
	{
	  resize_root_window (window, delta, Qnil, Qt, Qt);
	  if (window_resize_check (w, false))
	    window_resize_apply (w, false);
	  else
	    resize_failed = true;
	}

      /* Resize child windows horizontally.  */
      if (!resize_failed)
	{
	  w->left_col = r->left_col;
	  w->pixel_left = r->pixel_left;
	  XSETINT (delta, r->pixel_width - w->pixel_width);
	  resize_root_window (window, delta, Qt, Qnil, Qt);
	  if (window_resize_check (w, true))
	    window_resize_apply (w, true);
	  else
	    {
	      resize_root_window (window, delta, Qt, Qt, Qt);
	      if (window_resize_check (w, true))
		window_resize_apply (w, true);
	      else
		resize_failed = true;
	    }
	}

      if (resize_failed)
	/* Play safe, if we still can ...  */
	{
	  window = swindow;
	  w = XWINDOW (window);
	}
    }

  /* Cleanly unlink WINDOW from window-tree.  */
  if (!NILP (w->prev))
    /* Get SIBLING above (on the left of) WINDOW.  */
    {
      sibling = w->prev;
      s = XWINDOW (sibling);
      wset_next (s, w->next);
      if (!NILP (s->next))
	wset_prev (XWINDOW (s->next), sibling);
    }
  else
    /* Get SIBLING below (on the right of) WINDOW.  */
    {
      sibling = w->next;
      s = XWINDOW (sibling);
      wset_prev (s, Qnil);
      wset_combination (XWINDOW (w->parent),
			XWINDOW (w->parent)->horizontal, sibling);
    }

  /* Delete ROOT and all child windows of ROOT.  */
  if (WINDOWP (r->contents))
    {
      delete_all_child_windows (r->contents);
      wset_combination (r, false, Qnil);
    }

  replace_window (root, window, true);
  /* Assign new total sizes to all windows on FRAME.  We can't do that
     _before_ WINDOW replaces ROOT since 'window--pixel-to-total' works
     on the whole frame and thus would work on the frame's old window
     configuration (Bug#51007).  */
  window_pixel_to_total (frame, Qnil);
  window_pixel_to_total (frame, Qt);

  /* This must become SWINDOW anyway .......  */
  if (BUFFERP (w->contents) && !resize_failed)
    {
      /* Try to minimize scrolling, by setting the window start to the
	 point will cause the text at the old window start to be at the
	 same place on the frame.  But don't try to do this if the
	 window start is outside the visible portion (as might happen
	 when the display is not current, due to typeahead).  */
      new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
      if (new_top != top
	  && startpos >= BUF_BEGV (XBUFFER (w->contents))
	  && startpos <= BUF_ZV (XBUFFER (w->contents)))
	{
	  struct position pos;
	  struct buffer *obuf = current_buffer;

	  Fset_buffer (w->contents);
	  /* This computation used to temporarily move point, but that
	     can have unwanted side effects due to text properties.  */
	  pos = *vmotion (startpos, startbyte, -top, w);

	  set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
	  w->window_end_valid = false;
	  w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
				    || FETCH_BYTE (pos.bytepos - 1) == '\n');
	  /* We need to do this, so that the window-scroll-functions
	     get called.  */
	  w->optional_new_start = true;

	  set_buffer_internal (obuf);
	}
    }

  adjust_frame_glyphs (f);
  unblock_input ();

  FRAME_WINDOW_CHANGE (f) = true;

  return Qnil;
}