Function: delete-window-internal
delete-window-internal is a function defined in window.c.
Signature
(delete-window-internal WINDOW)
Documentation
Remove WINDOW from its frame.
WINDOW defaults to the selected window. Return nil. Signal an error when WINDOW is the only window on its frame.
Source Code
// Defined in /usr/src/emacs/src/window.c
{
Lisp_Object parent, sibling, frame, root;
struct window *w, *p, *s, *r;
struct frame *f;
bool horflag, before_sibling = false;
w = decode_any_window (window);
XSETWINDOW (window, w);
if (NILP (w->contents))
/* It's a no-op to delete an already deleted window. */
return Qnil;
parent = w->parent;
if (NILP (parent))
/* Never delete a minibuffer or frame root window. */
error ("Attempt to delete minibuffer or sole ordinary window");
else if (NILP (w->prev) && NILP (w->next))
/* Rather bow out here, this case should be handled on the Elisp
level. */
error ("Attempt to delete sole window of parent");
p = XWINDOW (parent);
horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
frame = WINDOW_FRAME (w);
f = XFRAME (frame);
root = FRAME_ROOT_WINDOW (f);
r = XWINDOW (root);
/* Unlink WINDOW from window tree. */
if (NILP (w->prev))
/* Get SIBLING below (on the right of) WINDOW. */
{
/* before_sibling means WINDOW is the first child of its
parent and thus before the sibling. */
before_sibling = true;
sibling = w->next;
s = XWINDOW (sibling);
wset_prev (s, Qnil);
wset_combination (p, horflag, sibling);
}
else
/* 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);
}
if (window_resize_check (r, horflag)
&& (XFIXNUM (r->new_pixel)
== (horflag ? r->pixel_width : r->pixel_height)))
/* We can delete WINDOW now. */
{
/* Block input. */
block_input ();
xwidget_view_delete_all_in_window (w);
window_resize_apply (p, horflag);
/* If this window is referred to by the dpyinfo's mouse
highlight, invalidate that slot to be safe (Bug#9904). */
if (!FRAME_INITIAL_P (f))
{
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
if (EQ (hlinfo->mouse_face_window, window))
hlinfo->mouse_face_window = Qnil;
}
fset_redisplay (f);
Vwindow_list = Qnil;
wset_next (w, Qnil); /* Don't delete w->next too. */
free_window_matrices (w);
if (WINDOWP (w->contents))
{
delete_all_child_windows (w->contents);
wset_combination (w, false, Qnil);
}
else
{
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
unchain_marker (XMARKER (w->old_pointm));
unchain_marker (XMARKER (w->start));
wset_buffer (w, Qnil);
}
if (NILP (s->prev) && NILP (s->next))
/* A matrjoshka where SIBLING has become the only child of
PARENT. */
{
/* Put SIBLING into PARENT's place. */
replace_window (parent, sibling, false);
/* Have SIBLING inherit the following three slot values from
PARENT (the combination_limit slot is not inherited). */
wset_normal_cols (s, p->normal_cols);
wset_normal_lines (s, p->normal_lines);
/* Mark PARENT as deleted. */
wset_combination (p, false, Qnil);
/* Try to merge SIBLING into its new parent. */
recombine_windows (sibling);
}
adjust_frame_glyphs (f);
if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
/* We apparently deleted the frame's selected window; use the
frame's first window as substitute but don't record it yet.
`delete-window' may have something better up its sleeves. */
{
/* Use the frame's first window as fallback ... */
Lisp_Object new_selected_window = Fframe_first_window (frame);
if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
Fselect_window (new_selected_window, Qt);
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, new_selected_window);
}
unblock_input ();
FRAME_WINDOW_CHANGE (f) = true;
}
else
/* We failed: Relink WINDOW into window tree. */
{
if (before_sibling)
{
wset_prev (s, window);
wset_combination (p, horflag, window);
}
else
{
wset_next (s, window);
if (!NILP (w->next))
wset_prev (XWINDOW (w->next), window);
}
error ("Deletion failed");
}
return Qnil;
}