commit d8adce56a0a9169c3ad6cb6f51fc116f5ccd127c (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Mon May 30 15:06:55 2022 +0800 Fix cursor flushing inside minibuffers on NS * src/nsterm.m (EV_TRAILER): Fix coding style. (ns_flush_display): New function. (ns_redisplay_interface): Register `flush_display'. diff --git a/src/nsterm.m b/src/nsterm.m index 176ce7d5bb..b5d5ab334d 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -440,28 +440,28 @@ - (unsigned long)unsignedLong /* This is a piece of code which is common to all the event handling methods. Maybe it should even be a function. */ -#define EV_TRAILER(e) \ - { \ - XSETFRAME (emacs_event->frame_or_window, emacsframe); \ - EV_TRAILER2 (e); \ +#define EV_TRAILER(e) \ + { \ + XSETFRAME (emacs_event->frame_or_window, emacsframe); \ + EV_TRAILER2 (e); \ } #define EV_TRAILER2(e) \ { \ - if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ - if (q_event_ptr) \ - { \ - Lisp_Object tem = Vinhibit_quit; \ - Vinhibit_quit = Qt; \ - n_emacs_events_pending++; \ - kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \ - Vinhibit_quit = tem; \ - } \ - else \ - hold_event (emacs_event); \ - EVENT_INIT (*emacs_event); \ - ns_send_appdefined (-1); \ - } + if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ + if (q_event_ptr) \ + { \ + Lisp_Object tem = Vinhibit_quit; \ + Vinhibit_quit = Qt; \ + n_emacs_events_pending++; \ + kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \ + Vinhibit_quit = tem; \ + } \ + else \ + hold_event (emacs_event); \ + EVENT_INIT (*emacs_event); \ + ns_send_appdefined (-1); \ + } /* TODO: Get rid of need for these forward declarations. */ @@ -5182,11 +5182,26 @@ static Lisp_Object ns_string_to_lispmod (const char *s) } #endif -/* This and next define (many of the) public functions in this file. */ -/* gui_* are generic versions in xdisp.c that we, and other terms, get away - with using despite presence in the "system dependent" redisplay - interface. In addition, many of the ns_ methods have code that is - shared with all terms, indicating need for further refactoring. */ +static void +ns_flush_display (struct frame *f) +{ + struct input_event ie; + + /* Called from some of the minibuffer code. Run the event loop once + to make the toolkit make changes that were made to the back + buffer visible again. TODO: what should happen to ie? */ + + EVENT_INIT (ie); + ns_read_socket (FRAME_TERMINAL (f), &ie); +} + +/* This and next define (many of the) public functions in this + file. */ +/* gui_* are generic versions in xdisp.c that we, and other terms, get + away with using despite presence in the "system dependent" + redisplay interface. In addition, many of the ns_ methods have + code that is shared with all terms, indicating need for further + refactoring. */ extern frame_parm_handler ns_frame_parm_handlers[]; static struct redisplay_interface ns_redisplay_interface = { @@ -5203,7 +5218,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s) #else ns_update_window_end, #endif - 0, /* flush_display */ + ns_flush_display, gui_clear_window_mouse_face, gui_get_glyph_overhangs, gui_fix_overlapping_area, commit fd510f12392fcb2bf34eb08262ddda20d8a3c221 Author: Po Lu Date: Mon May 30 14:04:43 2022 +0800 Fix hangs when x-get-selection is called inside a popup menu * src/xselect.c (wait_for_property_change): (x_get_foreign_selection): Use `x_wait_for_cell_change' if input is blocked. (bug#22214) * src/xterm.c (x_wait_for_cell_change): New function. * src/xterm.h: Update prototypes. diff --git a/src/xselect.c b/src/xselect.c index bfd081b1e2..a414873594 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1148,8 +1148,13 @@ wait_for_property_change (struct prop_location *location) intmax_t secs = timeout / 1000; int nsecs = (timeout % 1000) * 1000000; TRACE2 (" Waiting %"PRIdMAX" secs, %d nsecs", secs, nsecs); - wait_reading_process_output (secs, nsecs, 0, false, - property_change_reply, NULL, 0); + + if (!input_blocked_p ()) + wait_reading_process_output (secs, nsecs, 0, false, + property_change_reply, NULL, 0); + else + x_wait_for_cell_change (property_change_reply, + make_timespec (secs, nsecs)); if (NILP (XCAR (property_change_reply))) { @@ -1256,8 +1261,17 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, intmax_t secs = timeout / 1000; int nsecs = (timeout % 1000) * 1000000; TRACE1 (" Start waiting %"PRIdMAX" secs for SelectionNotify", secs); - wait_reading_process_output (secs, nsecs, 0, false, - reading_selection_reply, NULL, 0); + /* This function can be called with input blocked inside Xt or GTK + timeouts run inside popup menus, so use a function that works + when input is blocked. Prefer wait_reading_process_output + otherwise, or the toolkit might not get some events. + (bug#22214) */ + if (!input_blocked_p ()) + wait_reading_process_output (secs, nsecs, 0, false, + reading_selection_reply, NULL, 0); + else + x_wait_for_cell_change (reading_selection_reply, + make_timespec (secs, nsecs)); TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); if (NILP (XCAR (reading_selection_reply))) diff --git a/src/xterm.c b/src/xterm.c index eee888f6fe..777a6c4daf 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -14836,6 +14836,70 @@ x_display_pixel_width (struct x_display_info *dpyinfo) return WidthOfScreen (dpyinfo->screen); } +/* Handle events from each display until CELL's car becomes non-nil, + or TIMEOUT elapses. */ +void +x_wait_for_cell_change (Lisp_Object cell, struct timespec timeout) +{ + struct x_display_info *dpyinfo; + fd_set fds; + int fd, maxfd, finish; + XEvent event; + struct input_event hold_quit; + struct timespec current, at; + + at = timespec_add (current_timespec (), timeout); + + while (true) + { + FD_ZERO (&fds); + maxfd = -1; + + for (dpyinfo = x_display_list; dpyinfo; + dpyinfo = dpyinfo->next) + { + if (XPending (dpyinfo->display)) + { + EVENT_INIT (hold_quit); + + XNextEvent (dpyinfo->display, &event); + handle_one_xevent (dpyinfo, &event, + &finish, &hold_quit); + + /* Make us quit now. */ + if (hold_quit.kind != NO_EVENT) + kbd_buffer_store_event (&hold_quit); + + if (!NILP (XCAR (cell))) + return; + } + + fd = XConnectionNumber (dpyinfo->display); + + if (fd > maxfd) + maxfd = fd; + + eassert (fd < FD_SETSIZE); + FD_SET (XConnectionNumber (dpyinfo->display), &fds); + } + + eassert (maxfd >= 0); + + current = current_timespec (); + + if (timespec_cmp (at, current) < 0 + || !NILP (XCAR (cell))) + return; + + timeout = timespec_sub (at, current); + + /* We don't have to check the return of pselect, because if an + error occurs XPending will call the IO error handler, which + then brings us out of this loop. */ + pselect (maxfd, &fds, NULL, NULL, &timeout, NULL); + } +} + #ifdef USE_GTK static void x_monitors_changed_cb (GdkScreen *gscr, gpointer user_data) diff --git a/src/xterm.h b/src/xterm.h index c8e86d5d09..d7e184ed9f 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1386,8 +1386,8 @@ extern const char *x_get_string_resource (void *, const char *, const char *); /* Defined in xterm.c */ -typedef void (*x_special_error_handler)(Display *, XErrorEvent *, char *, - void *); +typedef void (*x_special_error_handler) (Display *, XErrorEvent *, char *, + void *); extern bool x_text_icon (struct frame *, const char *); extern void x_catch_errors (Display *); @@ -1425,6 +1425,7 @@ extern void x_clear_area (struct frame *f, int, int, int, int); || (!defined USE_X_TOOLKIT && !defined USE_GTK) extern void x_mouse_leave (struct x_display_info *); #endif +extern void x_wait_for_cell_change (Lisp_Object, struct timespec); #ifndef USE_GTK extern int x_dispatch_event (XEvent *, Display *); commit 52d41f2750c0f66d7f7ba8e198832734fe750fa5 Merge: 48ef8ab15f 1b7b69e764 Author: Stefan Kangas Date: Mon May 30 06:30:24 2022 +0200 Merge from origin/emacs-28 1b7b69e764 Some Tramp cleanup on MS Windows commit 48ef8ab15f0e884ac97736d1d24af7eecf9313cc Author: Po Lu Date: Mon May 30 10:36:43 2022 +0800 Try to implement `dnd-indicate-insertion-point' on macOS * lisp/term/ns-win.el (ns-handle-drag-motion): New function. * src/nsterm.m ([EmacsView draggingUpdated:]): Call that function instead. (syms_of_nsterm): Clean up old style defvars and add new defvar for the DND drag function. diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index b49143fbc2..c2ce9fef1d 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el @@ -912,6 +912,13 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") pasteboard)) (ns-begin-drag frame pasteboard action))) +(defun ns-handle-drag-motion (frame x y) + "Handle mouse movement on FRAME at X and Y during drag-and-drop. +This moves point to the current mouse position if + `dnd-indicate-insertion-point' is enabled." + (dnd-handle-movement (posn-at-x-y x y frame)) + (print (redisplay t) 'external-debugging-output)) + (provide 'ns-win) (provide 'term/ns-win) diff --git a/src/nsterm.m b/src/nsterm.m index 79e30d6ff9..176ce7d5bb 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -8596,12 +8596,18 @@ - (BOOL) wantsPeriodicDraggingUpdates - (NSDragOperation) draggingUpdated: (id ) sender { +#ifdef NS_IMPL_GNUSTEP struct input_event ie; +#else + Lisp_Object frame; +#endif NSPoint position; int x, y; +#ifdef NS_IMPL_GNUSTEP EVENT_INIT (ie); ie.kind = DRAG_N_DROP_EVENT; +#endif /* Get rid of mouse face. */ [self mouseExited: [[self window] currentEvent]]; @@ -8611,6 +8617,7 @@ - (NSDragOperation) draggingUpdated: (id ) sender x = lrint (position.x); y = lrint (position.y); +#ifdef NS_IMPL_GNUSTEP XSETINT (ie.x, x); XSETINT (ie.y, y); XSETFRAME (ie.frame_or_window, emacsframe); @@ -8618,6 +8625,15 @@ - (NSDragOperation) draggingUpdated: (id ) sender ie.modifiers = 0; kbd_buffer_store_event (&ie); +#else + /* Input events won't be processed until the drop happens on macOS, + so call this function instead. */ + XSETFRAME (frame, emacsframe); + + safe_call (4, Vns_drag_motion_function, frame, + make_fixnum (x), make_fixnum (y)); +#endif + return NSDragOperationGeneric; } @@ -10490,6 +10506,7 @@ Convert an X font name (XLFD) to an NS font name. DEFSYM (Qns_drag_operation_copy, "ns-drag-operation-copy"); DEFSYM (Qns_drag_operation_link, "ns-drag-operation-link"); DEFSYM (Qns_drag_operation_generic, "ns-drag-operation-generic"); + DEFSYM (Qns_handle_drag_motion, "ns-handle-drag-motion"); Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier)); Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier)); @@ -10497,117 +10514,117 @@ Convert an X font name (XLFD) to an NS font name. Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier)); Fput (Qcontrol, Qmodifier_value, make_fixnum (ctrl_modifier)); - DEFVAR_LISP ("ns-input-file", ns_input_file, - "The file specified in the last NS event."); - ns_input_file =Qnil; + DEFVAR_LISP ("ns-input-font", ns_input_font, + doc: /* The font specified in the last NS event. */); + ns_input_font = Qnil; - DEFVAR_LISP ("ns-working-text", ns_working_text, - "String for visualizing working composition sequence."); - ns_working_text =Qnil; + DEFVAR_LISP ("ns-input-fontsize", ns_input_fontsize, + doc: /* The fontsize specified in the last NS event. */); + ns_input_fontsize = Qnil; - DEFVAR_LISP ("ns-input-font", ns_input_font, - "The font specified in the last NS event."); - ns_input_font =Qnil; + DEFVAR_LISP ("ns-input-line", ns_input_line, + doc: /* The line specified in the last NS event. */); + ns_input_line = Qnil; - DEFVAR_LISP ("ns-input-fontsize", ns_input_fontsize, - "The fontsize specified in the last NS event."); - ns_input_fontsize =Qnil; + DEFVAR_LISP ("ns-input-spi-name", ns_input_spi_name, + doc: /* The service name specified in the last NS event. */); + ns_input_spi_name = Qnil; - DEFVAR_LISP ("ns-input-line", ns_input_line, - "The line specified in the last NS event."); - ns_input_line =Qnil; + DEFVAR_LISP ("ns-input-spi-arg", ns_input_spi_arg, + doc: /* The service argument specified in the last NS event. */); + ns_input_spi_arg = Qnil; - DEFVAR_LISP ("ns-input-spi-name", ns_input_spi_name, - "The service name specified in the last NS event."); - ns_input_spi_name =Qnil; + DEFVAR_LISP ("ns-input-file", ns_input_file, + doc: /* The file specified in the last NS event. */); + ns_input_file = Qnil; - DEFVAR_LISP ("ns-input-spi-arg", ns_input_spi_arg, - "The service argument specified in the last NS event."); - ns_input_spi_arg =Qnil; + DEFVAR_LISP ("ns-working-text", ns_working_text, + doc: /* String for visualizing working composition sequence. */); + ns_working_text = Qnil; DEFVAR_LISP ("ns-alternate-modifier", ns_alternate_modifier, - "This variable describes the behavior of the alternate or option key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the alternate or option key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_alternate_modifier = Qmeta; DEFVAR_LISP ("ns-right-alternate-modifier", ns_right_alternate_modifier, - "This variable describes the behavior of the right alternate or option key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -It can also be `left' to use the value of `ns-alternate-modifier' instead.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the right alternate or option key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. +It can also be `left' to use the value of `ns-alternate-modifier' instead. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_right_alternate_modifier = Qleft; DEFVAR_LISP ("ns-command-modifier", ns_command_modifier, - "This variable describes the behavior of the command key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the command key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_command_modifier = Qsuper; DEFVAR_LISP ("ns-right-command-modifier", ns_right_command_modifier, - "This variable describes the behavior of the right command key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -It can also be `left' to use the value of `ns-command-modifier' instead.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the right command key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. +It can also be `left' to use the value of `ns-command-modifier' instead. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_right_command_modifier = Qleft; DEFVAR_LISP ("ns-control-modifier", ns_control_modifier, - "This variable describes the behavior of the control key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the control key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_control_modifier = Qcontrol; DEFVAR_LISP ("ns-right-control-modifier", ns_right_control_modifier, - "This variable describes the behavior of the right control key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -It can also be `left' to use the value of `ns-control-modifier' instead.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the right control key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. +It can also be `left' to use the value of `ns-control-modifier' instead. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_right_control_modifier = Qleft; DEFVAR_LISP ("ns-function-modifier", ns_function_modifier, - "This variable describes the behavior of the function (fn) key.\n\ -Either SYMBOL, describing the behavior for any event,\n\ -or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior\n\ -separately for ordinary keys, function keys, and mouse events.\n\ -\n\ -Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'.\n\ -If `none', the key is ignored by Emacs and retains its standard meaning."); + doc: /* This variable describes the behavior of the function (fn) key. +Either SYMBOL, describing the behavior for any event, +or (:ordinary SYMBOL :function SYMBOL :mouse SYMBOL), describing behavior +separately for ordinary keys, function keys, and mouse events. + +Each SYMBOL is `control', `meta', `alt', `super', `hyper' or `none'. +If `none', the key is ignored by Emacs and retains its standard meaning. */); ns_function_modifier = Qnone; DEFVAR_LISP ("ns-antialias-text", ns_antialias_text, - "Non-nil (the default) means to render text antialiased."); + doc: /* Non-nil (the default) means to render text antialiased. */); ns_antialias_text = Qt; DEFVAR_LISP ("ns-use-thin-smoothing", ns_use_thin_smoothing, - "Non-nil turns on a font smoothing method that produces thinner strokes."); + doc: /* Non-nil turns on a font smoothing method that produces thinner strokes. */); ns_use_thin_smoothing = Qnil; DEFVAR_LISP ("ns-confirm-quit", ns_confirm_quit, - "Whether to confirm application quit using dialog."); + doc: /* Whether to confirm application quit using dialog. */); ns_confirm_quit = Qnil; DEFVAR_LISP ("ns-auto-hide-menu-bar", ns_auto_hide_menu_bar, @@ -10677,6 +10694,16 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with mice with smooth scrolling capability. */); Vns_scroll_event_delta_factor = make_float (1.0); + DEFVAR_LISP ("ns-drag-motion-function", Vns_drag_motion_function, + doc: /* Function called when another program drags items over Emacs. + +It is called with three arguments FRAME, X, and Y, whenever the user +moves the mouse over an Emacs frame as part of a drag-and-drop +operation. FRAME is the frame the mouse is on top of, and X and Y are +the frame-relative positions of the mouse in the X and Y axises +respectively. */); + Vns_drag_motion_function = Qns_handle_drag_motion; + /* Tell Emacs about this window system. */ Fprovide (Qns, Qnil); commit 5b770b60f4f9d7d157774b999b0574aee133e7cb Author: Po Lu Date: Mon May 30 09:25:03 2022 +0800 Further clean up DND target handling * src/xfns.c (Fx_begin_drag): Alloca target list. * src/xterm.c (x_set_dnd_targets): Copy the given targets list. (x_dnd_begin_drag_and_drop): Record freeing the targets list on the specpdl. (handle_one_xevent, x_dnd_cleanup_drag_and_drop) (x_connection_closed, x_delete_terminal): Stop calling `x_set_dnd_targets' manually to free the targets list. diff --git a/src/xfns.c b/src/xfns.c index 8237e8870c..259034861a 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -6932,7 +6932,7 @@ that mouse buttons are being held down, such as immediately after a else signal_error ("Invalid drag-and-drop action", action); - target_atoms = xmalloc (ntargets * sizeof *target_atoms); + target_atoms = SAFE_ALLOCA (ntargets * sizeof *target_atoms); block_input (); XInternAtoms (FRAME_X_DISPLAY (f), target_names, diff --git a/src/xterm.c b/src/xterm.c index 996e194926..eee888f6fe 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3907,8 +3907,24 @@ x_set_dnd_targets (Atom *targets, int ntargets) if (x_dnd_targets) xfree (x_dnd_targets); - x_dnd_targets = targets; + block_input (); + x_dnd_targets = xmalloc (sizeof *targets * ntargets); x_dnd_n_targets = ntargets; + + memcpy (x_dnd_targets, targets, + sizeof *targets * ntargets); + unblock_input (); +} + +static void +x_free_dnd_targets (void) +{ + if (!x_dnd_targets) + return; + + xfree (x_dnd_targets); + x_dnd_targets = NULL; + x_dnd_n_targets = 0; } static void @@ -3962,7 +3978,6 @@ x_dnd_cleanup_drag_and_drop (void *frame) x_dnd_in_progress = false; } - x_set_dnd_targets (NULL, 0); x_dnd_waiting_for_finish = false; if (x_dnd_use_toplevels) @@ -10332,7 +10347,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, struct frame *any; char *atom_name, *ask_actions; Lisp_Object action, ltimestamp; - specpdl_ref ref, count; + specpdl_ref ref, count, base; ptrdiff_t i, end, fill; XTextProperty prop; xm_drop_start_message dmsg; @@ -10348,6 +10363,8 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, int n_events; struct frame *event_frame; + base = SPECPDL_INDEX (); + /* Before starting drag-and-drop, walk through the keyboard buffer to see if there are any UNSUPPORTED_DROP_EVENTs, and run them now if they exist, to prevent race conditions from happening due to @@ -10427,6 +10444,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, if (popup_activated ()) error ("Trying to drag-and-drop from within a menu-entry"); + record_unwind_protect_void (x_free_dnd_targets); x_set_dnd_targets (target_atoms, ntargets); ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f), @@ -10738,7 +10756,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, x_dnd_frame = NULL; } - x_set_dnd_targets (NULL, 0); x_dnd_waiting_for_finish = false; if (x_dnd_use_toplevels) @@ -10810,7 +10827,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, x_dnd_frame = NULL; } - x_set_dnd_targets (NULL, 0); x_dnd_waiting_for_finish = false; if (x_dnd_use_toplevels) @@ -10850,7 +10866,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, #endif } - x_set_dnd_targets (NULL, 0); x_dnd_waiting_for_finish = false; #ifdef USE_GTK @@ -10887,7 +10902,8 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, XSETFRAME (action, x_dnd_return_frame_object); x_dnd_return_frame_object = NULL; - return action; + + return unbind_to (base, action); } x_dnd_return_frame_object = NULL; @@ -10903,7 +10919,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, && (any = x_any_window_to_frame (FRAME_DISPLAY_INFO (f), x_dnd_end_window)) && (allow_current_frame || any != f)) - return QXdndActionPrivate; + return unbind_to (base, QXdndActionPrivate); if (x_dnd_action != None) { @@ -10928,10 +10944,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, action = Qnil; unblock_input (); - return action; + return unbind_to (base, action); } - return Qnil; + return unbind_to (base, Qnil); } /* The focus may have changed. Figure out if it is a real focus change, @@ -17334,7 +17350,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_last_seen_window = None; x_dnd_last_seen_toplevel = None; x_dnd_frame = NULL; - x_set_dnd_targets (NULL, 0); } } @@ -18653,7 +18668,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_last_seen_window = None; x_dnd_last_seen_toplevel = None; x_dnd_frame = NULL; - x_set_dnd_targets (NULL, 0); goto XI_OTHER; } @@ -21459,7 +21473,6 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) x_dnd_last_seen_window = None; x_dnd_last_seen_toplevel = None; x_dnd_in_progress = false; - x_set_dnd_targets (NULL, 0); x_dnd_waiting_for_finish = false; if (x_dnd_use_toplevels) @@ -25493,7 +25506,6 @@ x_delete_terminal (struct terminal *terminal) x_dnd_last_seen_window = None; x_dnd_last_seen_toplevel = None; x_dnd_in_progress = false; - x_set_dnd_targets (NULL, 0); x_dnd_waiting_for_finish = false; if (x_dnd_use_toplevels) commit e2e232933c6f944b1dda7c578425b34f1e160e7f Author: Po Lu Date: Mon May 30 09:07:27 2022 +0800 Fix crash when loading Postscript images * src/xterm.c (handle_one_xevent): Catch errors around `x_kill_gs_process'. diff --git a/src/xterm.c b/src/xterm.c index ab36c1681a..996e194926 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -15260,7 +15260,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; #ifndef USE_CAIRO Pixmap pixmap = (Pixmap) event->xclient.data.l[1]; + /* FIXME: why does this sometimes generate a BadMatch + error? */ + x_catch_errors (dpyinfo->display); x_kill_gs_process (pixmap, f); + x_uncatch_errors (); expose_frame (f, 0, 0, 0, 0); #endif /* !USE_CAIRO */ goto done; commit b6a476638848e02e29fd4a0fb8ba5dfc394723b0 Author: Po Lu Date: Mon May 30 08:49:24 2022 +0800 Use XDrawPoint to clear relief rect corners * xterm.c (x_clear_point): New function. (x_draw_relief_rect): Use that instead. diff --git a/src/xterm.c b/src/xterm.c index 908185c3d1..ab36c1681a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -6573,6 +6573,31 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h) x_clear_rectangle (s->f, s->gc, x, y, w, h, s->hl != DRAW_CURSOR); } +#ifndef USE_CAIRO + +static void +x_clear_point (struct frame *f, GC gc, int x, int y, + bool respect_alpha_background) +{ + XGCValues xgcv; + Display *dpy; + + dpy = FRAME_X_DISPLAY (f); + + if (f->alpha_background != 1.0 + && respect_alpha_background) + { + x_clear_rectangle (f, gc, x, y, 1, 1, true); + return; + } + + XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv); + XSetForeground (dpy, gc, xgcv.background); + XDrawPoint (dpy, FRAME_X_DRAWABLE (f), gc, x, y); + XSetForeground (dpy, gc, xgcv.foreground); +} + +#endif /* Draw the background of glyph_string S. If S->background_filled_p is non-zero don't draw it. FORCE_P non-zero means draw the @@ -7985,25 +8010,21 @@ x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x, { if (left_p && top_p && x_inside_rect_p (clip_rect, 1, left_x, top_y)) - /* This should respect `alpha-backgroun' since it's being + /* This should respect `alpha-background' since it's being cleared with the background color of the frame. */ - x_clear_rectangle (f, normal_gc, left_x, top_y, 1, 1, - true); + x_clear_point (f, normal_gc, left_x, top_y, true); if (left_p && bot_p && x_inside_rect_p (clip_rect, 1, left_x, bottom_y)) - x_clear_rectangle (f, normal_gc, left_x, bottom_y, 1, 1, - true); + x_clear_point (f, normal_gc, left_x, bottom_y, true); if (right_p && top_p && x_inside_rect_p (clip_rect, 1, right_x, top_y)) - x_clear_rectangle (f, normal_gc, right_x, top_y, 1, 1, - true); + x_clear_point (f, normal_gc, right_x, top_y, true); if (right_p && bot_p && x_inside_rect_p (clip_rect, 1, right_x, bottom_y)) - x_clear_rectangle (f, normal_gc, right_x, bottom_y, 1, 1, - true); + x_clear_point (f, normal_gc, right_x, bottom_y, true); } x_reset_clip_rectangles (f, white_gc); commit 7f7acf395697e4cfa470cfa2993b70c2308e95c1 Author: Paul Eggert Date: Sun May 29 14:57:48 2022 -0700 Document decoded-time-string issue on 6-elt args * lisp/simple.el: Document problematic use of decoded-time-dst on 6-element args. diff --git a/lisp/simple.el b/lisp/simple.el index a254ee2251..d6b7045432 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10519,6 +10519,14 @@ This is an integer indicating the UTC offset in seconds, i.e., the number of seconds east of Greenwich.") ) +;; Document that decoded-time-dst is problematic on 6-element lists. +;; It should return -1 indicating unknown DST, but currently returns +;; nil indicating standard time. +(put 'decoded-time-dst 'function-documentation + (append (get 'decoded-time-dst 'function-documentation) + "As a special case, `decoded-time-dst' returns an unspecified +value when given a list too short to have a dst element.")) + (defun get-scratch-buffer-create () "Return the *scratch* buffer, creating a new one if needed." (or (get-buffer "*scratch*") commit b40009e2f933c1c1e1c55ac7474df2797e4c7e17 Author: Paul Eggert Date: Sun May 29 13:07:50 2022 -0700 ISO 8601 strings sans "Z" don’t specify DST flag * lisp/calendar/iso8601.el (iso8601--zone-dst): New function. (iso8601-parse, iso8601-parse-time): Use it. (iso8601--decoded-time): Default dst to -1, not nil. * test/lisp/calendar/iso8601-tests.el (test-iso8601-combined) (standard-test-time-of-day-zone): Adjust to new behavior. diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el index e31120f52f..6827a957a6 100644 --- a/lisp/calendar/iso8601.el +++ b/lisp/calendar/iso8601.el @@ -114,6 +114,11 @@ iso8601--duration-week-match iso8601--duration-combined-match))) +;; "Z" dnd "z" are standard time; nil and [-+][0-9][0-9]... are local time +;; with unknown DST. +(defun iso8601--zone-dst (zone) + (if (= (length zone) 1) nil -1)) + (defun iso8601-parse (string &optional form) "Parse an ISO 8601 date/time string and return a `decode-time' structure. @@ -140,7 +145,7 @@ See `decode-time' for the meaning of FORM." (setf (decoded-time-zone date) ;; The time zone in decoded times are in seconds. (* (iso8601-parse-zone zone-string) 60)) - (setf (decoded-time-dst date) nil)) + (setf (decoded-time-dst date) (iso8601--zone-dst zone-string))) date))) (defun iso8601-parse-date (string) @@ -256,6 +261,7 @@ See `decode-time' for the meaning of FORM." (iso8601--decoded-time :hour hour :minute (or minute 0) :second (or second 0) + :dst (iso8601--zone-dst zone) :zone (and zone (* 60 (iso8601-parse-zone zone))))))))) @@ -364,7 +370,7 @@ Return the number of minutes." (cl-defun iso8601--decoded-time (&key second minute hour day month year - dst zone) + (dst -1) zone) (list (iso8601--value second) (iso8601--value minute) (iso8601--value hour) @@ -372,7 +378,7 @@ Return the number of minutes." (iso8601--value month) (iso8601--value year) nil - (if (or dst zone) dst -1) + dst zone)) (defun iso8601--encode-time (time) diff --git a/test/lisp/calendar/iso8601-tests.el b/test/lisp/calendar/iso8601-tests.el index 6c9e85ec92..f64c498c02 100644 --- a/test/lisp/calendar/iso8601-tests.el +++ b/test/lisp/calendar/iso8601-tests.el @@ -82,9 +82,9 @@ (should (equal (iso8601-parse "2008-03-02T13:47:30Z") '(30 47 13 2 3 2008 nil nil 0))) (should (equal (iso8601-parse "2008-03-02T13:47:30+01:00") - '(30 47 13 2 3 2008 nil nil 3600))) + '(30 47 13 2 3 2008 nil -1 3600))) (should (equal (iso8601-parse "2008-03-02T13:47:30-01") - '(30 47 13 2 3 2008 nil nil -3600)))) + '(30 47 13 2 3 2008 nil -1 -3600)))) (ert-deftest test-iso8601-duration () (should (equal (iso8601-parse-duration "P3Y6M4DT12H30M5S") @@ -221,24 +221,24 @@ (ert-deftest standard-test-time-of-day-zone () (should (equal (iso8601-parse-time "152746+0100") - '(46 27 15 nil nil nil nil nil 3600))) + '(46 27 15 nil nil nil nil -1 3600))) (should (equal (iso8601-parse-time "15:27:46+0100") - '(46 27 15 nil nil nil nil nil 3600))) + '(46 27 15 nil nil nil nil -1 3600))) (should (equal (iso8601-parse-time "152746+01") - '(46 27 15 nil nil nil nil nil 3600))) + '(46 27 15 nil nil nil nil -1 3600))) (should (equal (iso8601-parse-time "15:27:46+01") - '(46 27 15 nil nil nil nil nil 3600))) + '(46 27 15 nil nil nil nil -1 3600))) (should (equal (iso8601-parse-time "152746-0500") - '(46 27 15 nil nil nil nil nil -18000))) + '(46 27 15 nil nil nil nil -1 -18000))) (should (equal (iso8601-parse-time "15:27:46-0500") - '(46 27 15 nil nil nil nil nil -18000))) + '(46 27 15 nil nil nil nil -1 -18000))) (should (equal (iso8601-parse-time "152746-05") - '(46 27 15 nil nil nil nil nil -18000))) + '(46 27 15 nil nil nil nil -1 -18000))) (should (equal (iso8601-parse-time "15:27:46-05") - '(46 27 15 nil nil nil nil nil -18000)))) + '(46 27 15 nil nil nil nil -1 -18000)))) (defun test-iso8601-format-time-string-zone-round-trip (offset-minutes z-format) commit 4b44eaa1f9c3c7b77ce1b5c14e5195c0fac75950 Author: Paul Eggert Date: Sun May 29 08:52:13 2022 -0700 Doc fix for dst flag * doc/lispref/os.texi (Time Conversion): Note Common Lisp dst differs. diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index f4dd2e7072..11a0d02338 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1649,8 +1649,8 @@ this default may change in future Emacs releases, so callers requiring a particular form should specify @var{form}. @strong{Common Lisp Note:} Common Lisp has different meanings for -@var{dow} and @var{utcoff}, and its @var{second} is an integer between -0 and 59 inclusive. +@var{dow}, @code{dst} and @var{utcoff}, and its @var{second} is an +integer between 0 and 59 inclusive. To access (or alter) the elements in the calendrical information, the @code{decoded-time-second}, @code{decoded-time-minute}, commit aa955dc569b361771e4d2b3b1d7b90c1ceea8b6a Author: Stefan Monnier Date: Sun May 29 13:37:44 2022 -0400 * lisp/shell.el (shell): Fix last change Wrap the file-name prompt within `with-connection-local-variables` as it was before the previous change. While at it, make sure we set the `default-directory` of the actual shell buffer after querying the user. diff --git a/lisp/shell.el b/lisp/shell.el index 1fcd1a1d1c..8bcc578406 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -755,38 +755,47 @@ Make the shell buffer the current buffer, and return it. \(Type \\[describe-mode] in the shell buffer for a list of commands.)" (interactive - (list - (and current-prefix-arg - (prog1 - (read-buffer "Shell buffer: " - ;; If the current buffer is an inactive - ;; shell buffer, use it as the default. - (if (and (eq major-mode 'shell-mode) - (null (get-buffer-process (current-buffer)))) - (buffer-name) - (generate-new-buffer-name "*shell*"))) - (if (file-remote-p default-directory) - ;; It must be possible to declare a local default-directory. - ;; FIXME: This can't be right: it changes the default-directory - ;; of the current-buffer rather than of the *shell* buffer. - (setq default-directory - (expand-file-name - (read-directory-name - "Default directory: " default-directory default-directory - t nil)))))) - ;; On remote hosts, the local `shell-file-name' might be useless. - (when (and (file-remote-p default-directory) - (null explicit-shell-file-name) - (null (getenv "ESHELL"))) - ;; `expand-file-name' shall not add the MS Windows volume letter - ;; (Bug#49229). - (replace-regexp-in-string - "^[[:alpha:]]:" "" - (file-local-name - (expand-file-name - (read-file-name "Remote shell path: " default-directory - shell-file-name t shell-file-name - #'file-remote-p))))))) + (let* ((buffer + (and current-prefix-arg + (read-buffer "Shell buffer: " + ;; If the current buffer is an inactive + ;; shell buffer, use it as the default. + (if (and (eq major-mode 'shell-mode) + (null (get-buffer-process + (current-buffer)))) + (buffer-name) + (generate-new-buffer-name "*shell*"))))) + (buf (if (or buffer (not (derived-mode-p 'shell-mode)) + (comint-check-proc (current-buffer))) + (get-buffer-create (or buffer "*shell*")) + ;; If the current buffer is a dead shell buffer, use it. + (current-buffer)))) + + (with-current-buffer buf + (when (and buffer (file-remote-p default-directory)) + ;; It must be possible to declare a local default-directory. + (setq default-directory + (expand-file-name + (read-directory-name + "Default directory: " default-directory default-directory + t nil)))) + (list + buffer + ;; On remote hosts, the local `shell-file-name' might be useless. + (with-connection-local-variables + (when (and (file-remote-p default-directory) + (null explicit-shell-file-name) + (null (getenv "ESHELL"))) + ;; `expand-file-name' shall not add the MS Windows volume letter + ;; (Bug#49229). + (replace-regexp-in-string + "^[[:alpha:]]:" "" + (file-local-name + (expand-file-name + (read-file-name "Remote shell path: " default-directory + shell-file-name t shell-file-name + #'file-remote-p)))))))))) + (setq buffer (if (or buffer (not (derived-mode-p 'shell-mode)) (comint-check-proc (current-buffer))) (get-buffer-create (or buffer "*shell*")) commit e1eab9b49619c4075950bc99fff0ca129cc91308 Author: Eli Zaretskii Date: Sun May 29 20:12:56 2022 +0300 ; Fix Batak greeting * etc/HELLO: * lisp/language/indonesian.el ("Batak"): Fix greeting. diff --git a/etc/HELLO b/etc/HELLO index 2c4ae26ca6..7f49c613f6 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -28,7 +28,7 @@ Amharic (አማርኛ) ሠላም Arabic (العربيّة) السّلام عليكم Armenian (հայերեն) Բարև ձեզ Balinese (ᬅᬓ᭄ᬱᬭᬩᬮᬶ) ᬒᬁᬲ᭄ᬯᬲ᭄ᬢ᭄ᬬᬲ᭄ᬢᬸ -Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲, ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ +Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲ / ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ Belarusian (беларуская) Прывітанне Bengali (বাংলা) নমস্কার Brahmi (𑀩𑁆𑀭𑀸𑀳𑁆𑀫𑀻) 𑀦𑀫𑀲𑁆𑀢𑁂 diff --git a/lisp/language/indonesian.el b/lisp/language/indonesian.el index 701945ae9b..c65c1cd5d0 100644 --- a/lisp/language/indonesian.el +++ b/lisp/language/indonesian.el @@ -59,7 +59,7 @@ Sundanese language and its script are supported in this language environment.")) (coding-system utf-8) (coding-priority utf-8) (input-method . "batak") - (sample-text . "Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲, ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ") + (sample-text . "Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲ / ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ") (documentation . "\ Languages that use the Batak script, such as Karo, Toba, Pakpak, Mandailing and Simalungun, are supported in this language environment."))) commit f02a8374d591aa02de4a98c4127120404d0b1d3d Author: Eli Zaretskii Date: Sun May 29 19:35:15 2022 +0300 ; Fix last change (bug#55694) * etc/HELLO ("Batak"): Add one more greeting. * lisp/language/indonesian.el ("Batak"): Fix doc string and add one more greeting. diff --git a/etc/HELLO b/etc/HELLO index c89f8943c7..2c4ae26ca6 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -28,7 +28,7 @@ Amharic (አማርኛ) ሠላም Arabic (العربيّة) السّلام عليكم Armenian (հայերեն) Բարև ձեզ Balinese (ᬅᬓ᭄ᬱᬭᬩᬮᬶ) ᬒᬁᬲ᭄ᬯᬲ᭄ᬢ᭄ᬬᬲ᭄ᬢᬸ -Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲ +Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲, ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ Belarusian (беларуская) Прывітанне Bengali (বাংলা) নমস্কার Brahmi (𑀩𑁆𑀭𑀸𑀳𑁆𑀫𑀻) 𑀦𑀫𑀲𑁆𑀢𑁂 diff --git a/lisp/language/indonesian.el b/lisp/language/indonesian.el index 319ec48158..701945ae9b 100644 --- a/lisp/language/indonesian.el +++ b/lisp/language/indonesian.el @@ -59,10 +59,10 @@ Sundanese language and its script are supported in this language environment.")) (coding-system utf-8) (coding-priority utf-8) (input-method . "batak") - (sample-text . "Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲") + (sample-text . "Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲, ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ") (documentation . "\ -Such languages using the Batak script such as Karo, Toba, Pakpak, Mandailing -and Simalungun are supported in this language environment."))) +Languages that use the Batak script, such as Karo, Toba, Pakpak, Mandailing +and Simalungun, are supported in this language environment."))) ;; Balinese composition rules (let ((consonant "[\x1B13-\x1B33\x1B45-\x1B4B]") commit 230ed406aae59b4cebb024f6020241422a29e240 Author: समीर सिंह Sameer Singh Date: Sun May 29 18:55:58 2022 +0530 Add support for the Batak script (bug #55694) * lisp/language/indonesian.el ("Batak"): New language environment. Add composition rules for Batak. Add sample text and input method. * lisp/international/fontset.el (script-representative-chars) (setup-default-fontset): Support Batak. * lisp/leim/quail/indonesian.el ("batak"): New input method. Rename TITLE of balinese, javanese and sundanese in ("quail-define-package"). * etc/HELLO: Add a Batak greeting. * etc/NEWS: Announce the new language environment and its input method. diff --git a/etc/HELLO b/etc/HELLO index 4ff066847d..c89f8943c7 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -28,6 +28,7 @@ Amharic (አማርኛ) ሠላም Arabic (العربيّة) السّلام عليكم Armenian (հայերեն) Բարև ձեզ Balinese (ᬅᬓ᭄ᬱᬭᬩᬮᬶ) ᬒᬁᬲ᭄ᬯᬲ᭄ᬢ᭄ᬬᬲ᭄ᬢᬸ +Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲ Belarusian (беларуская) Прывітанне Bengali (বাংলা) নমস্কার Brahmi (𑀩𑁆𑀭𑀸𑀳𑁆𑀫𑀻) 𑀦𑀫𑀲𑁆𑀢𑁂 diff --git a/etc/NEWS b/etc/NEWS index d8d22449f7..5987acdac9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -836,6 +836,7 @@ corresponding language environments are: **** Balinese script and language environment **** Javanese script and language environment **** Sundanese script and language environment +**** Batak script and language environment --- *** The "Oriya" language environment was renamed to "Odia". diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 00ee0cf475..bf4b9b578e 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -191,6 +191,7 @@ (limbu #x1901 #x1920 #x1936) (balinese #x1B13 #x1B35 #x1B5E) (sundanese #x1B8A #x1BAB #x1CC4) + (batak #x1BC2 #x1BE7 #x1BFF) (tai-le #x1950) (tai-lue #x1980) (tai-tham #x1A20 #x1A55 #x1A61 #x1A80) @@ -762,6 +763,7 @@ limbu balinese sundanese + batak symbol braille yi diff --git a/lisp/language/indonesian.el b/lisp/language/indonesian.el index 4bdcd0a49c..319ec48158 100644 --- a/lisp/language/indonesian.el +++ b/lisp/language/indonesian.el @@ -54,6 +54,16 @@ Javanese language and its script are supported in this language environment."))) (documentation . "\ Sundanese language and its script are supported in this language environment."))) +(set-language-info-alist + "Batak" '((charset unicode) + (coding-system utf-8) + (coding-priority utf-8) + (input-method . "batak") + (sample-text . "Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲") + (documentation . "\ +Such languages using the Batak script such as Karo, Toba, Pakpak, Mandailing +and Simalungun are supported in this language environment."))) + ;; Balinese composition rules (let ((consonant "[\x1B13-\x1B33\x1B45-\x1B4B]") (independent-vowel "[\x1B05-\x1B12]") @@ -119,5 +129,19 @@ Sundanese language and its script are supported in this language environment.")) vowel "?" modifier-above "?" dependant-consonant "?") 1 'font-shape-gstring)))) +;; Batak composition rules +(let ((akshara "[\x1BC0-\x1BE5]") + (vowel "[\x1BE7-\x1BEF]") + (dependant-consonant "[\x1BF0\x1BF1]") + (modifier-above "\x1BE6") + (virama "[\x1BF2\x1BF3]")) + (set-char-table-range composition-function-table + '(#x1BE6 . #x1BF3) + (list (vector + ;; Akshara based syllables + (concat akshara virama "?" vowel "*" modifier-above + "?" dependant-consonant "?") + 1 'font-shape-gstring)))) + (provide 'indonesian) ;;; indonesian.el ends here diff --git a/lisp/leim/quail/indonesian.el b/lisp/leim/quail/indonesian.el index 3a0654db90..fd232c4f71 100644 --- a/lisp/leim/quail/indonesian.el +++ b/lisp/leim/quail/indonesian.el @@ -32,7 +32,7 @@ ;; Javanese. (quail-define-package - "balinese" "Balinese" "ᬅ" t "Balinese phonetic input method. + "balinese" "Balinese" "ᬩ" t "Balinese phonetic input method. `\\=`' is used to switch levels instead of Alt-Gr. " nil t t t t nil nil nil nil nil t) @@ -174,7 +174,7 @@ ("`M" ?ᬀ)) (quail-define-package - "javanese" "Javanese" "ꦄ" t "Javanese phonetic input method. + "javanese" "Javanese" "ꦗ" t "Javanese phonetic input method. `\\=`' is used to switch levels instead of Alt-Gr. " nil t t t t nil nil nil nil nil t) @@ -287,7 +287,7 @@ ("`m" ?ꦀ)) (quail-define-package - "sundanese" "Sundanese" "ᮃ" t "Sundanese phonetic input method. + "sundanese" "Sundanese" "ᮞᮥ" t "Sundanese phonetic input method. `\\=`' is used to switch levels instead of Alt-Gr. " nil t t t t nil nil nil nil nil t) @@ -377,5 +377,71 @@ ("`m" ?ᮿ) ("`M" ?ᮬ)) +(quail-define-package + "batak" "Batak" "ᯅ" t "Batak phonetic input method, + used by languages such as Karo, Toba, Pakpak, Mandailing + and Simalungun. + + `\\=`' is used to switch levels instead of Alt-Gr. +" nil t t t t nil nil nil nil nil t) + +(quail-define-rules + ("q" ?᯼) + ("Q" ?᯽) + ("w" ?ᯋ) + ("W" ?ᯌ) + ("`w" ?ᯍ) + ("e" ?ᯧ) + ("E" ?ᯨ) + ("`e" ?ᯩ) + ("r" ?ᯒ) + ("R" ?ᯓ) + ("t" ?ᯖ) + ("T" ?ᯗ) + ("y" ?ᯛ) + ("Y" ?ᯜ) + ("u" ?ᯮ) + ("U" ?ᯥ) + ("`u" ?ᯯ) + ("i" ?ᯪ) + ("I" ?ᯫ) + ("`i" ?ᯤ) + ("o" ?ᯬ) + ("O" ?ᯭ) + ("p" ?ᯇ) + ("P" ?ᯈ) + ("a" ?ᯀ) + ("A" ?ᯁ) + ("s" ?ᯘ) + ("S" ?ᯙ) + ("`s" ?ᯚ) + ("d" ?ᯑ) + ("f" ?᯲) + ("F" ?᯳) + ("g" ?ᯎ) + ("G" ?ᯏ) + ("h" ?ᯂ) + ("H" ?ᯃ) + ("`h" ?ᯄ) + ("`H" ?ᯱ) + ("j" ?ᯐ) + ("k" ?᯦) + ("l" ?ᯞ) + ("L" ?ᯟ) + ("z" ?ᯝ) + ("Z" ?ᯰ) + ("x" ?ᯠ) + ("c" ?ᯡ) + ("v" ?᯾) + ("V" ?᯿) + ("b" ?ᯅ) + ("B" ?ᯆ) + ("n" ?ᯉ) + ("N" ?ᯊ) + ("`n" ?ᯢ) + ("m" ?ᯔ) + ("M" ?ᯕ) + ("`m" ?ᯣ)) + (provide 'indonesian) ;;; indonesian.el ends here commit e06d600b4963fc6ccc69fb0bbbc725350a80c9fc Author: Lars Ingebrigtsen Date: Sun May 29 16:40:53 2022 +0200 Fix hfy-etags-cmd type * lisp/htmlfontify.el (hfy-etags-cmd): Fix the type -- this variable usually ends up being nil. diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el index a809e61da7..89cacdff21 100644 --- a/lisp/htmlfontify.el +++ b/lisp/htmlfontify.el @@ -364,7 +364,7 @@ the etags output on stdout. Two canned commands are provided - they drive Emacs's etags and exuberant-ctags' etags respectively." :tag "etags-command" - :type (let ((clist (list '(string)))) + :type (let ((clist (list '(string) '(const :tag "None" nil)))) (dolist (C hfy-etags-cmd-alist) (push (list 'const :tag (car C) (cdr C)) clist)) (cons 'choice clist))) commit f7324b7a64424500251f00a796d2d6ed26e716b6 Author: Daniel Martín Date: Sun May 29 16:31:38 2022 +0200 Fix reference to help-enable-variable-value-editing * lisp/help-mode.el (help-mode): Fix docstring to reference the correct variable name. * lisp/ldefs-boot.el (help-mode): Ditto (bug#55705). diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 3bd272b723..2fcb8b9f3e 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -404,7 +404,7 @@ The format is (FUNCTION ARGS...).") ;;;###autoload (define-derived-mode help-mode special-mode "Help" "Major mode for viewing help text and navigating references in it. -Also see the `help-enable-editing' variable. +Also see the `help-enable-variable-value-editing' variable. Commands: \\{help-mode-map}" diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 362c3221c6..690da5bb49 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -16524,7 +16524,7 @@ gives the window that lists the options.") (autoload 'help-mode "help-mode" "\ Major mode for viewing help text and navigating references in it. -Also see the `help-enable-editing' variable. +Also see the `help-enable-variable-value-editing' variable. Commands: \\{help-mode-map} commit fe8a127de2bac8eb37f9adccc20195a3b4be25df Author: Po Lu Date: Sun May 29 20:13:25 2022 +0800 * etc/tutorial/TUTORIAL.cn (INSTALLING PACKAGES): Translate from English. diff --git a/etc/tutorials/TUTORIAL.cn b/etc/tutorials/TUTORIAL.cn index 5d03014e41..770d9a83be 100644 --- a/etc/tutorials/TUTORIAL.cn +++ b/etc/tutorials/TUTORIAL.cn @@ -905,6 +905,15 @@ Dired 能够在一个缓冲区里列出一个目录下的所有文件(可以 Emacs 使用手册里还有许许多多的精彩功能等着你来了解。 +* 安装包裹(INSTALLING PACKAGES) +--------------------------- + +Emacs 社区著作了许多持有扩展性的包裹(packages),其中包括对各种语言的 +支持、色彩鲜艳的主题、用于集成外部程序的包裹,等等。 + +使用 M-x list-packages 便可浏览存在的包裹。这个命令显示的界面中可以安 +装和卸载包裹,以及查看包裹的简介。Emacs 使用手册中有对包裹管理更详细的 +介绍。 * 总结(CONCLUSION) -------------------- commit 1b7b69e764370288583aeeda38069a3c8f9ec912 (refs/remotes/origin/emacs-28) Author: Michael Albinus Date: Sun May 29 13:31:32 2022 +0200 Some Tramp cleanup on MS Windows * lisp/net/tramp.el (tramp-restricted-shell-hosts-alist): Do not add localhost when `tramp-encoding-shell' is a POSIX shell. * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process): Skip on MS Windows. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 63ea8a283c..3ee1169139 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -497,7 +497,8 @@ interpreted as a regular expression which always matches." ;; either lower case or upper case letters. See ;; . (defcustom tramp-restricted-shell-hosts-alist - (when (eq system-type 'windows-nt) + (when (and (eq system-type 'windows-nt) + (not (string-match-p "sh$" tramp-encoding-shell))) (list (format "\\`\\(%s\\|%s\\)\\'" (regexp-quote (downcase tramp-system-name)) (regexp-quote (upcase tramp-system-name))))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index dbf62dbc1c..61fa6a5ae4 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -5019,6 +5019,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." '(:unstable))) (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) + (skip-unless (not (tramp--test-windows-nt-p))) (skip-unless (not (tramp--test-crypt-p))) ;; Since Emacs 26.1. (skip-unless (boundp 'interrupt-process-functions)) commit f0bf7f03f8172d6abe274668c39fb160e1870cf5 Author: Mattias Engdegård Date: Sun May 29 10:54:25 2022 +0200 ; * lisp/leim/quail/indonesian.el: Remove ineffective backslashes. diff --git a/lisp/leim/quail/indonesian.el b/lisp/leim/quail/indonesian.el index 84773b4a8c..3a0654db90 100644 --- a/lisp/leim/quail/indonesian.el +++ b/lisp/leim/quail/indonesian.el @@ -64,10 +64,10 @@ ("`*" ?᭲) ("9" ?᭙) ("`9" ?9) - ("`\(" ?᭳) + ("`(" ?᭳) ("0" ?᭐) ("`0" ?0) - ("`\)" ?᭼) + ("`)" ?᭼) ("`\\" ?᭞) ("`|" ?᭟) ("`" ?ᬝ) @@ -206,10 +206,10 @@ ("`*" ?꧈) ("9" ?꧙) ("`9" ?9) - ("`\(" ?꧉) + ("`(" ?꧉) ("0" ?꧐) ("`0" ?0) - ("`\)" ?꧞) + ("`)" ?꧞) ("`\\" ?꧊) ("`|" ?꧋) ("`" ?ꦛ) commit c9aff6fe5a26ca402b0f0bc89f71a2cc46671882 Author: Mattias Engdegård Date: Sun May 29 10:49:13 2022 +0200 Traverse record literals in byte-compile--first-symbol-with-pos * lisp/emacs-lisp/bytecomp.el (byte-compile--first-symbol-with-pos): Traverse record literals as well as vectors. Either is rather pointless but there were some strong feelings about it. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index ee530f95d0..5d16d55089 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1195,7 +1195,7 @@ Order is by depth-first search." (setq form (cdr form))) (or sym (and form (byte-compile--first-symbol-with-pos form)))))) - ((vectorp form) + ((or (vectorp form) (recordp form)) (let ((len (length form)) (i 0) (sym nil)) commit 96d056b3aa7bc689e2550bddd56f51a88c69fe2f Author: Po Lu Date: Sun May 29 16:32:34 2022 +0800 * admin/alloc-colors.c: Fix missing declaration. diff --git a/admin/alloc-colors.c b/admin/alloc-colors.c index 4db447332b..b78dd42b7e 100644 --- a/admin/alloc-colors.c +++ b/admin/alloc-colors.c @@ -23,6 +23,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include void fatal (const char *fmt, ...) commit 232a6ee9c60a41a22d9264683d26780145add6a6 Author: Eli Zaretskii Date: Sun May 29 11:00:36 2022 +0300 ; * etc/NEWS: Fix last change. diff --git a/etc/NEWS b/etc/NEWS index 1165ac37b2..d8d22449f7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -331,7 +331,7 @@ a convenient method of making commands disabled in this way. ** 'count-lines' will now report buffer totals if given a prefix. +++ -** 'count-words' will now report sentences count when used interactively. +** 'count-words' will now report sentence count when used interactively. --- ** New user option 'find-library-include-other-files'. commit 460d5fd971489ba7b573d71a94cdaac2f9f1a767 Author: Manuel Giraud Date: Fri May 20 13:52:28 2022 +0200 Make `count-words' count sentences. * lisp/textmodes/paragraphs.el (count-sentences): New function. * lisp/simple.el (count-words--format): Update format for showing sentences. (count-words): Also count sentences. * lisp/simple.el (count-words): * etc/NEWS: * doc/emacs/basic.texi (Position Info): Update documentation for sentence counting. diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi index 196a28be5a..b93a6d5de6 100644 --- a/doc/emacs/basic.texi +++ b/doc/emacs/basic.texi @@ -653,14 +653,14 @@ Toggle automatic display of the current line number or column number. displayed before each line, see @ref{Display Custom}. @item M-= -Display the number of lines, words, and characters that are present in -the region (@code{count-words-region}). @xref{Mark}, for information -about the region. +Display the number of lines, sentences, words, and characters that are +present in the region (@code{count-words-region}). @xref{Mark}, for +information about the region. @item M-x count-words -Display the number of lines, words, and characters that are present in -the buffer. If the region is active (@pxref{Mark}), display the -numbers for the region instead. +Display the number of lines, sentences, words, and characters that are +present in the buffer. If the region is active (@pxref{Mark}), +display the numbers for the region instead. @item C-x = Display the character code of character after point, character position of @@ -689,7 +689,7 @@ narrowed region and the line number relative to the whole buffer. @kindex M-= @findex count-words-region @kbd{M-=} (@code{count-words-region}) displays a message reporting -the number of lines, words, and characters in the region +the number of lines, sentences, words, and characters in the region (@pxref{Mark}, for an explanation of the region). With a prefix argument, @kbd{C-u M-=}, the command displays a count for the entire buffer. diff --git a/etc/NEWS b/etc/NEWS index 85a0ee44b9..1165ac37b2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -330,6 +330,9 @@ a convenient method of making commands disabled in this way. --- ** 'count-lines' will now report buffer totals if given a prefix. ++++ +** 'count-words' will now report sentences count when used interactively. + --- ** New user option 'find-library-include-other-files'. If set to nil, commands like 'find-library' will only include library diff --git a/lisp/simple.el b/lisp/simple.el index db52d83cea..a254ee2251 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1667,8 +1667,9 @@ START and END." If called interactively, START and END are normally the start and end of the buffer; but if the region is active, START and END are the start and end of the region. Print a message reporting the -number of lines, words, and chars. With prefix argument, also -include the data for the entire (un-narrowed) buffer. +number of lines, sentences, words, and chars. With prefix +argument, also include the data for the entire (un-narrowed) +buffer. If called from Lisp, return the number of words between START and END, without printing any message. TOTALS is ignored when called @@ -1708,11 +1709,13 @@ from Lisp." (defun count-words--format (str start end) (let ((lines (count-lines start end)) + (sentences (count-sentences start end)) (words (count-words start end)) (chars (- end start))) - (format "%s has %d line%s, %d word%s, and %d character%s" + (format "%s has %d line%s, %d sentence%s, %d word%s, and %d character%s" str lines (if (= lines 1) "" "s") + sentences (if (= sentences 1) "" "s") words (if (= words 1) "" "s") chars (if (= chars 1) "" "s")))) diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index 7daf71e990..98eb494823 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -477,7 +477,23 @@ sentences. Also, every paragraph boundary terminates sentences as well." (skip-chars-backward " \t\n") (goto-char par-end))) (setq arg (1- arg))) - (constrain-to-field nil opoint t))) + (let ((npoint (constrain-to-field nil opoint t))) + (not (= npoint opoint))))) + +(defun count-sentences (start end) + "Count sentences in current buffer from START to END." + (let ((sentences 0) + (inhibit-field-text-motion t)) + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (while (ignore-errors (forward-sentence)) + (setq sentences (1+ sentences))) + ;; Remove last possibly empty sentence + (when (/= (skip-chars-backward " \t\n") 0) + (setq sentences (1- sentences))) + sentences)))) (defun repunctuate-sentences-filter (_start _end) "Search filter used by `repunctuate-sentences' to skip unneeded spaces. commit 6f8e856ada08abf4cd29f03fe379a66693a78ba3 Author: Po Lu Date: Sun May 29 15:49:48 2022 +0800 Keep display mm width and height up to date after changes * src/xfns.c (Fx_display_mm_width, Fx_display_mm_height): Use new fields if they are set. * src/xterm.c (handle_one_xevent): Set new fields on RRNotify if the screen is correct. * src/xterm.h (struct x_display_info): New fields `screen_mm_width', `screen_mm_height'. diff --git a/src/xfns.c b/src/xfns.c index 401ad81695..8237e8870c 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5434,6 +5434,9 @@ for each physical monitor, use `display-monitor-attributes-list'. */) { struct x_display_info *dpyinfo = check_x_display_info (terminal); + if (dpyinfo->screen_mm_height) + return make_fixnum (dpyinfo->screen_mm_height); + return make_fixnum (HeightMMOfScreen (dpyinfo->screen)); } @@ -5451,6 +5454,9 @@ for each physical monitor, use `display-monitor-attributes-list'. */) { struct x_display_info *dpyinfo = check_x_display_info (terminal); + if (dpyinfo->screen_mm_width) + return make_fixnum (dpyinfo->screen_mm_width); + return make_fixnum (WidthMMOfScreen (dpyinfo->screen)); } diff --git a/src/xterm.c b/src/xterm.c index 65d3eaf83f..908185c3d1 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -20417,8 +20417,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, notify = ((XRRScreenChangeNotifyEvent *) event); timestamp = notify->timestamp; - dpyinfo->screen_width = notify->width; - dpyinfo->screen_height = notify->height; + /* Don't set screen dimensions if the notification is + for a different screen. */ + if (notify->root == dpyinfo->root_window) + { + dpyinfo->screen_width = notify->width; + dpyinfo->screen_height = notify->height; + dpyinfo->screen_mm_width = notify->mwidth; + dpyinfo->screen_mm_height = notify->mheight; + } } else timestamp = 0; diff --git a/src/xterm.h b/src/xterm.h index bc2e138aa9..c8e86d5d09 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -708,6 +708,11 @@ struct x_display_info that didn't happen. */ int screen_width; int screen_height; + + /* The mm width and height of the screen. Updated on + RRScreenChangeNotify. */ + int screen_mm_width; + int screen_mm_height; }; #ifdef HAVE_X_I18N