summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c170
1 files changed, 156 insertions, 14 deletions
diff --git a/src/window.c b/src/window.c
index 8d4bde8d6db..748ad9e77d4 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1680,7 +1680,8 @@ check_window_containing (struct window *w, void *user_data)
Lisp_Object
window_from_coordinates (struct frame *f, int x, int y,
- enum window_part *part, bool tab_bar_p, bool tool_bar_p)
+ enum window_part *part, bool menu_bar_p,
+ bool tab_bar_p, bool tool_bar_p)
{
Lisp_Object window;
struct check_window_data cw;
@@ -1693,6 +1694,21 @@ window_from_coordinates (struct frame *f, int x, int y,
cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
foreach_window (f, check_window_containing, &cw);
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_MENU_BAR)
+ /* If not found above, see if it's in the menu bar window, if a menu
+ bar exists. */
+ if (NILP (window)
+ && menu_bar_p
+ && WINDOWP (f->menu_bar_window)
+ && WINDOW_TOTAL_LINES (XWINDOW (f->menu_bar_window)) > 0
+ && (coordinates_in_window (XWINDOW (f->menu_bar_window), x, y)
+ != ON_NOTHING))
+ {
+ *part = ON_TEXT;
+ window = f->menu_bar_window;
+ }
+#endif
+
#if defined (HAVE_WINDOW_SYSTEM)
/* If not found above, see if it's in the tab bar window, if a tab
bar exists. */
@@ -1746,7 +1762,7 @@ function returns nil. */)
+ FRAME_INTERNAL_BORDER_WIDTH (f)),
(FRAME_PIXEL_Y_FROM_CANON_Y (f, y)
+ FRAME_INTERNAL_BORDER_WIDTH (f)),
- 0, false, false);
+ 0, false, false, false);
}
ptrdiff_t
@@ -3514,7 +3530,10 @@ window-start value is reasonable when this function is called. */)
void
replace_buffer_in_windows (Lisp_Object buffer)
{
- call1 (Qreplace_buffer_in_windows, buffer);
+ /* When kill-buffer is called early during loadup, this function is
+ undefined. */
+ if (!NILP (Ffboundp (Qreplace_buffer_in_windows)))
+ call1 (Qreplace_buffer_in_windows, buffer);
}
/* If BUFFER is shown in a window, safely replace it with some other
@@ -3810,7 +3829,7 @@ run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
frame. Make sure to record changes for each live frame
in window_change_record later. */
window_change_record_frames = true;
- safe_call1 (XCAR (funs), window_or_frame);
+ safe_calln (XCAR (funs), window_or_frame);
}
funs = XCDR (funs);
@@ -3876,6 +3895,9 @@ run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
*
* This function does not save and restore match data. Any functions
* it calls are responsible for doing that themselves.
+ *
+ * Additionally, report changes to each frame's selected window to the
+ * input method in textconv.c.
*/
void
run_window_change_functions (void)
@@ -4035,6 +4057,18 @@ run_window_change_functions (void)
run_window_change_functions_1
(Qwindow_selection_change_functions, Qnil, frame);
+#if defined HAVE_TEXT_CONVERSION
+
+ /* If the buffer or selected window has changed, also reset the
+ input method composition state. */
+
+ if ((frame_selected_window_change || frame_buffer_change)
+ && FRAME_LIVE_P (f)
+ && FRAME_WINDOW_P (f))
+ report_selected_window_change (f);
+
+#endif
+
/* A frame has changed state when a size or buffer change
occurred, its selected window has changed, when it was
(de-)selected or its window state change flag was set. */
@@ -4117,6 +4151,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
buffer);
w->start_at_line_beg = false;
w->force_start = false;
+ /* Flush the base_line cache since it applied to another buffer. */
+ w->base_line_number = 0;
}
wset_redisplay (w);
@@ -4813,10 +4849,9 @@ values. */)
return Qt;
}
+/* Resize frame F's windows when F's inner height (inner width if
+ HORFLAG is true) has been set to SIZE pixels. */
-/**
-Resize frame F's windows when F's inner height (inner width if HORFLAG
-is true) has been set to SIZE pixels. */
void
resize_frame_windows (struct frame *f, int size, bool horflag)
{
@@ -5298,7 +5333,17 @@ resize_mini_window_apply (struct window *w, int delta)
w->pixel_top = r->pixel_top + r->pixel_height;
w->top_line = r->top_line + r->total_lines;
- /* Enforce full redisplay of the frame. */
+ /* Enforce full redisplay of the frame. If f->redisplay is already
+ set, which it generally is in the wake of a ConfigureNotify
+ (frame resize) event, merely setting f->redisplay is insufficient
+ for redisplay_internal to continue redisplaying the frame, as
+ redisplay_internal cannot distinguish between f->redisplay set
+ before it calls redisplay_window and that after, so garbage the
+ frame as well. */
+
+ if (f->redisplay)
+ SET_FRAME_GARBAGED (f);
+
/* FIXME: Shouldn't some of the caller do it? */
fset_redisplay (f);
adjust_frame_glyphs (f);
@@ -5335,7 +5380,14 @@ grow_mini_window (struct window *w, int delta)
grow = call3 (Qwindow__resize_root_window_vertically,
root, make_fixnum (- delta), Qt);
- if (FIXNUMP (grow) && window_resize_check (r, false))
+ if (FIXNUMP (grow)
+ /* It might be impossible to resize the window, in which case
+ calling resize_mini_window_apply will set off an infinite
+ loop where the redisplay cycle so forced returns to
+ resize_mini_window, making endless attempts to expand the
+ minibuffer window to this impossible size. (bug#69140) */
+ && XFIXNUM (grow) != 0
+ && window_resize_check (r, false))
resize_mini_window_apply (w, -XFIXNUM (grow));
}
}
@@ -7057,6 +7109,10 @@ 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.
+This function consults the variable `window-restore-killed-buffer-windows'
+when restoring a window whose buffer was killed after CONFIGURATION was
+recorded.
+
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. */)
@@ -7067,6 +7123,7 @@ the return value is nil. Otherwise the value is t. */)
struct Lisp_Vector *saved_windows;
Lisp_Object new_current_buffer;
Lisp_Object frame;
+ Lisp_Object kept_windows = Qnil;
Lisp_Object old_frame = selected_frame;
struct frame *f;
ptrdiff_t old_point = -1;
@@ -7307,6 +7364,13 @@ the return value is nil. Otherwise the value is t. */)
BUF_PT (XBUFFER (w->contents)),
BUF_PT_BYTE (XBUFFER (w->contents)));
w->start_at_line_beg = true;
+ if (FUNCTIONP (window_restore_killed_buffer_windows)
+ && !MINI_WINDOW_P (w))
+ kept_windows = Fcons (listn (6, window, p->buffer,
+ Fmarker_last_position (p->start),
+ Fmarker_last_position (p->pointm),
+ p->dedicated, Qt),
+ kept_windows);
}
else if (!NILP (w->start))
/* Leaf window has no live buffer, get one. */
@@ -7322,11 +7386,25 @@ the return value is nil. Otherwise the value is t. */)
set_marker_restricted_both (w->pointm, w->contents, 0, 0);
set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
w->start_at_line_beg = true;
- if (!NILP (w->dedicated))
- /* Record this window as dead. */
- dead_windows = Fcons (window, dead_windows);
- /* Make sure window is no more dedicated. */
- wset_dedicated (w, Qnil);
+ if (!MINI_WINDOW_P (w))
+ {
+ if (FUNCTIONP (window_restore_killed_buffer_windows))
+ kept_windows
+ = Fcons (listn (6, window, p->buffer,
+ Fmarker_last_position (p->start),
+ Fmarker_last_position (p->pointm),
+ p->dedicated, Qnil),
+ kept_windows);
+ else if (EQ (window_restore_killed_buffer_windows, Qdelete)
+ || (!NILP (p->dedicated)
+ && (NILP (window_restore_killed_buffer_windows)
+ || EQ (window_restore_killed_buffer_windows,
+ Qdedicated))))
+ /* Try to delete this window later. */
+ dead_windows = Fcons (window, dead_windows);
+ /* Make sure window is no more dedicated. */
+ wset_dedicated (w, Qnil);
+ }
}
}
@@ -7430,6 +7508,11 @@ the return value is nil. Otherwise the value is t. */)
minibuf_selected_window = data->minibuf_selected_window;
SAFE_FREE ();
+
+ if (!NILP (Vrun_hooks) && FUNCTIONP (window_restore_killed_buffer_windows))
+ safe_calln (window_restore_killed_buffer_windows,
+ frame, kept_windows, Qconfiguration);
+
return FRAME_LIVE_P (f) ? Qt : Qnil;
}
@@ -8427,6 +8510,9 @@ syms_of_window (void)
DEFSYM (Qheader_line_format, "header-line-format");
DEFSYM (Qtab_line_format, "tab-line-format");
DEFSYM (Qno_other_window, "no-other-window");
+ DEFSYM (Qconfiguration, "configuration");
+ DEFSYM (Qdelete, "delete");
+ DEFSYM (Qdedicated, "dedicated");
DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
doc: /* Non-nil means call as function to display a help buffer.
@@ -8584,6 +8670,62 @@ its buffer or its total or body size since the last redisplay. Each
call is performed with the frame temporarily selected. */);
Vwindow_configuration_change_hook = Qnil;
+ DEFVAR_LISP ("window-restore-killed-buffer-windows",
+ window_restore_killed_buffer_windows,
+ doc: /* Control restoring windows whose buffer was killed.
+This variable specifies how the functions `set-window-configuration' and
+`window-state-put' shall handle a window whose buffer has been killed
+since the corresponding configuration or state was recorded. Any such
+window may be live -- in which case it shows some other buffer -- or
+dead at the time one of these functions is called.
+
+By default, `set-window-configuration' leaves the window alone if it is
+live, while `window-state-put' deletes it. The following values can be
+used to override the default behavior for dead windows in the case of
+`set-window-configuration' and for dead and live windows in the case of
+`window-state-put'.
+
+ - t means to restore the window and show some other buffer in it.
+
+ - `delete' means to try to delete the window.
+
+ - `dedicated' means to try to delete the window if and only if it is
+ dedicated to its buffer.
+
+ - nil, the default, which means that `set-window-configuration' will
+ try to delete the window if and only if it is dedicated to its
+ buffer while `window-state-put' will unconditionally try to delete
+ it.
+
+ - a function means to restore the window and show some other buffer in
+ it, like if the value were t, but also to add an entry for that
+ window to a list that will be later passed as argument to that
+ function.
+
+If a window cannot be deleted (typically, because it is the last window
+on its frame), show another buffer in it.
+
+If the value is a function, it should take three arguments. The first
+argument specifies the frame whose windows have been restored. The
+third argument is the symbol `configuration' if the windows are
+restored by `set-window-configuration' and the symbol `state' if the
+windows are restored by `window-state-put'.
+
+The second argument specifies a list of entries for all windows whose
+previous buffers have been found dead at the time
+`set-window-configuration' or `window-state-put' tried to restore them
+(minibuffer windows are excluded). This means that the function
+specified by this variable may also delete windows which were found to
+be alive by `set-window-configuration'.
+
+Each entry is a list of six values: the window whose buffer was found
+dead, the dead buffer or its name, the positions of window-start and
+window-point of the buffer in that window, the dedicated state of the
+window as reported by `window-dedicated-p', and a boolean -- t if the
+window was live when `set-window-configuration' tried to restore it,
+and nil otherwise. */);
+ window_restore_killed_buffer_windows = Qnil;
+
DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
doc: /* Non-nil means `recenter' redraws entire frame.
If this option is non-nil, then the `recenter' command with a nil