commit 9b34005c32462a3e0e8a201e3b0d52a67a84d7bd (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Sun Mar 20 15:00:36 2022 +0800 Improve compliance with version 5 of the XDND specification * src/xterm.c (x_dnd_cleanup_drag_and_drop): New function. (x_dnd_begin_drag_and_drop): Handle selection request events immediately. (handle_one_xevent): Wait for XdndFinished events and return the action chosen there. diff --git a/src/xterm.c b/src/xterm.c index 01840569fe..98888414d5 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -788,6 +788,9 @@ static void x_scroll_bar_end_update (struct x_display_info *, struct scroll_bar #endif static bool x_dnd_in_progress; +static bool x_dnd_waiting_for_finish; +static Window x_dnd_pending_finish_target; +static int x_dnd_waiting_for_finish_proto; /* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'. @@ -809,6 +812,9 @@ static Atom x_dnd_wanted_action; static Atom *x_dnd_targets = NULL; static int x_dnd_n_targets; static struct frame *x_dnd_frame; +static XWindowAttributes x_dnd_old_window_attrs; +static XIC x_dnd_old_ic; +static bool x_dnd_unwind_flag; #define X_DND_SUPPORTED_VERSION 5 @@ -1145,6 +1151,47 @@ x_set_dnd_targets (Atom *targets, int ntargets) x_dnd_n_targets = ntargets; } +static void +x_dnd_cleanup_drag_and_drop (void *frame) +{ + struct frame *f = frame; + + if (!x_dnd_unwind_flag) + return; + + if (x_dnd_in_progress) + { + eassert (x_dnd_frame); + + block_input (); + if (x_dnd_last_seen_window != None + && x_dnd_last_protocol_version != -1) + x_dnd_send_leave (x_dnd_frame, + x_dnd_last_seen_window); + unblock_input (); + + x_dnd_in_progress = false; + x_set_dnd_targets (NULL, 0); + } + + FRAME_DISPLAY_INFO (f)->grabbed = 0; +#ifdef USE_GTK + current_hold_quit = NULL; +#endif +#ifdef HAVE_X_I18N + FRAME_XIC (f) = x_dnd_old_ic; +#endif + + block_input (); + /* Restore the old event mask. */ + XSelectInput (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->root_window, + x_dnd_old_window_attrs.your_event_mask); + unblock_input (); + + x_dnd_frame = NULL; +} + Lisp_Object x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, bool return_frame_p) @@ -1161,6 +1208,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, struct input_event hold_quit; char *atom_name; Lisp_Object action, ltimestamp; + specpdl_ref ref; if (!FRAME_VISIBLE_P (f)) error ("Frame is invisible"); @@ -1187,6 +1235,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, x_dnd_action = None; x_dnd_wanted_action = xaction; x_dnd_return_frame = 0; + x_dnd_waiting_for_finish = false; if (return_frame_p) x_dnd_return_frame = 1; @@ -1215,7 +1264,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, Otherwise, the ibus XIM server gets very confused. */ FRAME_XIC (f) = NULL; #endif - while (x_dnd_in_progress) + while (x_dnd_in_progress || x_dnd_waiting_for_finish) { hold_quit.kind = NO_EVENT; #ifdef USE_GTK @@ -1234,6 +1283,20 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, if (hold_quit.kind != NO_EVENT) { + if (hold_quit.kind == SELECTION_REQUEST_EVENT) + { + x_dnd_old_ic = ic; + x_dnd_old_window_attrs = root_window_attrs; + x_dnd_unwind_flag = true; + + ref = SPECPDL_INDEX (); + record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f); + x_handle_selection_event ((struct selection_input_event *) &hold_quit); + x_dnd_unwind_flag = false; + unbind_to (ref, Qnil); + continue; + } + if (x_dnd_in_progress) { if (x_dnd_last_seen_window != None @@ -10771,6 +10834,20 @@ handle_one_xevent (struct x_display_info *dpyinfo, } } + if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished + && x_dnd_waiting_for_finish + && event->xclient.data.l[0] == x_dnd_pending_finish_target) + { + x_dnd_waiting_for_finish = false; + + if (x_dnd_waiting_for_finish_proto >= 5) + x_dnd_wanted_action = event->xclient.data.l[2]; + + if (x_dnd_waiting_for_finish_proto >= 5 + && !(event->xclient.data.l[1] & 1)) + x_dnd_wanted_action = None; + } + if (event->xclient.message_type == dpyinfo->Xatom_wm_protocols && event->xclient.format == 32) { @@ -11055,6 +11132,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, SELECTION_EVENT_TARGET (&inev.sie) = eventp->target; SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property; SELECTION_EVENT_TIME (&inev.sie) = eventp->time; + + /* If drag-and-drop is in progress, handle SelectionRequest + events immediately, by setting hold_quit to the input + event. */ + + if (x_dnd_in_progress || x_dnd_waiting_for_finish) + { + *hold_quit = inev.ie; + EVENT_INIT (inev.ie); + } } break; @@ -12341,9 +12428,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (x_dnd_last_seen_window != None && x_dnd_last_protocol_version != -1) - x_dnd_send_drop (x_dnd_frame, x_dnd_last_seen_window, - x_dnd_selection_timestamp, - x_dnd_last_protocol_version); + { + x_dnd_waiting_for_finish = true; + x_dnd_pending_finish_target = x_dnd_last_seen_window; + x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version; + + x_dnd_send_drop (x_dnd_frame, x_dnd_last_seen_window, + x_dnd_selection_timestamp, + x_dnd_last_protocol_version); + } x_dnd_last_protocol_version = -1; x_dnd_last_seen_window = None; @@ -13320,9 +13413,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (x_dnd_last_seen_window != None && x_dnd_last_protocol_version != -1) - x_dnd_send_drop (x_dnd_frame, x_dnd_last_seen_window, - x_dnd_selection_timestamp, - x_dnd_last_protocol_version); + { + x_dnd_waiting_for_finish = true; + x_dnd_pending_finish_target = x_dnd_last_seen_window; + x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version; + + x_dnd_send_drop (x_dnd_frame, x_dnd_last_seen_window, + x_dnd_selection_timestamp, + x_dnd_last_protocol_version); + } x_dnd_last_protocol_version = -1; x_dnd_last_seen_window = None; commit 34ac8088b002e59e943471c4b39c368aebaca45c Author: Po Lu Date: Sun Mar 20 05:53:30 2022 +0000 Fix some crashes in shut_down_emacs on Haiku * src/emacs.c (shut_down_emacs): Stop quitting be app, since it's not always there. diff --git a/src/emacs.c b/src/emacs.c index 0ff916b18b..2a4dcc2c2c 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -2818,9 +2818,6 @@ shut_down_emacs (int sig, Lisp_Object stuff) /* Don't update display from now on. */ Vinhibit_redisplay = Qt; -#ifdef HAVE_HAIKU - be_app_quit (); -#endif /* If we are controlling the terminal, reset terminal modes. */ #ifndef DOS_NT pid_t tpgrp = tcgetpgrp (STDIN_FILENO); commit a232a8a22c6a228d871ff8df7cd25b0cabe3e5fb Author: Po Lu Date: Sun Mar 20 05:51:19 2022 +0000 Implement `haiku_delete_terminal' * src/haikuterm.c (haiku_delete_terminal): Actually delete the terminal instead of aborting. diff --git a/src/haikuterm.c b/src/haikuterm.c index 4ae64129ef..221bdfd2ee 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -115,7 +115,25 @@ haiku_toolkit_position (struct frame *f, int x, int y, static void haiku_delete_terminal (struct terminal *terminal) { - emacs_abort (); + struct haiku_display_info *dpyinfo = terminal->display_info.haiku; + struct terminal *t; + + if (!terminal->name) + return; + + block_input (); + be_app_quit (); + + /* Close all frames and delete the generic struct terminal. */ + for (t = terminal_list; t; t = t->next_terminal) + { + if (t->type == output_haiku && t->display_info.haiku == dpyinfo) + { + delete_terminal (t); + break; + } + } + unblock_input (); } static const char * commit b19b9cbe514a8b75ec20e0056cba91b465057614 Author: Po Lu Date: Sun Mar 20 12:51:46 2022 +0800 Check list tail properly in x-begin-drag * src/xfns.c (Fx_begin_drag): Check that TARGETS is actually a proper list. * src/xterm.c (x_dnd_update_state): Remove debugging code. diff --git a/src/xfns.c b/src/xfns.c index b5d0b2c54e..9d30f2adee 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -6620,10 +6620,11 @@ instead. */) int ntargets = 0; char *target_names[2048]; Atom *target_atoms; - Lisp_Object lval; + Lisp_Object lval, original; Atom xaction; CHECK_LIST (targets); + original = targets; for (; CONSP (targets); targets = XCDR (targets)) { @@ -6638,6 +6639,8 @@ instead. */) error ("Too many targets"); } + CHECK_LIST_END (targets, original); + if (NILP (action) || EQ (action, QXdndActionCopy)) xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionCopy; else if (EQ (action, QXdndActionMove)) diff --git a/src/xterm.c b/src/xterm.c index 3e7b51e4db..01840569fe 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -10606,8 +10606,6 @@ x_dnd_update_state (struct x_display_info *dpyinfo) unsigned int dummy_mask; Window dummy, dummy_child, target; - puts ("us"); - if (XQueryPointer (dpyinfo->display, dpyinfo->root_window, &dummy, &dummy_child, commit 629ac0803f29dcc9b5be5f704c0892b121f6adf5 Author: Po Lu Date: Sun Mar 20 11:23:11 2022 +0800 Fix crash on some compositing managers * src/xterm.c (x_dnd_get_target_window): Catch errors around CompositeReleaseOverlayWindow. diff --git a/src/xterm.c b/src/xterm.c index 3e888407b3..3e7b51e4db 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -911,27 +911,34 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, if (XGetSelectionOwner (dpyinfo->display, dpyinfo->Xatom_NET_WM_CM_Sn) != None) { + x_catch_errors (dpyinfo->display); overlay_window = XCompositeGetOverlayWindow (dpyinfo->display, dpyinfo->root_window); XCompositeReleaseOverlayWindow (dpyinfo->display, dpyinfo->root_window); - XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs); - - if (attrs.map_state == IsViewable) + if (!x_had_errors_p (dpyinfo->display)) { - proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window); + XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs); - if (proxy != None) + if (attrs.map_state == IsViewable) { - proto = x_dnd_get_window_proto (dpyinfo, proxy); + proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window); - if (proto != -1) + if (proxy != None) { - *proto_out = proto; - return proxy; + proto = x_dnd_get_window_proto (dpyinfo, proxy); + + if (proto != -1) + { + *proto_out = proto; + x_uncatch_errors_after_check (); + + return proxy; + } } } } + x_uncatch_errors_after_check (); } } commit 77f5eb874b70ab78ca4daf3adf30f18d002db439 Author: Po Lu Date: Sun Mar 20 09:53:52 2022 +0800 Improve behaviour of drag-n-drop during window manager operations * src/xterm.c (x_dnd_begin_drag_and_drop): Select for some events on the root window. (x_dnd_update_state): New function. (handle_one_xevent): Call that function when we get some events from the root window substructure or the window manager. (x_term_init): New atom `_NET_CLIENT_LIST_STACKING'. * src/xterm.h (struct x_display_info): New atom `_NET_CLIENT_LIST_STACKING'. diff --git a/src/xterm.c b/src/xterm.c index 4f8accbda3..3e888407b3 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1149,6 +1149,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, #ifdef HAVE_X_I18N XIC ic = FRAME_XIC (f); #endif + XWindowAttributes root_window_attrs; struct input_event hold_quit; char *atom_name; @@ -1187,7 +1188,21 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, current_count = 0; #endif + /* Now select for SubstructureNotifyMask and PropertyNotifyMask on + the root window, so we can get notified when window stacking + changes, a common operation during drag-and-drop. */ + block_input (); + XGetWindowAttributes (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->root_window, + &root_window_attrs); + + XSelectInput (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->root_window, + root_window_attrs.your_event_mask + | SubstructureNotifyMask + | PropertyChangeMask); + #ifdef HAVE_X_I18N /* Make sure no events get filtered when XInput 2 is enabled. Otherwise, the ibus XIM server gets very confused. */ @@ -1230,6 +1245,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, #ifdef HAVE_X_I18N FRAME_XIC (f) = ic; #endif + /* Restore the old event mask. */ + XSelectInput (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->root_window, + root_window_attrs.your_event_mask); unblock_input (); quit (); } @@ -1243,6 +1262,11 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, current_hold_quit = NULL; #endif + /* Restore the old event mask. */ + XSelectInput (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->root_window, + root_window_attrs.your_event_mask); + unblock_input (); if (x_dnd_return_frame == 3) @@ -10566,6 +10590,74 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc) } } +/* Get the window underneath the pointer, see if it moved, and update + the DND state accordingly. */ +static void +x_dnd_update_state (struct x_display_info *dpyinfo) +{ + int root_x, root_y, dummy_x, dummy_y, target_proto; + unsigned int dummy_mask; + Window dummy, dummy_child, target; + + puts ("us"); + + if (XQueryPointer (dpyinfo->display, + dpyinfo->root_window, + &dummy, &dummy_child, + &root_x, &root_y, + &dummy_x, &dummy_y, + &dummy_mask)) + { + target = x_dnd_get_target_window (dpyinfo, root_x, + root_y, &target_proto); + + if (target != x_dnd_last_seen_window) + { + if (x_dnd_last_seen_window != None + && x_dnd_last_protocol_version != -1 + && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) + x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); + + if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame) + && x_dnd_return_frame == 1) + x_dnd_return_frame = 2; + + if (x_dnd_return_frame == 2 + && x_any_window_to_frame (dpyinfo, target)) + { + x_dnd_in_progress = false; + x_dnd_return_frame_object + = x_any_window_to_frame (dpyinfo, target); + x_dnd_return_frame = 3; + } + + x_dnd_last_seen_window = target; + x_dnd_last_protocol_version = target_proto; + + if (target != None && x_dnd_last_protocol_version != -1) + x_dnd_send_enter (x_dnd_frame, target, + x_dnd_last_protocol_version); + } + + if (x_dnd_last_protocol_version != -1 && target != None) + x_dnd_send_position (x_dnd_frame, target, + x_dnd_last_protocol_version, + root_x, root_y, x_dnd_selection_timestamp, + dpyinfo->Xatom_XdndActionCopy); + } + /* The pointer moved out of the screen. */ + else if (x_dnd_last_protocol_version) + { + if (x_dnd_last_seen_window != None + && x_dnd_last_protocol_version != -1) + x_dnd_send_leave (x_dnd_frame, + x_dnd_last_seen_window); + + x_dnd_in_progress = false; + x_dnd_frame = NULL; + } +} + /* Handles the XEvent EVENT on display DPYINFO. *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. @@ -11006,6 +11098,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, } } + if (event->xproperty.window == dpyinfo->root_window + && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking + || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop) + && x_dnd_in_progress) + x_dnd_update_state (dpyinfo); + x_handle_property_notify (&event->xproperty); xft_settings_event (dpyinfo, event); goto OTHER; @@ -11219,6 +11317,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (xg_is_menu_window (dpyinfo->display, event->xmap.window)) popup_activated_flag = 1; #endif + + if (x_dnd_in_progress) + x_dnd_update_state (dpyinfo); /* We use x_top_window_to_frame because map events can come for sub-windows and they don't mean that the frame is visible. */ @@ -12181,6 +12282,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif } + + if (x_dnd_in_progress) + x_dnd_update_state (dpyinfo); goto OTHER; case ButtonRelease: @@ -12460,6 +12564,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, break; case CirculateNotify: + if (x_dnd_in_progress) + x_dnd_update_state (dpyinfo); goto OTHER; case CirculateRequest: @@ -18801,6 +18907,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn) ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time) ATOM_REFS_INIT ("_NET_WM_USER_TIME_WINDOW", Xatom_net_wm_user_time_window) + ATOM_REFS_INIT ("_NET_CLIENT_LIST_STACKING", Xatom_net_client_list_stacking) /* Session management */ ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) diff --git a/src/xterm.h b/src/xterm.h index ed612c3c1e..2a11f87e16 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -550,7 +550,7 @@ struct x_display_info Xatom_net_workarea, Xatom_net_wm_opaque_region, Xatom_net_wm_ping, Xatom_net_wm_sync_request, Xatom_net_wm_sync_request_counter, Xatom_net_wm_frame_drawn, Xatom_net_wm_user_time, - Xatom_net_wm_user_time_window; + Xatom_net_wm_user_time_window, Xatom_net_client_list_stacking; /* XSettings atoms and windows. */ Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; commit d2ac7447db52f492f9cbb52566de2e452c8bc65d Merge: 6887bf555f ccf4a4fa48 Author: Eli Zaretskii Date: Sat Mar 19 22:18:47 2022 +0200 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit ccf4a4fa482f61938a9495c862b74f4a2d3ade0c Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Port to gcc -D EMACS_EXTERN_INLINE * src/comp.h, src/thread.h: Add INLINE_HEADER_BEGIN and INLINE_HEADER_END, since it uses INLINE. * src/emacs.c: Include these two files. diff --git a/src/comp.h b/src/comp.h index 40f1e9b979..da53f32971 100644 --- a/src/comp.h +++ b/src/comp.h @@ -53,6 +53,8 @@ struct Lisp_Native_Comp_Unit #ifdef HAVE_NATIVE_COMP +INLINE_HEADER_BEGIN + INLINE bool NATIVE_COMP_UNITP (Lisp_Object a) { @@ -99,6 +101,8 @@ void unload_comp_unit (struct Lisp_Native_Comp_Unit *cu) extern void syms_of_comp (void); +INLINE_HEADER_END + #endif /* #ifdef HAVE_NATIVE_COMP */ #endif /* #ifndef COMP_H */ diff --git a/src/emacs.c b/src/emacs.c index d1060bca0b..0ff916b18b 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -140,6 +140,10 @@ extern char etext; #include "fingerprint.h" #include "epaths.h" +/* Include these only because of INLINE. */ +#include "comp.h" +#include "thread.h" + static const char emacs_version[] = PACKAGE_VERSION; static const char emacs_copyright[] = COPYRIGHT; static const char emacs_bugreport[] = PACKAGE_BUGREPORT; diff --git a/src/thread.h b/src/thread.h index ddba1a2d99..b34ca3d57c 100644 --- a/src/thread.h +++ b/src/thread.h @@ -33,6 +33,8 @@ along with GNU Emacs. If not, see . */ #include "sysselect.h" /* FIXME */ #include "systhread.h" +INLINE_HEADER_BEGIN + /* Byte-code interpreter thread state. */ struct bc_thread_state { struct bc_frame *fp; /* current frame pointer */ @@ -194,6 +196,8 @@ struct thread_state struct bc_thread_state bc; } GCALIGNED_STRUCT; +INLINE_HEADER_BEGIN + INLINE bool THREADP (Lisp_Object a) { @@ -315,4 +319,6 @@ int thread_select (select_func *func, int max_fds, fd_set *rfds, bool thread_check_current_buffer (struct buffer *); +INLINE_HEADER_END + #endif /* THREAD_H */ commit c11b4758b7bd971fcbb824638a06f52c7768d268 Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 valid_sp inline fix * src/bytecode.c (valid_sp): static, not INLINE, as INLINE should be used only in headers and between INLINE_HEADER_BEGIN and INLINE_HEADER_END. No need for ‘inline’ here. diff --git a/src/bytecode.c b/src/bytecode.c index ed1f6ca4a8..6246498616 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -452,7 +452,7 @@ DEFUN ("internal-stack-stats", Finternal_stack_stats, Sinternal_stack_stats, } /* Whether a stack pointer is valid in the current frame. */ -INLINE bool +static bool valid_sp (struct bc_thread_state *bc, Lisp_Object *sp) { struct bc_frame *fp = bc->fp; commit 495d8519ca030de4367be14f703c44855c2186dd Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Simplify alloc.c static function decls * src/alloc.c: Omit unnecessary static function declarations. Don’t use ‘inline static’ as the C standard says that keyword order is obsolescent. Anyway, no need for ‘inline’ as compilers inline without it well enough. diff --git a/src/alloc.c b/src/alloc.c index b0fbc91fe5..b06dd943ba 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -445,26 +445,11 @@ static void compact_small_strings (void); static void free_large_strings (void); extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; -/* Forward declare mark accessor functions: they're used all over the - place. */ - -inline static bool vector_marked_p (const struct Lisp_Vector *v); -inline static void set_vector_marked (struct Lisp_Vector *v); - -inline static bool vectorlike_marked_p (const union vectorlike_header *v); -inline static void set_vectorlike_marked (union vectorlike_header *v); - -inline static bool cons_marked_p (const struct Lisp_Cons *c); -inline static void set_cons_marked (struct Lisp_Cons *c); - -inline static bool string_marked_p (const struct Lisp_String *s); -inline static void set_string_marked (struct Lisp_String *s); - -inline static bool symbol_marked_p (const struct Lisp_Symbol *s); -inline static void set_symbol_marked (struct Lisp_Symbol *s); - -inline static bool interval_marked_p (INTERVAL i); -inline static void set_interval_marked (INTERVAL i); +static bool vector_marked_p (struct Lisp_Vector const *); +static bool vectorlike_marked_p (union vectorlike_header const *); +static void set_vectorlike_marked (union vectorlike_header *); +static bool interval_marked_p (INTERVAL); +static void set_interval_marked (INTERVAL); /* When scanning the C stack for live Lisp objects, Emacs keeps track of what memory allocated via lisp_malloc and lisp_align_malloc is intended commit c386f7e825b425c9f80f8bb42ce329c127aa4d62 Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Make native helper functions static These don’t need to be extern, even with -flto, since their addresses are taken. * src/comp.c (helper_unwind_protect, helper_unbind_n) (helper_save_restriction, helper_GET_SYMBOL_WITH_POSITION) (helper_PSEUDOVECTOR_TYPEP_XUNTAG): Now static. diff --git a/src/comp.c b/src/comp.c index d0173491a2..50f92fe2cf 100644 --- a/src/comp.c +++ b/src/comp.c @@ -664,11 +664,12 @@ typedef struct { Helper functions called by the run-time. */ -void helper_unwind_protect (Lisp_Object handler); -Lisp_Object helper_unbind_n (Lisp_Object n); -void helper_save_restriction (void); -bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code); -struct Lisp_Symbol_With_Pos *helper_GET_SYMBOL_WITH_POSITION (Lisp_Object a); +static void helper_unwind_protect (Lisp_Object); +static Lisp_Object helper_unbind_n (Lisp_Object); +static void helper_save_restriction (void); +static bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object, enum pvec_type); +static struct Lisp_Symbol_With_Pos * +helper_GET_SYMBOL_WITH_POSITION (Lisp_Object); /* Note: helper_link_table must match the list created by `declare_runtime_imported_funcs'. */ @@ -4973,7 +4974,7 @@ unknown (before GCC version 10). */) /* for laziness. Change this if a performance impact is measured. */ /******************************************************************************/ -void +static void helper_unwind_protect (Lisp_Object handler) { /* Support for a function here is new in 24.4. */ @@ -4981,20 +4982,20 @@ helper_unwind_protect (Lisp_Object handler) handler); } -Lisp_Object +static Lisp_Object helper_unbind_n (Lisp_Object n) { return unbind_to (specpdl_ref_add (SPECPDL_INDEX (), -XFIXNUM (n)), Qnil); } -void +static void helper_save_restriction (void) { record_unwind_protect (save_restriction_restore, save_restriction_save ()); } -bool +static bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code) { return PSEUDOVECTOR_TYPEP (XUNTAG (a, Lisp_Vectorlike, @@ -5002,7 +5003,7 @@ helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code) code); } -struct Lisp_Symbol_With_Pos * +static struct Lisp_Symbol_With_Pos * helper_GET_SYMBOL_WITH_POSITION (Lisp_Object a) { if (!SYMBOL_WITH_POS_P (a)) commit 0fed5610426e141b057fc359ab9a86b3ac7e9df5 Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Remove unused fns/data and make fns static * src/comp.c (saved_sigset, helper_temp_output_buffer_setup): Remove; unused. * src/comp.c (logfile, helper_link_table): * src/fns.c (hashfn_equal, hashfn_eql): * src/frame.c (frame_windows_min_size): * src/gnutls.c (emacs_gnutls_global_init): * src/minibuf.c (Vcommand_loop_level_list): * src/syntax.c (syntax_code_spec): * src/timefns.c (time_overflow): * src/xterm.c (x_xrender_color_from_gc_foreground) (x_display_set_last_user_time): Now static, since it’s not used elsewhere. * src/xterm.c (x_xrender_color_from_gc_foreground) (x_xrender_color_from_gc_background): Move earlier to avoid forward use. (x_xrender_color_from_gc_foreground): Do not define unless !defined USE_CAIRO && (RENDER_MAJOR > 0 || RENDER_MINOR >= 2), since it’s not used otherwise. diff --git a/src/comp.c b/src/comp.c index ef9dcf1527..d0173491a2 100644 --- a/src/comp.c +++ b/src/comp.c @@ -516,8 +516,6 @@ typedef struct { ptrdiff_t size; } f_reloc_t; -sigset_t saved_sigset; - static f_reloc_t freloc; #define NUM_CAST_TYPES 15 @@ -648,7 +646,7 @@ typedef struct { static comp_t comp; -FILE *logfile = NULL; +static FILE *logfile; /* This is used for serialized objects by the reload mechanism. */ typedef struct { @@ -667,7 +665,6 @@ typedef struct { */ void helper_unwind_protect (Lisp_Object handler); -Lisp_Object helper_temp_output_buffer_setup (Lisp_Object x); Lisp_Object helper_unbind_n (Lisp_Object n); void helper_save_restriction (void); bool helper_PSEUDOVECTOR_TYPEP_XUNTAG (Lisp_Object a, enum pvec_type code); @@ -675,7 +672,7 @@ struct Lisp_Symbol_With_Pos *helper_GET_SYMBOL_WITH_POSITION (Lisp_Object a); /* Note: helper_link_table must match the list created by `declare_runtime_imported_funcs'. */ -void *helper_link_table[] = +static void *helper_link_table[] = { wrong_type_argument, helper_PSEUDOVECTOR_TYPEP_XUNTAG, pure_write_error, @@ -4984,14 +4981,6 @@ helper_unwind_protect (Lisp_Object handler) handler); } -Lisp_Object -helper_temp_output_buffer_setup (Lisp_Object x) -{ - CHECK_STRING (x); - temp_output_buffer_setup (SSDATA (x)); - return Vstandard_output; -} - Lisp_Object helper_unbind_n (Lisp_Object n) { diff --git a/src/fns.c b/src/fns.c index 4caf8448f1..0cc0c0a53d 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4214,7 +4214,7 @@ hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h) /* Ignore HT and return a hash code for KEY which uses 'equal' to compare keys. The hash code is at most INTMASK. */ -Lisp_Object +static Lisp_Object hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h) { return make_ufixnum (sxhash (key)); @@ -4223,7 +4223,7 @@ hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h) /* Ignore HT and return a hash code for KEY which uses 'eql' to compare keys. The hash code is at most INTMASK. */ -Lisp_Object +static Lisp_Object hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h) { return (FLOATP (key) || BIGNUMP (key) ? hashfn_equal : hashfn_eq) (key, h); diff --git a/src/frame.c b/src/frame.c index 0ec7057db2..8f8df8f8e0 100644 --- a/src/frame.c +++ b/src/frame.c @@ -335,7 +335,7 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size, * additionally limit the minimum frame height to a value large enough * to support menu bar, tab bar, mode line and echo area. */ -int +static int frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise) { diff --git a/src/frame.h b/src/frame.h index 5d5f2122fb..61df57e966 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1338,8 +1338,6 @@ extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object); extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object); extern Lisp_Object mouse_position (bool); -extern int frame_windows_min_size (Lisp_Object, Lisp_Object, Lisp_Object, - Lisp_Object); extern void frame_size_history_plain (struct frame *, Lisp_Object); extern void frame_size_history_extra (struct frame *, Lisp_Object, int, int, int, int, int, int); diff --git a/src/gnutls.c b/src/gnutls.c index 09590ca005..0e1e63e157 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -1521,7 +1521,7 @@ returned as the :certificate entry. */) /* Initialize global GnuTLS state to defaults. Call 'gnutls-global-deinit' when GnuTLS usage is no longer needed. Return zero on success. */ -Lisp_Object +static Lisp_Object emacs_gnutls_global_init (void) { int ret = GNUTLS_E_SUCCESS; diff --git a/src/gnutls.h b/src/gnutls.h index 791e5340c2..19d3d3f5bc 100644 --- a/src/gnutls.h +++ b/src/gnutls.h @@ -90,7 +90,6 @@ extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err); extern int w32_gnutls_rnd (gnutls_rnd_level_t, void *, size_t); #endif extern Lisp_Object emacs_gnutls_deinit (Lisp_Object); -extern Lisp_Object emacs_gnutls_global_init (void); extern int gnutls_try_handshake (struct Lisp_Process *p); extern Lisp_Object gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist); diff --git a/src/lisp.h b/src/lisp.h index bd3cdd5307..9599934c1f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3910,8 +3910,6 @@ extern void hexbuf_digest (char *, void const *, int); extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *); EMACS_UINT hash_string (char const *, ptrdiff_t); EMACS_UINT sxhash (Lisp_Object); -Lisp_Object hashfn_eql (Lisp_Object, struct Lisp_Hash_Table *); -Lisp_Object hashfn_equal (Lisp_Object, struct Lisp_Hash_Table *); Lisp_Object hashfn_user_defined (Lisp_Object, struct Lisp_Hash_Table *); Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float, Lisp_Object, bool); diff --git a/src/minibuf.c b/src/minibuf.c index 49a474dd49..97a6ec6901 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -41,7 +41,7 @@ along with GNU Emacs. If not, see . */ minibuffer recursions are encountered. */ Lisp_Object Vminibuffer_list; -Lisp_Object Vcommand_loop_level_list; +static Lisp_Object Vcommand_loop_level_list; /* Data to remember during recursive minibuffer invocations. */ diff --git a/src/syntax.c b/src/syntax.c index 13c36fdf3c..f9022d18d2 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -1074,7 +1074,7 @@ unsigned char const syntax_spec_code[0400] = /* Indexed by syntax code, give the letter that describes it. */ -char const syntax_code_spec[16] = +static char const syntax_code_spec[16] = { ' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>', '@', '!', '|' diff --git a/src/syntax.h b/src/syntax.h index c1bb9274d0..5949a95a73 100644 --- a/src/syntax.h +++ b/src/syntax.h @@ -147,10 +147,6 @@ extern bool syntax_prefix_flag_p (int c); extern unsigned char const syntax_spec_code[0400]; -/* Indexed by syntax code, give the letter that describes it. */ - -extern char const syntax_code_spec[16]; - /* Convert the byte offset BYTEPOS into a character position, for the object recorded in gl_state with SETUP_SYNTAX_TABLE_FOR_OBJECT. diff --git a/src/systime.h b/src/systime.h index 41d728f1c2..75088bd4a6 100644 --- a/src/systime.h +++ b/src/systime.h @@ -91,7 +91,6 @@ extern Lisp_Object timespec_to_lisp (struct timespec); extern bool list4_to_timespec (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, struct timespec *); extern struct timespec lisp_time_argument (Lisp_Object); -extern AVOID time_overflow (void); extern double float_time (Lisp_Object); extern void init_timefns (void); extern void syms_of_timefns (void); diff --git a/src/timefns.c b/src/timefns.c index 9b5b090ba7..9e8592d35a 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -342,7 +342,7 @@ init_timefns (void) } /* Report that a time value is out of range for Emacs. */ -void +static AVOID time_overflow (void) { error ("Specified time is not representable"); diff --git a/src/xterm.c b/src/xterm.c index fb0fc66ae5..4f8accbda3 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2339,6 +2339,68 @@ x_reset_clip_rectangles (struct frame *f, GC gc) #endif } +#ifdef HAVE_XRENDER +# if !defined USE_CAIRO && (RENDER_MAJOR > 0 || RENDER_MINOR >= 2) +static void +x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color, + bool apply_alpha_background) +{ + XGCValues xgcv; + XColor xc; + + XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv); + xc.pixel = xgcv.foreground; + x_query_colors (f, &xc, 1); + + color->alpha = (apply_alpha_background + ? 65535 * f->alpha_background + : 65535); + + if (color->alpha == 65535) + { + color->red = xc.red; + color->blue = xc.blue; + color->green = xc.green; + } + else + { + color->red = (xc.red * color->alpha) / 65535; + color->blue = (xc.blue * color->alpha) / 65535; + color->green = (xc.green * color->alpha) / 65535; + } +} +# endif + +void +x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color, + bool apply_alpha_background) +{ + XGCValues xgcv; + XColor xc; + + XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv); + xc.pixel = xgcv.background; + x_query_colors (f, &xc, 1); + + color->alpha = (apply_alpha_background + ? 65535 * f->alpha_background + : 65535); + + if (color->alpha == 65535) + { + color->red = xc.red; + color->blue = xc.blue; + color->green = xc.green; + } + else + { + color->red = (xc.red * color->alpha) / 65535; + color->blue = (xc.blue * color->alpha) / 65535; + color->green = (xc.green * color->alpha) / 65535; + } +} +#endif + static void x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height, bool respect_alpha_background) @@ -3299,7 +3361,7 @@ static void x_scroll_bar_clear (struct frame *); static void x_check_font (struct frame *, struct font *); #endif -void +static void x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time) { #ifndef USE_GTK @@ -19311,66 +19373,6 @@ init_xterm (void) } #endif -#ifdef HAVE_XRENDER -void -x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color, - bool apply_alpha_background) -{ - XGCValues xgcv; - XColor xc; - - XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv); - xc.pixel = xgcv.foreground; - x_query_colors (f, &xc, 1); - - color->alpha = (apply_alpha_background - ? 65535 * f->alpha_background - : 65535); - - if (color->alpha == 65535) - { - color->red = xc.red; - color->blue = xc.blue; - color->green = xc.green; - } - else - { - color->red = (xc.red * color->alpha) / 65535; - color->blue = (xc.blue * color->alpha) / 65535; - color->green = (xc.green * color->alpha) / 65535; - } -} - -void -x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color, - bool apply_alpha_background) -{ - XGCValues xgcv; - XColor xc; - - XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv); - xc.pixel = xgcv.background; - x_query_colors (f, &xc, 1); - - color->alpha = (apply_alpha_background - ? 65535 * f->alpha_background - : 65535); - - if (color->alpha == 65535) - { - color->red = xc.red; - color->blue = xc.blue; - color->green = xc.green; - } - else - { - color->red = (xc.red * color->alpha) / 65535; - color->blue = (xc.blue * color->alpha) / 65535; - color->green = (xc.green * color->alpha) / 65535; - } -} -#endif - void syms_of_xterm (void) { diff --git a/src/xterm.h b/src/xterm.h index 05d5e08dc0..ed612c3c1e 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1361,8 +1361,6 @@ extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t); #endif #ifdef HAVE_XRENDER -extern void x_xrender_color_from_gc_foreground (struct frame *, GC, - XRenderColor *, bool); extern void x_xrender_color_from_gc_background (struct frame *, GC, XRenderColor *, bool); extern void x_xr_ensure_picture (struct frame *f); @@ -1374,8 +1372,6 @@ extern void x_xr_reset_ext_clip (struct frame *f); extern void x_scroll_bar_configure (GdkEvent *); #endif -extern void x_display_set_last_user_time (struct x_display_info *, Time); - extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom, bool); extern void x_set_dnd_targets (Atom *, int); commit c3c5e50ba484eb849b9476ea9dba96a1a669be82 Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Use filenvercmp instead of doing it by hand * src/fns.c (Fstring_version_lessp): Use filenvercmp, not string_version_cmp. (string_version_cmp): Remove; no longer used. diff --git a/src/fns.c b/src/fns.c index 6e89fe3ca5..4caf8448f1 100644 --- a/src/fns.c +++ b/src/fns.c @@ -485,37 +485,9 @@ Symbols are also allowed; their print names are used instead. */) string2 = SYMBOL_NAME (string2); CHECK_STRING (string1); CHECK_STRING (string2); - return string_version_cmp (string1, string2) < 0 ? Qt : Qnil; -} - -/* Return negative, 0, positive if STRING1 is <, =, > STRING2 as per - string-version-lessp. */ -int -string_version_cmp (Lisp_Object string1, Lisp_Object string2) -{ - char *p1 = SSDATA (string1); - char *p2 = SSDATA (string2); - char *lim1 = p1 + SBYTES (string1); - char *lim2 = p2 + SBYTES (string2); - int cmp; - - while ((cmp = filevercmp (p1, p2)) == 0) - { - /* If the strings are identical through their first null bytes, - skip past identical prefixes and try again. */ - ptrdiff_t size = strlen (p1) + 1; - eassert (size == strlen (p2) + 1); - p1 += size; - p2 += size; - bool more1 = p1 <= lim1; - bool more2 = p2 <= lim2; - if (!more1) - return more2; - if (!more2) - return -1; - } - - return cmp; + int cmp = filenvercmp (SSDATA (string1), SBYTES (string1), + SSDATA (string2), SBYTES (string2)); + return cmp < 0 ? Qt : Qnil; } DEFUN ("string-collate-lessp", Fstring_collate_lessp, Sstring_collate_lessp, 2, 4, 0, diff --git a/src/lisp.h b/src/lisp.h index c5045d72ee..bd3cdd5307 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3927,7 +3927,6 @@ extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, extern Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object merge_c (Lisp_Object, Lisp_Object, bool (*) (Lisp_Object, Lisp_Object)); extern Lisp_Object do_yes_or_no_p (Lisp_Object); -extern int string_version_cmp (Lisp_Object, Lisp_Object); extern Lisp_Object concat2 (Lisp_Object, Lisp_Object); extern Lisp_Object concat3 (Lisp_Object, Lisp_Object, Lisp_Object); extern bool equal_no_quit (Lisp_Object, Lisp_Object); commit a5cbd983767c5b3e18e7b039795d036262b41958 Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Omit unnecessary code when !HAVE_NATIVE_COMP * src/decompress.c (MD5_BLOCKSIZE, acc_buf, acc_size) (accumulate_and_process_md5, final_process_md5, md5_gz_stream): * src/dynlib.c (dynlib_open_for_eln, dynlib_close) [!WINDOWSNT]: * src/fileio.c (internal_delete_file_1, internal_delete_file): Define only if HAVE_NATIVE_COMP && WINDOWSNT, as they’re not used otherwise. diff --git a/src/decompress.c b/src/decompress.c index ddd8abbf27..dbdc9104a3 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -67,8 +67,9 @@ init_zlib_functions (void) #endif /* WINDOWSNT */ +#ifdef HAVE_NATIVE_COMP -#define MD5_BLOCKSIZE 32768 /* From md5.c */ +# define MD5_BLOCKSIZE 32768 /* From md5.c */ static char acc_buff[2 * MD5_BLOCKSIZE]; static size_t acc_size; @@ -106,7 +107,7 @@ md5_gz_stream (FILE *source, void *resblock) unsigned char in[MD5_BLOCKSIZE]; unsigned char out[MD5_BLOCKSIZE]; -#ifdef WINDOWSNT +# ifdef WINDOWSNT if (!zlib_initialized) zlib_initialized = init_zlib_functions (); if (!zlib_initialized) @@ -114,7 +115,7 @@ md5_gz_stream (FILE *source, void *resblock) message1 ("zlib library not found"); return -1; } -#endif +# endif eassert (!acc_size); @@ -164,7 +165,8 @@ md5_gz_stream (FILE *source, void *resblock) return 0; } -#undef MD5_BLOCKSIZE +# undef MD5_BLOCKSIZE +#endif diff --git a/src/dynlib.c b/src/dynlib.c index 8cb9a23374..e2c71f1448 100644 --- a/src/dynlib.c +++ b/src/dynlib.c @@ -279,11 +279,13 @@ dynlib_open (const char *path) return dlopen (path, RTLD_LAZY | RTLD_GLOBAL); } +# ifdef HAVE_NATIVE_COMP dynlib_handle_ptr dynlib_open_for_eln (const char *path) { return dlopen (path, RTLD_LAZY); } +# endif void * dynlib_sym (dynlib_handle_ptr h, const char *sym) @@ -313,11 +315,13 @@ dynlib_error (void) return dlerror (); } +# ifdef HAVE_NATIVE_COMP int dynlib_close (dynlib_handle_ptr h) { return dlclose (h) == 0; } +# endif #else diff --git a/src/fileio.c b/src/fileio.c index a0282204de..5d66a93ac6 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2505,6 +2505,8 @@ With a prefix argument, TRASH is nil. */) return Qnil; } +#if defined HAVE_NATIVE_COMP && defined WINDOWSNT + static Lisp_Object internal_delete_file_1 (Lisp_Object ignore) { @@ -2523,6 +2525,8 @@ internal_delete_file (Lisp_Object filename) Qt, internal_delete_file_1); return NILP (tem); } + +#endif /* Return -1 if FILE is a case-insensitive file name, 0 if not, and a positive errno value if the result cannot be determined. */ commit abfb76732c7fd321e5662f9885c301833b3281a7 Author: Paul Eggert Date: Sat Mar 19 12:35:04 2022 -0700 Remove internal_condition_case_[345] * src/comp.c (directory_files_matching) [WINDOWSNT]: New function. (eln_load_path_final_clean_up) [WINDOWSNT]: Use it. This removes the need for internal_condition_case_5. * src/eval.c (internal_condition_case_3) (internal_condition_case_4, internal_condition_case_5): Remove. The first two were never used; the last only in now-removed code. diff --git a/src/comp.c b/src/comp.c index 499eee7e70..ef9dcf1527 100644 --- a/src/comp.c +++ b/src/comp.c @@ -5032,6 +5032,12 @@ return_nil (Lisp_Object arg) { return Qnil; } + +static Lisp_Object +directory_files_matching (Lisp_Object name, Lisp_Object match) +{ + return Fdirectory_files (name, Qt, match, Qnil, Qnil); +} #endif /* Windows does not let us delete a .eln file that is currently loaded @@ -5049,11 +5055,11 @@ eln_load_path_final_clean_up (void) FOR_EACH_TAIL (dir_tail) { Lisp_Object files_in_dir = - internal_condition_case_5 (Fdirectory_files, + internal_condition_case_2 (directory_files_matching, Fexpand_file_name (Vcomp_native_version_dir, XCAR (dir_tail)), - Qt, build_string ("\\.eln\\.old\\'"), Qnil, - Qnil, Qt, return_nil); + build_string ("\\.eln\\.old\\'"), + Qt, return_nil); FOR_EACH_TAIL (files_in_dir) internal_delete_file (XCAR (files_in_dir)); } diff --git a/src/eval.c b/src/eval.c index c46b74ac40..39c328ea1f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1501,90 +1501,6 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), } } -/* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3 as - its arguments. */ - -Lisp_Object -internal_condition_case_3 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object, - Lisp_Object), - Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, - Lisp_Object handlers, - Lisp_Object (*hfun) (Lisp_Object)) -{ - struct handler *c = push_handler (handlers, CONDITION_CASE); - if (sys_setjmp (c->jmp)) - { - Lisp_Object val = handlerlist->val; - clobbered_eassert (handlerlist == c); - handlerlist = handlerlist->next; - return hfun (val); - } - else - { - Lisp_Object val = bfun (arg1, arg2, arg3); - eassert (handlerlist == c); - handlerlist = c->next; - return val; - } -} - -/* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as - its arguments. */ - -Lisp_Object -internal_condition_case_4 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object, - Lisp_Object, Lisp_Object), - Lisp_Object arg1, Lisp_Object arg2, - Lisp_Object arg3, Lisp_Object arg4, - Lisp_Object handlers, - Lisp_Object (*hfun) (Lisp_Object)) -{ - struct handler *c = push_handler (handlers, CONDITION_CASE); - if (sys_setjmp (c->jmp)) - { - Lisp_Object val = handlerlist->val; - clobbered_eassert (handlerlist == c); - handlerlist = handlerlist->next; - return hfun (val); - } - else - { - Lisp_Object val = bfun (arg1, arg2, arg3, arg4); - eassert (handlerlist == c); - handlerlist = c->next; - return val; - } -} - -/* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, - ARG4, ARG5 as its arguments. */ - -Lisp_Object -internal_condition_case_5 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object, - Lisp_Object, Lisp_Object, - Lisp_Object), - Lisp_Object arg1, Lisp_Object arg2, - Lisp_Object arg3, Lisp_Object arg4, - Lisp_Object arg5, Lisp_Object handlers, - Lisp_Object (*hfun) (Lisp_Object)) -{ - struct handler *c = push_handler (handlers, CONDITION_CASE); - if (sys_setjmp (c->jmp)) - { - Lisp_Object val = handlerlist->val; - clobbered_eassert (handlerlist == c); - handlerlist = handlerlist->next; - return hfun (val); - } - else - { - Lisp_Object val = bfun (arg1, arg2, arg3, arg4, arg5); - eassert (handlerlist == c); - handlerlist = c->next; - return val; - } -} - /* Like internal_condition_case but call BFUN with NARGS as first, and ARGS as second argument. */ diff --git a/src/lisp.h b/src/lisp.h index b558d311a8..c5045d72ee 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4466,9 +4466,6 @@ extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_ extern Lisp_Object internal_condition_case (Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_1 (Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_2 (Lisp_Object (*) (Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); -extern Lisp_Object internal_condition_case_3 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); -extern Lisp_Object internal_condition_case_4 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); -extern Lisp_Object internal_condition_case_5 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_n (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); commit 035e8e4d4518674304666b89935ad1ba8c351a9b Author: Paul Eggert Date: Sat Mar 19 12:35:03 2022 -0700 Remove sanitize_window_sizes * src/window.c (sanitize_window_sizes): Remove; no-longer-used. A previous refactoring moved this to Lisp without removing the C code. diff --git a/src/window.c b/src/window.c index 59e21f11cb..8f92b46afd 100644 --- a/src/window.c +++ b/src/window.c @@ -3181,14 +3181,6 @@ resize_root_window (Lisp_Object window, Lisp_Object delta, horizontal, ignore, pixelwise); } -void -sanitize_window_sizes (Lisp_Object horizontal) -{ - /* Don't burp in temacs -nw before window.el is loaded. */ - if (!NILP (Fsymbol_function (Qwindow__sanitize_window_sizes))) - call1 (Qwindow__sanitize_window_sizes, horizontal); -} - static Lisp_Object window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal) @@ -8232,7 +8224,6 @@ syms_of_window (void) DEFSYM (Qwindow__resize_root_window_vertically, "window--resize-root-window-vertically"); DEFSYM (Qwindow__resize_mini_frame, "window--resize-mini-frame"); - DEFSYM (Qwindow__sanitize_window_sizes, "window--sanitize-window-sizes"); DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total"); DEFSYM (Qsafe, "safe"); DEFSYM (Qdisplay_buffer, "display-buffer"); diff --git a/src/window.h b/src/window.h index 141c29e810..94c9b7124f 100644 --- a/src/window.h +++ b/src/window.h @@ -1188,7 +1188,6 @@ extern int window_scroll_margin (struct window *, enum margin_unit); extern void temp_output_buffer_show (Lisp_Object); extern void replace_buffer_in_windows (Lisp_Object); extern void replace_buffer_in_windows_safely (Lisp_Object); -extern void sanitize_window_sizes (Lisp_Object horizontal); /* This looks like a setter, but it is a bit special. */ extern void wset_buffer (struct window *, Lisp_Object); extern bool window_outdated (struct window *); commit 6887bf555f12e2059f237862159e19deddf596e1 Merge: 9c68894399 71b8f1fc63 Author: Eli Zaretskii Date: Sat Mar 19 17:19:19 2022 +0200 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 71b8f1fc635d9bbe00ca89457065e0c83456ac43 Author: Lars Ingebrigtsen Date: Sat Mar 19 15:11:15 2022 +0100 Make `command-modes' work for (native-compiled) subrs, too * lisp/emacs-lisp/comp.el (comp-func): Add a command-modes slot. (comp-spill-lap-function, comp-intern-func-in-ctxt): Fill it. (comp-emit-for-top-level, comp-emit-lambda-for-top-level): Use it. * src/alloc.c (mark_object): Mark the command_modes slot. * src/comp.c (make_subr): Add a command_modes parameter. (Fcomp__register_lambda): Use it. (Fcomp__register_subr): Ditto. * src/data.c (Fcommand_modes): Output the command_modes data for subrs (bug#54437). * src/lisp.h (GCALIGNED_STRUCT): Add a command_modes slot. * src/pdumper.c (dump_subr): Update hash. (dump_subr): Dump the command_modes slot. diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 122638077c..00efedd71f 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -898,6 +898,8 @@ non local exit (ends with an `unreachable' insn).")) :documentation "Doc string.") (int-spec nil :type list :documentation "Interactive form.") + (command-modes nil :type list + :documentation "Command modes.") (lap () :type list :documentation "LAP assembly representation.") (ssa-status nil :type symbol @@ -1243,6 +1245,7 @@ clashes." :c-name c-name :doc (documentation f t) :int-spec (interactive-form f) + :command-modes (command-modes f) :speed (comp-spill-speed function-name) :pure (comp-spill-decl-spec function-name 'pure)))) @@ -1282,10 +1285,12 @@ clashes." (make-comp-func-l :c-name c-name :doc (documentation form t) :int-spec (interactive-form form) + :command-modes (command-modes form) :speed (comp-ctxt-speed comp-ctxt)) (make-comp-func-d :c-name c-name :doc (documentation form t) :int-spec (interactive-form form) + :command-modes (command-modes form) :speed (comp-ctxt-speed comp-ctxt))))) (let ((lap (byte-to-native-lambda-lap (gethash (aref byte-code 1) @@ -1327,6 +1332,7 @@ clashes." (comp-func-byte-func func) byte-func (comp-func-doc func) (documentation byte-func t) (comp-func-int-spec func) (interactive-form byte-func) + (comp-func-command-modes func) (command-modes byte-func) (comp-func-c-name func) c-name (comp-func-lap func) lap (comp-func-frame-size func) (comp-byte-frame-size byte-func) @@ -2079,7 +2085,8 @@ and the annotation emission." (i (hash-table-count h))) (puthash i (comp-func-doc f) h) i) - (comp-func-int-spec f))) + (comp-func-int-spec f) + (comp-func-command-modes f))) ;; This is the compilation unit it-self passed as ;; parameter. (make-comp-mvar :slot 0)))))) @@ -2122,7 +2129,8 @@ These are stored in the reloc data array." (i (hash-table-count h))) (puthash i (comp-func-doc func) h) i) - (comp-func-int-spec func))) + (comp-func-int-spec func) + (comp-func-command-modes func))) ;; This is the compilation unit it-self passed as ;; parameter. (make-comp-mvar :slot 0))))) diff --git a/src/alloc.c b/src/alloc.c index c19e3dabb6..b0fbc91fe5 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6844,6 +6844,7 @@ mark_object (Lisp_Object arg) set_vector_marked (ptr); struct Lisp_Subr *subr = XSUBR (obj); mark_object (subr->native_intspec); + mark_object (subr->command_modes); mark_object (subr->native_comp_u); mark_object (subr->lambda_list); mark_object (subr->type); diff --git a/src/comp.c b/src/comp.c index 6449eedb27..499eee7e70 100644 --- a/src/comp.c +++ b/src/comp.c @@ -5411,7 +5411,7 @@ native_function_doc (Lisp_Object function) static Lisp_Object make_subr (Lisp_Object symbol_name, Lisp_Object minarg, Lisp_Object maxarg, Lisp_Object c_name, Lisp_Object type, Lisp_Object doc_idx, - Lisp_Object intspec, Lisp_Object comp_u) + Lisp_Object intspec, Lisp_Object command_modes, Lisp_Object comp_u) { struct Lisp_Native_Comp_Unit *cu = XNATIVE_COMP_UNIT (comp_u); dynlib_handle_ptr handle = cu->handle; @@ -5445,6 +5445,7 @@ make_subr (Lisp_Object symbol_name, Lisp_Object minarg, Lisp_Object maxarg, x->s.max_args = FIXNUMP (maxarg) ? XFIXNUM (maxarg) : MANY; x->s.symbol_name = xstrdup (SSDATA (symbol_name)); x->s.native_intspec = intspec; + x->s.command_modes = command_modes; x->s.doc = XFIXNUM (doc_idx); #ifdef HAVE_NATIVE_COMP x->s.native_comp_u = comp_u; @@ -5467,12 +5468,17 @@ This gets called by top_level_run during the load phase. */) { Lisp_Object doc_idx = FIRST (rest); Lisp_Object intspec = SECOND (rest); + Lisp_Object command_modes = Qnil; + if (!NILP (XCDR (XCDR (rest)))) + command_modes = THIRD (rest); + struct Lisp_Native_Comp_Unit *cu = XNATIVE_COMP_UNIT (comp_u); if (cu->loaded_once) return Qnil; Lisp_Object tem = - make_subr (c_name, minarg, maxarg, c_name, type, doc_idx, intspec, comp_u); + make_subr (c_name, minarg, maxarg, c_name, type, doc_idx, intspec, + command_modes, comp_u); /* We must protect it against GC because the function is not reachable through symbols. */ @@ -5497,9 +5503,13 @@ This gets called by top_level_run during the load phase. */) { Lisp_Object doc_idx = FIRST (rest); Lisp_Object intspec = SECOND (rest); + Lisp_Object command_modes = Qnil; + if (!NILP (XCDR (XCDR (rest)))) + command_modes = THIRD (rest); + Lisp_Object tem = make_subr (SYMBOL_NAME (name), minarg, maxarg, c_name, type, doc_idx, - intspec, comp_u); + intspec, command_modes, comp_u); defalias (name, tem); diff --git a/src/data.c b/src/data.c index 23b0e7c29d..5894340aba 100644 --- a/src/data.c +++ b/src/data.c @@ -1167,7 +1167,11 @@ The value, if non-nil, is a list of mode name symbols. */) fun = Fsymbol_function (fun); } - if (COMPILEDP (fun)) + if (SUBRP (fun)) + { + return XSUBR (fun)->command_modes; + } + else if (COMPILEDP (fun)) { if (PVSIZE (fun) <= COMPILED_INTERACTIVE) return Qnil; diff --git a/src/lisp.h b/src/lisp.h index e4d156c0f4..b558d311a8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2154,6 +2154,7 @@ struct Lisp_Subr const char *intspec; Lisp_Object native_intspec; }; + Lisp_Object command_modes; EMACS_INT doc; #ifdef HAVE_NATIVE_COMP Lisp_Object native_comp_u; diff --git a/src/pdumper.c b/src/pdumper.c index f14239f863..1183102362 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2854,7 +2854,7 @@ dump_bool_vector (struct dump_context *ctx, const struct Lisp_Vector *v) static dump_off dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr) { -#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_F09D8E8E19) +#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_A212A8F82A) # error "Lisp_Subr changed. See CHECK_STRUCTS comment in config.h." #endif struct Lisp_Subr out; @@ -2878,11 +2878,13 @@ dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr) COLD_OP_NATIVE_SUBR, make_lisp_ptr ((void *) subr, Lisp_Vectorlike)); dump_field_lv (ctx, &out, subr, &subr->native_intspec, WEIGHT_NORMAL); + dump_field_lv (ctx, &out, subr, &subr->command_modes, WEIGHT_NORMAL); } else { dump_field_emacs_ptr (ctx, &out, subr, &subr->symbol_name); dump_field_emacs_ptr (ctx, &out, subr, &subr->intspec); + dump_field_emacs_ptr (ctx, &out, subr, &subr->command_modes); } DUMP_FIELD_COPY (&out, subr, doc); #ifdef HAVE_NATIVE_COMP commit c79e0188e849715a7c4dc306c93ad8d0b3517d32 Author: Po Lu Date: Sat Mar 19 18:46:50 2022 +0800 Improve protection against faulty clients during DND * src/xterm.c (x_dnd_send_enter, x_dnd_send_position) (xdnd_send_leave, x_dnd_send_drop): Catch errors around call to XSendEvent. The target window could be gone. diff --git a/src/xterm.c b/src/xterm.c index b820c102f1..fb0fc66ae5 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1035,7 +1035,9 @@ x_dnd_send_enter (struct frame *f, Window target, int supported) PropModeReplace, (unsigned char *) x_dnd_targets, x_dnd_n_targets); + x_catch_errors (dpyinfo->display); XSendEvent (FRAME_X_DISPLAY (f), target, False, 0, &msg); + x_uncatch_errors (); } static void @@ -1075,7 +1077,9 @@ x_dnd_send_position (struct frame *f, Window target, int supported, if (supported >= 4) msg.xclient.data.l[4] = action; + x_catch_errors (dpyinfo->display); XSendEvent (FRAME_X_DISPLAY (f), target, False, 0, &msg); + x_uncatch_errors (); } static void @@ -1094,7 +1098,9 @@ x_dnd_send_leave (struct frame *f, Window target) msg.xclient.data.l[3] = 0; msg.xclient.data.l[4] = 0; + x_catch_errors (dpyinfo->display); XSendEvent (FRAME_X_DISPLAY (f), target, False, 0, &msg); + x_uncatch_errors (); } static void @@ -1117,7 +1123,9 @@ x_dnd_send_drop (struct frame *f, Window target, Time timestamp, if (supported >= 1) msg.xclient.data.l[2] = timestamp; + x_catch_errors (dpyinfo->display); XSendEvent (FRAME_X_DISPLAY (f), target, False, 0, &msg); + x_uncatch_errors (); } void commit 2f1fbf20ad957331b34bb3914e06185b3b34a1a1 Author: F. Jason Park Date: Sat Mar 19 02:33:24 2022 -0700 ; * test/lisp/erc/erc-tests.el (erc--switch-to-buffer): Fix test failure. diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 5a2b90a940..520f10dd4e 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -127,6 +127,7 @@ (with-current-buffer (get-buffer-create "server") (erc-mode) (set-process-buffer (setq erc-server-process proc) (current-buffer)) + (set-process-query-on-exit-flag erc-server-process nil) (with-current-buffer (get-buffer-create "#chan") (erc-mode) (setq erc-server-process proc)) @@ -154,7 +155,8 @@ (with-current-buffer (get-buffer-create "other") (erc-mode) - (setq erc-server-process (start-process "bNet" (current-buffer) "true"))) + (setq erc-server-process (start-process "bNet" (current-buffer) "true")) + (set-process-query-on-exit-flag erc-server-process nil)) (ert-info ("Foreign ERC buffer not selectable") (ert-simulate-keys (kbd "other C-m C-a C-k C-m") commit f755daafb92cc61596708a580040784fc269edd4 Author: Guy Gastineau Date: Fri Jan 28 23:12:42 2022 -0500 Remove redundant checks in erc--switch-to-buffer * lisp/erc/erc.el (erc--switch-to-buffer): Commit f925fc93bac41d7622d1af927e33b0e738ff55b0 "Add `predicate' arg to `read-buffer' and use it for erc-iswitchb" meant to remove this, but it was left behind. (Bug#53617) Copyright-paperwork-exempt: yes diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 9ee8d38b02..52fe106f2d 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1761,12 +1761,7 @@ nil." (lambda (bufname) (let ((buf (if (consp bufname) (cdr bufname) (get-buffer bufname)))) - (when buf - (erc--buffer-p buf (lambda () t) proc) - (with-current-buffer buf - (and (derived-mode-p 'erc-mode) - (or (null proc) - (eq proc erc-server-process)))))))))) + (and buf (erc--buffer-p buf (lambda () t) proc))))))) (defun erc-switch-to-buffer (&optional arg) "Prompt for an ERC buffer to switch to. When invoked with prefix argument, use all ERC buffers. Without commit 17bd063a67404a13ff719830336693d7cd7f6d79 Author: F. Jason Park Date: Sun Mar 13 22:39:36 2022 -0700 Add unit test for erc--switch-to-buffer * test/lisp/erc/erc-tests.el (erc--switch-to-buffer): Add new test. (Bug#53617) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 5603e76454..5a2b90a940 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -21,7 +21,7 @@ ;;; Code: -(require 'ert) +(require 'ert-x) (require 'erc) (require 'erc-ring) (require 'erc-networks) @@ -114,6 +114,61 @@ (should (get-buffer "#spam")) (kill-buffer "#spam"))) +(ert-deftest erc--switch-to-buffer () + (defvar erc-modified-channels-alist) ; lisp/erc/erc-track.el + + (let ((proc (start-process "aNet" (current-buffer) "true")) + (erc-modified-channels-alist `(("fake") (,(messages-buffer)))) + (inhibit-message noninteractive) + (completion-fail-discreetly t) ; otherwise ^G^G printed to .log file + ;; + erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) + + (with-current-buffer (get-buffer-create "server") + (erc-mode) + (set-process-buffer (setq erc-server-process proc) (current-buffer)) + (with-current-buffer (get-buffer-create "#chan") + (erc-mode) + (setq erc-server-process proc)) + (with-current-buffer (get-buffer-create "#foo") + (erc-mode) + (setq erc-server-process proc)) + + (ert-info ("Channel #chan selectable from server buffer") + (ert-simulate-keys (list ?# ?c ?h ?a ?n ?\C-m) + (should (string= "#chan" (erc--switch-to-buffer)))))) + + (ert-info ("Channel #foo selectable from non-ERC buffer") + (ert-simulate-keys (list ?# ?f ?o ?o ?\C-m) + (should (string= "#foo" (erc--switch-to-buffer))))) + + (ert-info ("Default selectable") + (ert-simulate-keys (list ?\C-m) + (should (string= "*Messages*" (erc--switch-to-buffer))))) + + (ert-info ("Extant but non-ERC buffer not selectable") + (get-buffer-create "#fake") ; not ours + (ert-simulate-keys (kbd "#fake C-m C-a C-k C-m") + ;; Initial query fails ~~~~~~^; clearing input accepts default + (should (string= "*Messages*" (erc--switch-to-buffer))))) + + (with-current-buffer (get-buffer-create "other") + (erc-mode) + (setq erc-server-process (start-process "bNet" (current-buffer) "true"))) + + (ert-info ("Foreign ERC buffer not selectable") + (ert-simulate-keys (kbd "other C-m C-a C-k C-m") + (with-current-buffer "server" + (should (string= "*Messages*" (erc--switch-to-buffer)))))) + + (ert-info ("Any ERC-buffer selectable from non-ERC buffer") + (should-not (eq major-mode 'erc-mode)) + (ert-simulate-keys (list ?o ?t ?h ?e ?r ?\C-m) + (should (string= "other" (erc--switch-to-buffer))))) + + (dolist (b '("server" "other" "#chan" "#foo" "#fake")) + (kill-buffer b)))) + (ert-deftest erc-lurker-maybe-trim () (let (erc-lurker-trim-nicks (erc-lurker-ignore-chars "_`")) commit 9c68894399e928220192fd44efbd71a1ca116028 Merge: 43ee6f291d e059d7c156 Author: Eli Zaretskii Date: Sat Mar 19 09:25:18 2022 +0200 Merge from origin/emacs-28 e059d7c Fix region highlight in non-selected windows commit e059d7c156edb37a7c836906b9a3510adee3d543 (refs/remotes/origin/emacs-28) Author: Eli Zaretskii Date: Sat Mar 19 09:19:53 2022 +0200 Fix region highlight in non-selected windows * src/xdisp.c (prepare_menu_bars): Include in the windows passed to pre-redisplay-functions windows whose point was moved from the last recorded position. (Bug#54450) diff --git a/src/xdisp.c b/src/xdisp.c index 3f283d6732..44f2536880 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12825,9 +12825,12 @@ prepare_menu_bars (void) { Lisp_Object this = XCAR (ws); struct window *w = XWINDOW (this); + /* Cf. conditions for redisplaying a window at the + beginning of redisplay_window. */ if (w->redisplay || XFRAME (w->frame)->redisplay - || XBUFFER (w->contents)->text->redisplay) + || XBUFFER (w->contents)->text->redisplay + || BUF_PT (XBUFFER (w->contents)) != w->last_point) { windows = Fcons (this, windows); }