* src/window.c (last_mouse_window): New global var. All static
instances removed, and all their uses replaced with this global
var. This fixes a very unlikely bug where last_mouse_window was
GC’ed and a new window created in its place. It also fixes several
places that assumed NIL_IS_ZERO without static_asserting it.
(init_window_once): Initialize the new var.
* src/dispextern.h (root_frame):
* src/frame.h (root_frame): Move declaration from dispextern.h
to frame.h.
(SET_FRAME_VISIBLE): Whend making the selected tty child frame
invisible, use mru_rooted_frame to find a frame to switch to.
* src/dispnew.c (root_frame): Move root_frame to frame.c.
* src/frame.c (do_switch_frame): On ttys don't change the
top frame when switching from a child frame to another frame
with the same root.
(root_frame): Move here from dispnew.c.
(Fframe_root_frame): New Lisp function.
(delete_frame): Whend deleting the selected tty child frame use,
mru_rooted_frame to find a frame to switch to.
* src/window.c (mru_rooted_frame): New function.
* src/window.h (mru_rooted_frame): Declare it.
* doc/lispref/frames.texi (Child Frames): Describe new function
'frame-root-frame'.
The purpose of these changes is to improve the code handling the
display of buffers in windows, switching to previous and next
buffers in windows and restoring a previous state after quitting
or killing buffers. In particular it does:
- Add a new window parameter 'quit-restore-prev' so a window can
keep its initial 'quit-restore' parameter and undoing a sequence
of quit window operations becomes more reliable (Bug#59862).
- Optionally have 'kill-buffer' call 'quit-restore-window' for
all windows showing the argument buffer (Bug#59862).
- Add a new hook so it's possible to avoid that a window gets
deleted implicitly by functions like 'kill-buffer' (Bug#71386).
- Add a new option to make 'quit-restore-window' delete windows
more aggressively (Bug#59862).
- Immediately remove killed buffers from all windows' previous
and next buffers. For windows that are already dead, use a weak
hash table to be used by 'kill-buffer'. This avoids any special
handling of such windows by the garbage collector.
- Immediately remove 'quit-restore' and 'quit-restore-prev'
window parameters that reference killed buffers. These
parameters have no more use once their buffers got killed.
- Make sure that internal windows do not have any previous and
next buffers. This fixes a silly memory leak.
- Make sure that after set_window_buffer and some wset_buffer
calls the buffer now shown in the window does not appear in the
lists of that window's previous and next buffers. The old
behavior could make functions investigating these lists
erroneously believe that there still existed some other buffer
to switch to.
* src/alloc.c (mark_discard_killed_buffers): Remove function.
(mark_window): No more filter previous and next buffer lists.
* src/window.h (struct window): Move up prev_buffers and
next-buffers in structure; they are now treated by the collector
as usual.
* src/window.c (window_discard_buffer_from_alist)
(window_discard_buffer_from_list)
(window_discard_buffer_from_window)
(window_discard_buffer_from_dead_windows)
(Fwindow_discard_buffer): New functions.
(set_window_buffer): Discard BUFFER from WINDOW's previous and
next buffers.
(make_parent_window): Make sure internal windows have no previous
and next buffers.
(make_window): Don't initialize window's previous and next
buffers, they are handled by allocate_window now.
(Fdelete_window_internal): Add WINDOW to window_dead_windows_table.
(Fset_window_configuration): Remove resurrected window from
window_dead_windows_table. Make sure buffers set by wset_buffer
calls are not recorded in window's previous and next buffers.
(delete_all_child_windows): Add deleted windows to
window_dead_windows_table.
(window_dead_windows_table): New weak hash table to record dead
windows that are stored in saved window configurations.
* src/buffer.c (Fkill_buffer): Call new function
'window_discard_buffer_from_dead_windows'.
* lisp/window.el (window-deletable-functions): New hook.
(window-deletable-p): Update doc-string. Run
'window-deletable-functions' (Bug#71386).
(unrecord-window-buffer): New argument ALL. Move body to
'window-discard-buffer-from-window' so that if ALL is non-nil,
WINDOW's 'quit-restore' and 'quit-restore-prev' parameters get
removed too.
(switch-to-prev-buffer): Don't care about killed buffers here;
'replace-buffer-in-windows' should have done that already. Use
'unrecord-window-buffer'.
(switch-to-next-buffer): Don't care about killed buffers here;
'replace-buffer-in-windows' should do that now.
(kill-buffer-quit-windows): New option.
(delete-windows-on): Update doc-string. Handle new option
'kill-buffer-quit-windows'. Update 'unrecord-window-buffer'
calls.
(replace-buffer-in-windows): Update doc-string. Handle new
option 'kill-buffer-quit-windows' (Bug#59862). Update call to
'unrecord-window-buffer'.
(quit-restore-window-no-switch): New option.
(quit-restore-window): Update doc-string. Handle additional
values of BURY-OR-KILL so to not kill a buffer about to be
killed by the caller. Handle 'quit-restore-prev' parameter
(Bug#59862). Handle new option 'quit-restore-window-no-switch'
(Bug#59862).
(quit-windows-on): Update doc-string. Call 'quit-window-hook'
and call 'quit-restore-window' directly so that the buffer does
not get buried or killed by the latter. Update
'unrecord-window-buffer' call.
(display-buffer-record-window): Update doc-string. Handle new
`quit-restore-prev' parameter (Bug#59862).
(switch-to-buffer): Call 'display-buffer-record-window' so a
latter 'quit-restore-window' can use its parameters.
* doc/lispref/windows.texi (Deleting Windows): Describe implicit
deletion of windows and new hook 'window-deletable-functions'.
(Buffers and Windows): Update description of
'replace-buffer-in-windows'. Describe new option
'kill-buffer-quit-windows'.
(Quitting Windows): Describe 'quit-restore-prev' parameter and
new option 'quit-restore-window-no-switch'. Update description
of 'quit-restore-window'.
(Window Parameters): Mention 'quit-restore-prev' parameter.
* etc/NEWS: Add entries for 'window-deletable-functions',
'kill-buffer-quit-windows', 'quit-restore-window-no-switch'.
mention new parameter 'quit-restore-prev' and new argument
values for 'quit-restore-window'.
Be more systematic about putting space before paren in calls,
and in avoiding unnecessary parentheses in macros.
This was partly inspired by my wading through gcc -E output
while debugging something else, and seeing too many parens.
This patch does not change the generated .o files on my platform.
* src/window.h:
* src/window.c (window_from_coordinates): In the no toolkit
build, add support for the menu bar window. Add a new
'menu_bar_p' argument so the function's signature has changed.
All callers changed.
* src/androidterm.c (handle_one_android_event):
* src/haikuterm.c (haiku_read_socket):
* src/keyboard.c (make_lispy_position):
* src/nsterm.m ([EmacsView mouseDown:]):
* src/pgtkterm.c (button_event):
* src/w32term.c (w32_read_socket):
* src/xdisp.c (note_mouse_highlight):
* src/xterm.c (handle_one_xevent): Set menu_bar_p to true.
* src/window.h (WINDOW_MENU_BAR_P): Check for external menu bars
using HAVE_WINDOW_SYSTEM && HAVE_EXT_MENU_BAR instead of hard
coding X without Xt or GTK.
* src/window.h (GCALIGNED_STRUCT): Improve documentation of
`last_mark'.
* src/xdisp.c (mark_window_display_accurate_1): Don't set
`last_mark' to -1 if the mark is inactive.
* doc/emacs/android.texi (Android Fonts):
* doc/emacs/input.texi (On-Screen Keyboards):
* doc/lispref/commands.texi (Misc Events): Update documentation.
* java/org/gnu/emacs/EmacsInputConnection.java (setSelection):
New function.
* java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView)
(reconfigureFrontBuffer): Make bitmap references weak
references.
* java/org/gnu/emacs/EmacsView.java (handleDirtyBitmap): Don't
clear surfaceView bitmap.
* lisp/comint.el (comint-mode):
* lisp/international/fontset.el (script-representative-chars)
(setup-default-fontset): Improve detection of CJK fonts.
* lisp/isearch.el (set-text-conversion-style): New variable.
(isearch-mode, isearch-done): Save and restore the text
conversion style.
* lisp/minibuffer.el (minibuffer-mode): Set an appropriate text
conversion style.
* lisp/simple.el (analyze-text-conversion): Run
post-self-insert-hook properly.
* lisp/subr.el (read-char-from-minibuffer): Disable text
conversion when reading character.
* src/androidterm.c (show_back_buffer): Don't check that F is
not garbaged.
(android_update_selection, android_reset_conversion): Use the
ephemeral last point and handle text conversion being disabled.
* src/buffer.c (syms_of_buffer): Convert old style DEFVAR.
* src/keyboard.c (kbd_buffer_get_event): Handle text conversion
first.
* src/lisp.h: Update prototypes.
* src/lread.c (read_filtered_event): Temporarily disable text
conversion.
* src/sfnt.c (sfnt_decompose_glyph_1, sfnt_decompose_glyph_2):
New functions.
(sfnt_decompose_glyph, sfnt_decompose_instructed_outline):
Refactor contour decomposition to those two functions.
(main): Update tests.
* src/sfntfont-android.c (system_font_directories): Add empty
field.
(Fandroid_enumerate_fonts, init_sfntfont_android): Enumerate
fonts in a user fonts directory.
* src/sfntfont.c (struct sfnt_font_desc): New field
`num_glyphs'.
(sfnt_enum_font_1): Set num_glyphs and avoid duplicate fonts.
(sfntfont_glyph_valid): New function.
(sfntfont_lookup_char, sfntfont_list_1): Make sure glyphs found
are valid.
* src/textconv.c (sync_overlay, really_commit_text)
(really_set_composing_text, really_set_composing_region)
(really_delete_surrounding_text, really_set_point_and_mark)
(handle_pending_conversion_events_1)
(handle_pending_conversion_events, conversion_disabled_p)
(disable_text_conversion, resume_text_conversion)
(Fset_text_conversion_style, syms_of_textconv): Update to
respect new options.
* src/textconv.h:
* src/window.h (GCALIGNED_STRUCT): New field
`ephemeral_last_point'.
* src/xdisp.c (mark_window_display_accurate_1): Set it.
This variable and related functions have been obsolete since 23.1.
The last things to depend on this (fast-lock.el and lazy-lock.el) were
recently removed.
* src/dispextern.h (struct it): Delete field
'redisplay_end_trigger_charpos'.
* src/window.c (Fwindow_redisplay_end_trigger)
(Fset_window_redisplay_end_trigger): Delete defuns and corresponding
defsubrs for functions obsolete since 23.1.
* src/window.h (wset_redisplay_end_trigger): Delete function.
(GCALIGNED_STRUCT): Delete 'redisplay_end_trigger'.
* src/xdisp.c (run_redisplay_end_trigger_hook): Delete function.
(syms_of_xdisp) <redisplay_end_trigger_functions>: Delete
variable obsolete since 23.1.
(init_iterator, next_element_from_buffer): Don't run or set above
deleted hook variable.
* lisp/subr.el: Delete obsoletion definitions for above deleted
defuns and variable.
* doc/lispref/hooks.texi (Standard Hooks):
* lisp/emacs-lisp/byte-opt.el (side-effect-free-fns):
* lisp/loadhist.el (unload-feature-special-hooks): Don't mention
above deleted variable.
* admin/coccinelle/window.cocci: Adjust for above changes.
* src/dispextern.h (struct it): New 'narrowed_begv' field.
* src/dispextern.h (WITH_NARROWED_BEGV): New macro.
* src/xdisp.c (get_narrowed_begv): New function.
(init_iterator): Initilize the 'narrowed_begv' field.
(back_to_previous_line_start, get_visually_first_element,
move_it_vertically_backward): Use the new macro.
* src/dispextern.h: Prototype of 'get_narrowed_begv'.
* src/window.c (window_body_height): Make it externally visible.
* src/window.h: Prototype of 'window_body_height'.
* src/composite.c (find_automatic_composition): Optimize display in buffers
with very long lines with 'get_narrowed_begv'.
* lisp/obsolete/longlines.el: Reobsolete longlines-mode.
* etc/NEWS: Announce the new minor mode, and remove the unobsoletion
indication for 'longlines-mode'.
* doc/emacs/trouble.texi (Long Lines): Remove the section.
(Lossage): Remove the entry for the Long Lines section.
* doc/emacs/emacs.texi (Top): Remove the entry for the Long Lines section.
* src/window.h (window_body_unit): New enum...
(window_body_width): ... use it.
* src/window.c (window_body_unit_from_symbol): New function.
(window_body_height, window_body_width): Make PIXELWISE a
'window_body_unit'.
(window-body-height, window-body-width): Accept 'remap' for PIXELWISE.
(window-lines-pixel-dimensions, window_change_record_windows)
(run_window_change_functions, resize_frame_windows, grow_mini_window)
(shrink_mini_window, scroll-left, scroll-right): Update calls to
'window_body_height' and 'window_body_width'.
* src/indent.c (compute_motion): Update calls to 'window_body_width'.
* lisp/eshell/em-ls.el (eshell-ls-find-column-widths)
(eshell-ls-find-column-lengths): Use 'window-body-width'.
* lisp/eshell/esh-var.el (eshell-variable-aliases-list): Use
'window-body-width' and 'window-body-height'.
* test/lisp/eshell/esh-var-tests.el (esh-var-test/window-height)
(esh-var-test/window-width): Rename to...
(esh-var-test/lines-var, esh-var-test/columns-var): ... and update
expected value.
* doc/lispref/windows.texi (Window Sizes): Document new behavior of
PIXELWISE argument for 'window-body-width' and 'window-body-height'.
* etc/NEWS: Announce this change (bug#55696).
* doc/lispref/windows.texi (Vertical Scrolling): Document new
`preserve-vscroll-p' parameter of `set-window-vscroll'.
* etc/NEWS: Announce new parameter.
* lisp/pixel-scroll.el (pixel-scroll-precision-scroll-down-page)
(pixel-scroll-precision-scroll-up-page): Use that parameter when
setting the vscroll.
* src/window.c (window_scroll_pixel_based, Fset_window_vscroll):
Adjust for new parameter.
* src/window.h (struct window): New flag `preserve_vscroll_p'.
* src/xdisp.c (redisplay_window): Preserve the vscroll inside
force_start on frozen windows with that flag set. (bug#55312)
This consolidates the test made in those two functions so as to make
sure they agree whether a window needs to be redisplayed.
At the same time, change this test so it uses the window's point
rather than the buffer's point when comparing to `w->last_point`.
* src/xdisp.c (needs_no_redisplay): New function, extracted from
`redisplay_window`.
(redisplay_window, prepare_menu_bars): Use it.
* src/window.c (window_point): New function, extracted from `Fwindow_point`.
(Fwindow_point): Use it.
* src/window.h (window_point): Declare it.
Move that function next to its siblings. Also simplify it, since
after careful analysis it is now clear that the frame's title's update
is already handled elsewhere (in `prepare_menu_bars` and `redisplay_window`)
so we just need to make sure the `redisplay` bit is set.
* src/window.c (wset_update_mode_line): Move to `src/xdisp.c`.
* src/window.h (wset_update_mode_line): Declare.
* lisp/minibuffer.el (exit-minibuffer): When in a minibuffer, throw an error
should the command loop nesting level be wrong.
* src/lisp.h (minibuffer_quit_level): declare as an extern.
(command_loop_level): Move definition from src/window.h
* src/window.h (command_loop_level): move definition to src/lisp.h.
* src/eval.c (minibuffer_quit_level): Move this variable to file level from
being a static inside internal_catch.
(internal_catch): Simplify the logic.
* src/minibuf.c (Vcommand_loop_level_list): New variable.
(move_minibuffer_onto_frame): Set the major mode of *Minibuf-0*.
(Fminibuffer_innermost_command_loop_p): New primitive.
(Fabort_minibuffers): Check the command loop level before throwing t to 'exit,
and set minibuffer_quit_level too.
(read_minibuf): New variable calling_window.
Before stacking up minibuffers on the current mini-window, check that the
mini-window is not the current one.
Do not call choose_minibuf_frame from read_minibuf's unwinding process.
Bind calling_frame and calling_window over the recursive edit.
Set the new minibuffer's major mode directly.
Remove the switching away from the minibuffer after the recursive edit.
(get_minibuffer): Record the command loop level in new variable
Vcommand_loop_level_list. No longer set the major mode of a returned
minibuffer.
(minibuf_c_loop_level): New function.
(read_minibuf_unwind): New variables calling_frame, calling_window are unbound
from the binding stack. Remove old variable `window', which could not be set
reliably to the expired mini-window.
The expired minibuffer is determined as the nth in the list, rather than the
contents of the current or previous mini-window.
Switch the current window away from the mini-window here (moved from
read_minibuf).
In particular, add a new value to the variable, and fix several bugs apparent
with the implementation up till now.
* doc/emacs/mini.texi (Basic Minibuffer): Add a description of the new
non-nil, non-t value of minibuffer-follows-selected-frame.
* doc/emacs/trouble.texi (Quitting): Add a description of how C-g handles
recursive minibuffers when typed in one which isn't the most nested.
* doc/lispref/minibuf.texi (Intro to Minibuffers): Add an @dfn for "active
minibuffer".
(Minibuffer Commands): Document that exit-minibuffer throws an error when not
invoked from the innermost Minibuffer.
(Recursive Mini): Amend the description of the visibility of outer level
minibuffers.
(Minibuffer Misc): In the description of the minibuffer hooks, replace "the
minibuffer" with "a minibuffer".
* etc/NEWS (Entry announcing minibuffer-follows-selected-frame): Add a
description of the new non-nil, non-t value.
* lisp/cus-start.el (top level): make the customize entry for
minibuffer-follows-selected-frame a choice between three entries.
* lisp/minibuffer.el (exit-minibuffer): throw an error when we're not in the
most nested minibuffer.
(top level): Bind C-g to abort-minibuffers in minibuffer-local-map.
* lisp/window.el (window-deletable-p): return the symbol `frame' when (amongst
other things) minibuffer-follows-selected-frame is t.
* src/eval.c (internal_catch): Add a mechanism to (throw 'exit t) repeatedly
when the throw currently being processed doesn't terminate the current
minibuffer.
* src/lisp.h (this_minibuffer_depth): New extern declaration
(minibuf_level): extern declaration moved here from window.h.
* src/minibuf.c (minibuffer_follows_frame, minibuf_stays_put)
(minibuf_moves_frame_when_opened): New and amended functions to query the
value of minibuffer-follows-selected-frame.
(choose_minibuf_frame): check (minibuf > 1) in place of (minibufer > 0) at a
particular place. At another place, check that an alleged frame is so and is
live. Before selecting a non-miniwindow on a different frame, ensure it
really is a different frame.
(move_minibuffer_onto_frame): Stack up all recursive minibuffers on the target
frame. Check the minibuf_window isn't in the old frame before setting that
frame's miniwindow to an inactive minibuffer.
(Finnermost_minibuffer_p, Fabort_minibuffers): New primitives.
(this_minibuffer_depth): New function.
(read_minibuf): Record the calling frame in a variable, and switch back to it
after the recursive edit has terminated normally, using
select-frame-set-input-focus. Stack up all the recursive minibuffers on the
miniwindow where a new minibuffer is being opened. After the recursive edit,
switch the selected window away from the expired minibuffer's window.
(nth_minibuffer): New function.
(minibuffer-follows-selected-frame): Change from a DEFVAR_BOOL to a
DEFVAR_LISP.
* src/window.c (decode_next_window_args): Set *minibuf to w's mini-window's
content when that content is a minibuffer.
* src/window.h (minibuf_level) Declaration moved from here to lisp.h.
Problem reported by Pip Cet (Bug#38912#14).
* doc/lispref/objects.texi (Equality Predicates):
Document better when ‘equal’ looks inside objects.
* doc/lispref/windows.texi (Window Configurations):
Don’t say that ‘equal’ looks inside window configurations.
* etc/NEWS: Mention the change.
* src/fns.c (internal_equal):
Do not look inside window configurations.
(sxhash_obj): Hash markers, byte-code function objects,
char-tables, and font objects consistently with Fequal.
* src/window.c (compare_window_configurations):
Now static. Remove last argument. Caller changed.
* test/lisp/ffap-tests.el (ffap-other-window--bug-25352):
Use compare-window-configurations, not ‘equal’.
* test/src/fns-tests.el (test-sxhash-equal): New test.
* src/window.h (WINDOW_BUFFER_LOCAL_VALUE): New macro.
* src/nsterm.m (ns_draw_text_decoration):
* src/w32term.c (w32_draw_glyph_string):
* src/xterm.c (x_draw_glyph_string): Make sure buffer is live
before retrieving underline properties from it (Bug#38038).
* doc/lispref/display.texi (Fringe Size/Pos): Document new
argument PERSISTENT of 'set-window-fringes'.
(Scroll Bars): Document new argument PERSISTENT of
'set-window-scroll-bars'. Mention that HORIZONTAL-TYPE must
be 'bottom' to show a horizontal scroll bar on mini windows.
* lisp/window.el (window-min-pixel-height): For mini windows the
minimum height is one line.
(window--min-size-1): Use value returned by
'window-min-pixel-height' when dealing with mini windows.
(window--resize-mini-window): Try to handle horizontal scroll
bars and size restrictions more accurately.
(window--state-put-2): Handle persistence of scroll bar
settings.
* src/frame.c (make_frame): Allow horizontal scroll bars in
mini windows.
(adjust_frame_size): Drop PIXELWISE argument in
'resize_frame_windows' calls.
* src/window.c (set_window_buffer): Don't override WINDOW's
scroll bar and fringe settings when marked as persistent.
(resize_frame_windows): Drop fourth argument PIXELWISE - SIZE
is always specified in terms of pixels. Try to handle height
of mini windows more accurately.
(grow_mini_window, shrink_mini_window): Use body height of
mini window when calculating expected height change. Take
horizontal scroll bars into account.
(struct saved_window): Two new members to handle persistence
of window fringes and scroll bars.
(Fset_window_configuration, save_window_save): Handle
persistence of fringes and scroll bars.
(set_window_fringes, set_window_scroll_bars): New arguments
PERSISTENT. Make dimension checks more accurate.
(Fset_window_fringes): New argument PERSISTENT.
(Fwindow_fringes, Fwindow_scroll_bars): Add PERSISTENT to
return values.
(Fset_window_scroll_bars): New argument PERSISTENT. In
doc-string mention that 'bottom' must be specified to get a
horizontal scroll bar in mini windows.
(compare_window_configurations): Add checks for persistence of
fringes and scroll bars.
* src/window.h (struct window): New boolean slots
'fringes_persistent' and 'scroll_bars_persistent'.
(WINDOW_HAS_HORIZONTAL_SCROLL_BAR): Allow horizontal scroll bars
for mini windows.
(resize_frame_windows): Remove fourth argument of
'resize_frame_windows' in external declaration.
* src/xdisp.c (resize_mini_window): Use box text height to
tell whether mini window height changed.
(set_horizontal_scroll_bar): Set mini window's horizontal
scroll bar when its type is specified as 'bottom'.
* etc/NEWS: Mention new options for 'set-window-fringes' and
'set-window-scroll-bars'.
Problem reported by Keith David Bershatsky in:
https://lists.gnu.org/r/emacs-devel/2019-04/msg00259.html
Solution suggested by Stefan Monnier in:
https://lists.gnu.org/r/emacs-devel/2019-04/msg00282.html
* src/buffer.h (BUFFER_LISP_SIZE): Simplify by using PSEUDOVECSIZE.
(BUFFER_REST_SIZE): Simplify by using VECSIZE and BUFFER_LISP_SIZE.
* src/lisp.h (PSEUDOVECSIZE): Base it on the last Lisp field,
not the first non-Lisp field. All callers changed. Callers
without Lisp fields changed to use ALLOCATE_PLAIN_PSEUDOVECTOR.
(ALLOCATE_PLAIN_PSEUDOVECTOR): New macro.