commit 510eb1d401b5708657819913a52a3d8ba2dc0f3f (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Apr 7 14:32:10 2022 +0800 Fix error when calling DND movement tracking function * src/xterm.c (x_dnd_begin_drag_and_drop): Verify x_dnd_movement_x and x_dnd_movement_y are wholenums before caling posn-at-x-y. diff --git a/src/xterm.c b/src/xterm.c index f5770ad7e7..57a64cb5d1 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9540,7 +9540,12 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, x_dnd_movement_frame = NULL; if (!NILP (Vx_dnd_movement_function) - && !FRAME_TOOLTIP_P (XFRAME (frame_object))) + && !FRAME_TOOLTIP_P (XFRAME (frame_object)) + && x_dnd_movement_x >= 0 + && x_dnd_movement_y >= 0 + && x_dnd_frame + && (XFRAME (frame_object) != x_dnd_frame + || x_dnd_allow_current_frame)) { x_dnd_old_window_attrs = root_window_attrs; x_dnd_unwind_flag = true; commit 57ad2f333c754c927b7cddc17a61bd73fe38a738 Author: Po Lu Date: Thu Apr 7 14:25:52 2022 +0800 * src/xterm.c (xm_write_targets_table): Remove extra XGrabServer pair. diff --git a/src/xterm.c b/src/xterm.c index 4e2091a0de..f5770ad7e7 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1311,7 +1311,6 @@ xm_write_targets_table (Display *dpy, Window wdesc, rec_buffer = xmalloc (600); rec_buffer_size = 600; - XGrabServer (dpy); XChangeProperty (dpy, wdesc, targets_table_atom, targets_table_atom, 8, PropModeReplace, (unsigned char *) ptr, 8); @@ -1334,7 +1333,6 @@ xm_write_targets_table (Display *dpy, Window wdesc, (unsigned char *) rec_buffer, 2 + recs[i]->n_targets * 4); } - XUngrabServer (dpy); xfree (rec_buffer); } commit 48bbc4a9a1606b76cac2382b93743fb22dc044c7 Author: Po Lu Date: Thu Apr 7 14:02:34 2022 +0800 Fix DND bugs on GTK * src/xterm.c (handle_one_xevent): Don't let some client messages reach the toolkit. diff --git a/src/xterm.c b/src/xterm.c index 58a4fc6117..4e2091a0de 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -13540,6 +13540,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, else x_dnd_action = None; } + + goto done; } if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished @@ -13554,6 +13556,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (x_dnd_waiting_for_finish_proto >= 5 && !(event->xclient.data.l[1] & 1)) x_dnd_action = None; + + goto done; } if ((event->xclient.message_type @@ -13579,7 +13583,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, && operation != XM_DRAG_LINK) { x_dnd_waiting_for_finish = false; - goto OTHER; + goto done; } if (status != XM_DROP_SITE_VALID @@ -13587,7 +13591,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, || action == XM_DROP_ACTION_DROP_HELP)) { x_dnd_waiting_for_finish = false; - goto OTHER; + goto done; } switch (operation) @@ -13606,7 +13610,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, } x_dnd_waiting_for_motif_finish = 2; - goto OTHER; + goto done; } } commit c6ea0772ec1878d3d894e8b370f1272f88a97ea3 Author: Po Lu Date: Thu Apr 7 11:44:59 2022 +0800 Remove more code mindlessly copied from NS * src/pgtkfns.c (Fx_open_connection): * src/pgtkselect.c (nxatoms_of_pgtkselect): * src/pgtkselect.h: * src/pgtkterm.h: Delete `nxatoms_of_pgtkselect'. diff --git a/src/pgtkfns.c b/src/pgtkfns.c index b028296720..e6ce5e2f44 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -2212,7 +2212,6 @@ terminate Emacs if we can't open the connection. */) CHECK_STRING (display); - nxatoms_of_pgtkselect (); dpyinfo = pgtk_term_init (display, SSDATA (Vx_resource_name)); if (dpyinfo == 0) { diff --git a/src/pgtkselect.c b/src/pgtkselect.c index 2f4a872a05..4c87aaa7ea 100644 --- a/src/pgtkselect.c +++ b/src/pgtkselect.c @@ -492,12 +492,6 @@ frame's display, or the first available display. */) return Qnil; } - -void -nxatoms_of_pgtkselect (void) -{ -} - void syms_of_pgtkselect (void) { diff --git a/src/pgtkselect.h b/src/pgtkselect.h index 0509c83bde..fd9910b2d1 100644 --- a/src/pgtkselect.h +++ b/src/pgtkselect.h @@ -26,8 +26,6 @@ along with GNU Emacs. If not, see . */ #include extern void pgtk_selection_init (void); -extern void pgtk_selection_lost (GtkWidget * widget, - GdkEventSelection * event, - gpointer user_data); +extern void pgtk_selection_lost (GtkWidget *, GdkEventSelection *, gpointer); #endif /* HAVE_PGTK */ diff --git a/src/pgtkterm.h b/src/pgtkterm.h index 8803b482cc..b1165752ab 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -611,9 +611,6 @@ extern void syms_of_pgtkmenu (void); extern void syms_of_pgtkselect (void); extern void syms_of_pgtkim (void); -/* Implemented in pgtkselect. */ -extern void nxatoms_of_pgtkselect (void); - /* Initialization and marking implemented in pgtkterm.c */ extern void init_pgtkterm (void); extern void mark_pgtkterm (void); commit 1f4a0828cc3fb93914d2ac12bb93013864730bd9 Author: Po Lu Date: Thu Apr 7 10:20:47 2022 +0800 ; * etc/PROBLEMS: Explain how to get dropping text on xterm to work. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 4e4ec6d353..25022cad46 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1786,6 +1786,21 @@ remote X server, try this: (setq mouse-highlight nil) +*** Dropping text on xterm doesn't work. + +Emacs sends sythetic button events to legacy clients such as xterm +that do not support either the XDND or Motif drag-and-drop protocols +in order to "paste" the text that was dropped. Unfortunately, xterm +is configured to ignore these events by default. Add the following to +your X defaults file to avoid the problem: + + XTerm.*.allowSendEvents: True + +Note that this can in theory pose a security risk, but in pratice +modern X servers have so many other ways to send input to clients +without signifying that the event is synthesized that it does not +matter. + * Runtime problems on character terminals ** The meta key does not work on xterm. commit 7108c4165f06a827492724f5ab719a04f96478da Author: Po Lu Date: Thu Apr 7 10:15:12 2022 +0800 Fix sending unsupported drops when there is no target but a toplevel * src/xterm.c (handle_one_xevent): Send unsupported drops to last seen toplevel if no target was found. diff --git a/src/xterm.c b/src/xterm.c index 274f1e9d9d..58a4fc6117 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -15549,6 +15549,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, event->xbutton.time); } } + else if (x_dnd_last_seen_toplevel != None) + { + x_set_pending_dnd_time (event->xbutton.time); + x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel, + event->xbutton.x_root, + event->xbutton.y_root, + event->xbutton.time); + } + x_dnd_last_protocol_version = -1; x_dnd_last_motif_style = XM_DRAG_STYLE_NONE; @@ -16712,6 +16721,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, xev->root_x, xev->root_y, xev->time); } } + else if (x_dnd_last_seen_toplevel != None) + { + x_set_pending_dnd_time (xev->time); + x_dnd_send_unsupported_drop (dpyinfo, + x_dnd_last_seen_toplevel, + xev->root_x, xev->root_y, + xev->time); + } x_dnd_last_protocol_version = -1; x_dnd_last_motif_style = XM_DRAG_STYLE_NONE; commit 33055c26088ee72bcca0497d1f931fabda28289a Author: Po Lu Date: Thu Apr 7 08:57:25 2022 +0800 Improve doc of x-begin-drag * doc/lispref/frames.texi (Drag and Drop): Fix typos and clarify meaning of XdndActionPrivate. diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 85f92d4f62..05c6e4b719 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -4079,19 +4079,20 @@ If @var{return-frame} is non-@code{nil} and the mouse moves over an Emacs frame after first moving out of @var{frame}, then the frame to which the mouse moves will be returned immediately. If @var{return-frame} is the symbol @code{now}, then any frame underneath -the mouse pointer will be returned and no further work will be done. -@var{return-frame} useful when you want to treat dragging content from -one frame to another specially, while also being able to drag content -to other programs, but it is not guaranteed to work on all systems and -window managers. +the mouse pointer will be returned without waiting for the mouse to +first move out of @var{frame}. @var{return-frame} is useful when you +want to treat dragging content from one frame to another specially, +while also being able to drag content to other programs, but it is not +guaranteed to work on all systems and with all window managers. If the drop was rejected or no drop target was found, this function returns @code{nil}. Otherwise, it returns a symbol describing the action the target chose to perform, which can differ from @var{action} if that isn't supported by the drop target. @code{XdndActionPrivate} is also a valid return value in addition to @code{XdndActionCopy} and -@code{XdndActionMove}, and means that the drop target chose to perform -an unspecified action. +@code{XdndActionMove}; it means that the drop target chose to perform +an unspecified action, and no further processing is required by the +caller. @end defun @node Color Names commit 1e901298e3c2324a1da73de474818db51296df40 Author: Po Lu Date: Thu Apr 7 08:55:00 2022 +0800 Return an appropriate action when performing unsupported drop * src/xterm.c (x_dnd_send_unsupported_drop): Set action to XdndActionPrivate. diff --git a/src/xterm.c b/src/xterm.c index 3b0416722b..274f1e9d9d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -952,7 +952,10 @@ static XRectangle x_dnd_mouse_rect; XdndStatus messages from the drop target. Under Motif, this is changed upon receiving a XmDROP_START message - in reply to our own. */ + in reply to our own. + + When dropping on a target that doesn't support any drag-and-drop + protocol, this is set to the atom XdndActionPrivate. */ static Atom x_dnd_action; /* The action we want the drop target to perform. The drop target may @@ -2897,6 +2900,8 @@ x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_windo x_dnd_n_targets, atom_names)) return; + x_dnd_action = dpyinfo->Xatom_XdndActionPrivate; + for (i = x_dnd_n_targets; i > 0; --i) { targets = Fcons (build_string (atom_names[i - 1]), commit 340e81f47620b7d09ddc5c49c330b80e2ef635bd Author: Po Lu Date: Thu Apr 7 08:37:53 2022 +0800 * src/xselect.c (x_atom_to_symbol): Add XdndSelection. diff --git a/src/xselect.c b/src/xselect.c index 2969c816a3..f855980a30 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -285,6 +285,8 @@ x_atom_to_symbol (struct x_display_info *dpyinfo, Atom atom) return QTARGETS; if (atom == dpyinfo->Xatom_NULL) return QNULL; + if (atom == dpyinfo->Xatom_XdndSelection) + return QXdndSelection; block_input (); x_catch_errors (dpyinfo->display); commit 9a15e15b62047057cf9058b442bd00c02ab7feab Author: Vincent Belaïche Date: Wed Apr 6 22:59:43 2022 +0200 Fix ses-tests.el * lisp/ses.el (ses-jump-cell-name-function): Docstring typo. * test/lisp/ses-tests.el (ses--cells, foo, bar, B2, toto): Do not do any outer defvar, but set the defvar only under the with-suppressed-warnings directive to silence the byte-compiler. diff --git a/lisp/ses.el b/lisp/ses.el index 838f795d6a..59e10e777f 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -115,7 +115,7 @@ Set it to 'upcase to make cell name change case isensitive. May return * a string, in this case this must be a cell name. -* a (row . col) cons cell, in this case that must be valid cell coordinate." +* a (row . col) cons cell, in this case that must be valid cell coordinates." :type 'function) (defcustom ses-jump-prefix-function #'ses-jump-prefix diff --git a/test/lisp/ses-tests.el b/test/lisp/ses-tests.el index 2d58e38898..2322ea9d79 100644 --- a/test/lisp/ses-tests.el +++ b/test/lisp/ses-tests.el @@ -26,9 +26,20 @@ (require 'ses) ;; Silence byte-compiler. -(with-suppressed-warnings ((lexical A2) (lexical A3)) +(with-suppressed-warnings ((lexical ses--cells) + (lexical A2) + (lexical A3) + (lexical foo) + (lexical bar) + (lexical B2) + (lexical toto)) + (defvar ses--cells) (defvar A2) - (defvar A3)) + (defvar A3) + (defvar foo) + (defvar bar) + (defvar B2) + (defvar toto)) ;; PLAIN FORMULA TESTS ;; ====================================================================== @@ -59,11 +70,8 @@ equal to 2. This is done using interactive calls." ;; PLAIN CELL RENAMING TESTS ;; ====================================================================== -(defvar ses--foo) -(defvar ses--cells) - (ert-deftest ses-tests-lowlevel-renamed-cell () - "Check that renaming A1 to `ses--foo' and setting `ses--foo' to 1 and A2 to (1+ ses--foo), makes A2 value equal to 2. + "Check that renaming A1 to `foo' and setting `foo' to 1 and A2 to (1+ foo), makes A2 value equal to 2. This is done using low level functions, `ses-rename-cell' is not called but instead we use text replacement in the buffer previously passed in text mode." @@ -77,63 +85,63 @@ previously passed in text mode." (text-mode) (goto-char (point-min)) (while (re-search-forward "\\" nil t) - (replace-match "ses--foo" t t)) + (replace-match "foo" t t)) (ses-mode) (should-not (local-variable-p 'A1)) - (should (eq ses--foo 1)) - (should (equal (ses-cell-formula 1 0) '(ses-safe-formula (1+ ses--foo)))) + (should (eq foo 1)) + (should (equal (ses-cell-formula 1 0) '(ses-safe-formula (1+ foo)))) (should (eq (bound-and-true-p A2) 2))))) (ert-deftest ses-tests-renamed-cell () - "Check that renaming A1 to `ses--foo' and setting `ses--foo' to 1 and A2 -to (1+ ses--foo), makes A2 value equal to 2." + "Check that renaming A1 to `foo' and setting `foo' to 1 and A2 +to (1+ foo), makes A2 value equal to 2." (let ((ses-initial-size '(2 . 1))) (with-temp-buffer (ses-mode) - (ses-rename-cell 'ses--foo (ses-get-cell 0 0)) - (dolist (c '((0 0 1) (1 0 (1+ ses--foo)))) + (ses-rename-cell 'foo (ses-get-cell 0 0)) + (dolist (c '((0 0 1) (1 0 (1+ foo)))) (apply 'funcall-interactively 'ses-edit-cell c)) (ses-command-hook) (should-not (local-variable-p 'A1)) - (should (eq ses--foo 1)) - (should (equal (ses-cell-formula 1 0) '(1+ ses--foo))) + (should (eq foo 1)) + (should (equal (ses-cell-formula 1 0) '(1+ foo))) (should (eq (bound-and-true-p A2) 2))))) (ert-deftest ses-tests-renamed-cell-after-setting () "Check that setting A1 to 1 and A2 to (1+ A1), and then -renaming A1 to `ses--foo' makes `ses--foo' value equal to 2." +renaming A1 to `foo' makes `foo' value equal to 2." (let ((ses-initial-size '(2 . 1))) (with-temp-buffer (ses-mode) (dolist (c '((0 0 1) (1 0 (1+ A1)))) (apply 'funcall-interactively 'ses-edit-cell c)) (ses-command-hook); deferred recalc - (ses-rename-cell 'ses--foo (ses-get-cell 0 0)) + (ses-rename-cell 'foo (ses-get-cell 0 0)) (should-not (local-variable-p 'A1)) - (should (eq ses--foo 1)) - (should (equal (ses-cell-formula 1 0) '(1+ ses--foo))) + (should (eq foo 1)) + (should (equal (ses-cell-formula 1 0) '(1+ foo))) (should (eq (bound-and-true-p A2) 2))))) (ert-deftest ses-tests-renaming-cell-with-one-symbol-formula () "Check that setting A1 to 1 and A2 to A1, and then renaming A1 -to `ses--foo' makes `ses--foo' value equal to 1. Then set A1 to 2 and check -that `ses--foo' becomes 2." +to `foo' makes `foo' value equal to 1. Then set A1 to 2 and check +that `foo' becomes 2." (let ((ses-initial-size '(3 . 1))) (with-temp-buffer (ses-mode) (dolist (c '((0 0 1) (1 0 A1))) (apply 'funcall-interactively 'ses-edit-cell c)) (ses-command-hook); deferred recalc - (ses-rename-cell 'ses--foo (ses-get-cell 0 0)) + (ses-rename-cell 'foo (ses-get-cell 0 0)) (ses-command-hook); deferred recalc (should-not (local-variable-p 'A1)) - (should (eq ses--foo 1)) - (should (equal (ses-cell-formula 1 0) 'ses--foo)) + (should (eq foo 1)) + (should (equal (ses-cell-formula 1 0) 'foo)) (should (eq (bound-and-true-p A2) 1)) (funcall-interactively 'ses-edit-cell 0 0 2) (ses-command-hook); deferred recalc (should (eq (bound-and-true-p A2) 2)) - (should (eq ses--foo 2))))) + (should (eq foo 2))))) ;; ROW INSERTION TESTS @@ -155,11 +163,10 @@ to A2 and inserting a row, makes A2 value empty, and A3 equal to (should-not (bound-and-true-p A2)) (should (eq (bound-and-true-p A3) 2))))) -(defvar ses--bar) (ert-deftest ses-tests-renamed-cells-row-insertion () - "Check that setting A1 to 1 and A2 to (1+ A1), and then renaming A1 to `ses--foo' and A2 to `ses--bar' jumping -to `ses--bar' and inserting a row, makes A2 value empty, and `ses--bar' equal to + "Check that setting A1 to 1 and A2 to (1+ A1), and then renaming A1 to `foo' and A2 to `bar' jumping +to `bar' and inserting a row, makes A2 value empty, and `bar' equal to 2." (let ((ses-initial-size '(2 . 1))) (with-temp-buffer @@ -167,16 +174,16 @@ to `ses--bar' and inserting a row, makes A2 value empty, and `ses--bar' equal to (dolist (c '((0 0 1) (1 0 (1+ A1)))) (apply 'funcall-interactively 'ses-edit-cell c)) (ses-command-hook) - (ses-rename-cell 'ses--foo (ses-get-cell 0 0)) + (ses-rename-cell 'foo (ses-get-cell 0 0)) (ses-command-hook) - (ses-rename-cell 'ses--bar (ses-get-cell 1 0)) + (ses-rename-cell 'bar (ses-get-cell 1 0)) (ses-command-hook) - (should (eq ses--bar 2)) - (ses-jump 'ses--bar) + (should (eq bar 2)) + (ses-jump 'bar) (ses-insert-row 1) (ses-command-hook) (should-not (bound-and-true-p A2)) - (should (eq ses--bar 2))))) + (should (eq bar 2))))) ;; JUMP tests @@ -224,15 +231,15 @@ to `ses--bar' and inserting a row, makes A2 value empty, and `ses--bar' equal to (should (eq (ses--cell-at-pos (point)) 'B2))))) (ert-deftest ses-jump-B2-renamed () - "Test jumping to cell B2 after renaming it `ses--toto'." + "Test jumping to cell B2 after renaming it `toto'." (let ((ses-initial-size '(3 . 3)) ses-after-entry-functions) (with-temp-buffer (ses-mode) - (ses-rename-cell 'ses--toto (ses-get-cell 1 1)) - (ses-jump 'ses--toto) + (ses-rename-cell 'toto (ses-get-cell 1 1)) + (ses-jump 'toto) (ses-command-hook) - (should (eq (ses--cell-at-pos (point)) 'ses--toto))))) + (should (eq (ses--cell-at-pos (point)) 'toto))))) (provide 'ses-tests) commit 9b8b39cce1afdf98fd4152d0750222d5053fa737 Author: Stefan Monnier Date: Wed Apr 6 14:42:33 2022 -0400 * lisp/ses.el: Fix 80-column-docstring warnings Also remove redundant `:group` args and prefer #' to quote function names. diff --git a/lisp/ses.el b/lisp/ses.el index e3b3a45776..838f795d6a 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -84,17 +84,14 @@ (defcustom ses-initial-size '(1 . 1) "Initial size of a new spreadsheet, as a cons (NUMROWS . NUMCOLS)." - :group 'ses :type '(cons (integer :tag "numrows") (integer :tag "numcols"))) (defcustom ses-initial-column-width 7 "Initial width of columns in a new spreadsheet." - :group 'ses :type '(integer :match (lambda (widget value) (> value 0)))) (defcustom ses-initial-default-printer "%.7g" "Initial default printer for a new spreadsheet." - :group 'ses :type '(choice string (list :tag "Parenthesized string" string) function)) @@ -103,30 +100,27 @@ "Things to do after entering a value into a cell. An abnormal hook that usually runs a cursor-movement function. Each function is called with ARG=1." - :group 'ses :type 'hook :options '(forward-char backward-char next-line previous-line)) (defcustom ses-mode-hook nil "Hook functions to be run upon entering SES mode." - :group 'ses :type 'hook) -(defcustom ses-jump-cell-name-function 'upcase - "Function to process the string passed to function ‘ses-jump’. Set it to 'identity to make no change. +(defcustom ses-jump-cell-name-function #'upcase + "Function to process the string passed to function ‘ses-jump’. +Set it to 'identity to make no change. Set it to 'upcase to make cell name change case isensitive. May return * a string, in this case this must be a cell name. * a (row . col) cons cell, in this case that must be valid cell coordinate." - :group 'ses :type 'function) -(defcustom ses-jump-prefix-function 'ses-jump-prefix - "Function that takes the prefix argument passed to function ‘ses-jump’. It may return the same -sort of thing as ‘ses-jump-cell-name-function’." - :group 'ses +(defcustom ses-jump-prefix-function #'ses-jump-prefix + "Function that takes the prefix argument passed to function ‘ses-jump’. +It may return the same sort of thing as ‘ses-jump-cell-name-function’." :type 'function) @@ -251,7 +245,7 @@ Used for listing local printers or renamed cells.") (suppress-keymap newmap t) ;;These keys insert themselves as the beginning of a numeric value (dotimes (x (length numeric)) - (define-key newmap (substring numeric x (1+ x)) 'ses-read-cell)) + (define-key newmap (substring numeric x (1+ x)) #'ses-read-cell)) (define-key newmap [remap clipboard-kill-region] #'ses-kill-override) (define-key newmap [remap end-of-line] #'ses-end-of-line) (define-key newmap [remap kill-line] #'ses-delete-row) @@ -363,7 +357,7 @@ printer and then modify its output.") (t (error "Unexpected elements `%S' in list `ses-localvars'" x))))) ;;; This variable is documented as being permitted in file-locals: -(put 'ses--symbolic-formulas 'safe-local-variable 'consp) +(put 'ses--symbolic-formulas 'safe-local-variable #'consp) (defconst ses-paramlines-plist '(ses--col-widths -5 ses--col-printers -4 ses--default-printer -3 @@ -1074,8 +1068,7 @@ the old and FORCE is nil." (defcustom ses-self-reference-early-detection nil "Non-nil if cycle detection is early for cells that refer to themselves." :version "24.1" - :type 'boolean - :group 'ses) + :type 'boolean) (defun ses-update-cells (list &optional force) "Recalculate cells in LIST, checking for dependency loops. @@ -2082,8 +2075,8 @@ formula: ;; Not to use tab characters for safe (tabs may do bad for column ;; calculation). indent-tabs-mode nil) - (1value (add-hook 'change-major-mode-hook 'ses-cleanup nil t)) - (1value (add-hook 'kill-buffer-hook 'ses-killbuffer-hook nil t)) + (1value (add-hook 'change-major-mode-hook #'ses-cleanup nil t)) + (1value (add-hook 'kill-buffer-hook #'ses-killbuffer-hook nil t)) (cl-pushnew (current-buffer) ses--ses-buffer-list :test 'eq) ;; This makes revert impossible if the buffer is read-only. ;; (1value (add-hook 'before-revert-hook 'ses-cleanup nil t)) @@ -2134,8 +2127,8 @@ formula: ;; find-alternate-file, post-command-hook doesn't get run for some reason, ;; so use an idle timer to make sure. (setq ses--deferred-narrow 'ses-mode) - (1value (add-hook 'post-command-hook 'ses-command-hook nil t)) - (run-with-idle-timer 0.01 nil 'ses-command-hook) + (1value (add-hook 'post-command-hook #'ses-command-hook nil t)) + (run-with-idle-timer 0.01 nil #'ses-command-hook) (run-mode-hooks 'ses-mode-hook))) (put 'ses-mode 'mode-class 'special) @@ -2252,7 +2245,9 @@ Based on the current set of columns and `window-hscroll' position." ;; Redisplay and recalculation ;;---------------------------------------------------------------------------- (defun ses-jump-prefix (prefix-int) - "Convert an integer into a (ROW . COL), by numbering cells starting from 0 from top left to bottom right, going row by row." + "Convert an integer (unversal prefix) into a (ROW . COL). +Does it by numbering cells starting from 0 from top left to bottom right, +going row by row." (and (>= prefix-int 0) (< prefix-int (* ses--numcols ses--numrows)) (cons (/ prefix-int ses--numcols) (% prefix-int ses--numcols)))) @@ -2542,7 +2537,7 @@ Return nil if cell formula was unsafe and user declined confirmation." ;; Position cursor inside close-quote. (setq initial (cons initial (length initial)))) (dolist (key ses-completion-keys) - (define-key ses-mode-edit-map key 'ses-edit-cell-complete-symbol)) + (define-key ses-mode-edit-map key #'ses-edit-cell-complete-symbol)) ;; make it globally visible, so that it can be visible from the minibuffer. (setq ses--completion-table ses--named-cell-hashmap) (list row col @@ -2639,8 +2634,9 @@ With prefix, deletes several cells." ;;---------------------------------------------------------------------------- (defun ses-read-printer-complete-symbol () (interactive) - (let ((completion-at-point-functions (cons 'ses--read-printer-completion-at-point-function - completion-at-point-functions))) + (let ((completion-at-point-functions + (cons #'ses--read-printer-completion-at-point-function + completion-at-point-functions))) (completion-at-point))) (defun ses--read-printer-completion-at-point-function () @@ -2682,7 +2678,7 @@ canceled." (setq default "") (setq prompt (format-prompt prompt default))) (dolist (key ses-completion-keys) - (define-key ses-mode-edit-map key 'ses-read-printer-complete-symbol)) + (define-key ses-mode-edit-map key #'ses-read-printer-complete-symbol)) ;; make it globally visible, so that it can be visible from the minibuffer. (setq ses--completion-table ses--local-printer-hashmap) (let ((new (read-from-minibuffer prompt @@ -4114,13 +4110,15 @@ SPAN indicates how many rightward columns to include in width (default = 0)." (ses-center value span ?- printer)) (defun ses-dashfill-span (value &optional printer) - "Print VALUE, centered using dashes within the span that starts in the -current column and continues until the next nonblank column." + "Print VALUE, centered using dashes. +Centers within the span that starts in the current column and continues +until the next nonblank column." (ses-center-span value ?- printer)) (defun ses-tildefill-span (value &optional printer) - "Print VALUE, centered using tildes within the span that starts in the -current column and continues until the next nonblank column." + "Print VALUE, centered using tildes. +Centers within the span that starts in the current column and continues +until the next nonblank column." (ses-center-span value ?~ printer)) (defun ses-prin1 (value) commit fc62efc563733819795441d41ce450d64c56ed48 Author: Po Lu Date: Wed Apr 6 20:48:06 2022 +0800 Get rid of extra sync looking up window through XTranslateCoordinates * src/xterm.c (x_dnd_get_wm_state_and_proto): Return proxy as well. (x_dnd_get_target_window): Use that proxy. diff --git a/src/xterm.c b/src/xterm.c index b6fe5fda0f..3b0416722b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2656,7 +2656,8 @@ x_dnd_get_target_window_1 (struct x_display_info *dpyinfo, static int x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo, Window window, int *wmstate_out, - int *proto_out, int *motif_out) + int *proto_out, int *motif_out, + Window *proxy_out) { #ifndef USE_XCB Atom type; @@ -2667,6 +2668,7 @@ x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo, #else xcb_get_property_cookie_t wmstate_cookie; xcb_get_property_cookie_t xdnd_proto_cookie; + xcb_get_property_cookie_t xdnd_proxy_cookie; xcb_get_property_cookie_t xm_style_cookie; xcb_get_property_reply_t *reply; xcb_generic_error_t *error; @@ -2696,6 +2698,8 @@ x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo, else *motif_out = XM_DRAG_STYLE_NONE; + *proxy_out = x_dnd_get_window_proxy (dpyinfo, window); + if (data) XFree (data); #else @@ -2709,6 +2713,10 @@ x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo, (xcb_window_t) window, (xcb_atom_t) dpyinfo->Xatom_XdndAware, XCB_ATOM_ATOM, 0, 1); + xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0, + (xcb_window_t) window, + (xcb_atom_t) dpyinfo->Xatom_XdndProxy, + XCB_ATOM_WINDOW, 0, 1); xm_style_cookie = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) window, (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO, @@ -2746,6 +2754,22 @@ x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo, free (reply); } + *proxy_out = None; + reply = xcb_get_property_reply (dpyinfo->xcb_connection, + xdnd_proxy_cookie, &error); + + if (!reply) + free (error); + else + { + if (reply->format == 32 + && reply->type == XCB_ATOM_WINDOW + && (xcb_get_property_value_length (reply) >= 4)) + *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply); + + free (reply); + } + *motif_out = XM_DRAG_STYLE_NONE; reply = xcb_get_property_reply (dpyinfo->xcb_connection, @@ -3062,7 +3086,8 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, if (child_return) { if (x_dnd_get_wm_state_and_proto (dpyinfo, child_return, - &wmstate, &proto, &motif) + &wmstate, &proto, &motif, + &proxy) /* `proto' and `motif' are set by x_dnd_get_wm_state even if getting the wm state failed. */ || proto != -1 || motif != XM_DRAG_STYLE_NONE) @@ -3075,8 +3100,6 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, return child_return; } - proxy = x_dnd_get_window_proxy (dpyinfo, child_return); - if (proxy != None) { proto = x_dnd_get_window_proto (dpyinfo, proxy); commit c0bb11432ee07228d8819cc98c6ce29ccd42ae97 Author: Po Lu Date: Wed Apr 6 20:29:30 2022 +0800 Move some X11 drag and drop processing to Lisp * lisp/term/x-win.el: Set unsupported drop function. * lisp/x-dnd.el (x-dnd-handle-unsupported-drop): New function. * src/keyboard.c (kbd_buffer_get_event): Handle UNSUPPORTED_DROP_EVENT. * src/termhooks.h (enum event_kind): New event `UNSUPPORTED_DROP_EVENT'. * src/xterm.c (x_dnd_send_unsupported_drop): Send those events instead. (x_dnd_do_unsupported_drop): Move actual unsupported drop handling here. (syms_of_xterm): New variable `x-dnd-unsupported-drop-function'. * src/xterm.h: Update prototypes. diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index f0b9b27f66..a71ae87e21 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -86,6 +86,7 @@ (defvar x-session-id) (defvar x-session-previous-id) (defvar x-dnd-movement-function) +(defvar x-dnd-unsupported-drop-function) (defun x-handle-no-bitmap-icon (_switch) (setq default-frame-alist (cons '(icon-type) default-frame-alist))) @@ -1583,6 +1584,7 @@ frames on all displays." (redisplay)) (setq x-dnd-movement-function #'x-dnd-movement) +(setq x-dnd-unsupported-drop-function #'x-dnd-handle-unsupported-drop) (provide 'x-win) (provide 'term/x-win) diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index af9c7b83d9..47d8ae14cf 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -779,6 +779,19 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." ;;; + + +;;; Handling drops. + +(defun x-dnd-handle-unsupported-drop (targets _x _y action _window-id _frame) + "Return non-nil if the drop described by TARGETS and ACTION should not proceeed." + (not (and (or (eq action 'XdndActionCopy) + (eq action 'XdndActionMove)) + (or (member "STRING" targets) + (member "UTF8_STRING" targets) + (member "COMPOUND_TEXT" targets) + (member "TEXT" targets))))) + (provide 'x-dnd) ;;; x-dnd.el ends here diff --git a/src/keyboard.c b/src/keyboard.c index d34bec48a6..d99fe4be09 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4006,6 +4006,41 @@ kbd_buffer_get_event (KBOARD **kbp, } break; +#ifdef HAVE_X_WINDOWS + case UNSUPPORTED_DROP_EVENT: + { + struct frame *f; + + kbd_fetch_ptr = next_kbd_event (event); + input_pending = readable_events (0); + + f = XFRAME (event->ie.frame_or_window); + + if (!FRAME_LIVE_P (f)) + break; + + if (!NILP (Vx_dnd_unsupported_drop_function)) + { + if (!NILP (call6 (Vx_dnd_unsupported_drop_function, + XCAR (XCDR (event->ie.arg)), event->ie.x, + event->ie.y, XCAR (XCDR (XCDR (event->ie.arg))), + make_uint (event->ie.code), + event->ie.frame_or_window))) + break; + } + + x_dnd_do_unsupported_drop (FRAME_DISPLAY_INFO (f), + event->ie.frame_or_window, + XCAR (event->ie.arg), + XCAR (XCDR (event->ie.arg)), + (Window) event->ie.code, + XFIXNUM (event->ie.x), + XFIXNUM (event->ie.y), + event->ie.timestamp); + break; + } +#endif + #ifdef HAVE_EXT_MENU_BAR case MENU_BAR_ACTIVATE_EVENT: { diff --git a/src/termhooks.h b/src/termhooks.h index 93ac9ba0d2..0f02b56e9e 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -208,6 +208,25 @@ enum event_kind representation of the dropped items. .timestamp gives a timestamp (in milliseconds) for the click. */ +#ifdef HAVE_X_WINDOWS + UNSUPPORTED_DROP_EVENT, /* Event sent when the regular C + drag-and-drop machinery could not + handle a drop to a window. + + .code is the XID of the window that + could not be dropped to. + + .arg is a list of the local value of + XdndSelection, a list of selection + targets, and the intended action to + be taken upon drop, and .timestamp + gives the timestamp where the drop + happened. + + .x and .y give the coordinates of + the drop originating from the root + window. */ +#endif USER_SIGNAL_EVENT, /* A user signal. code is a number identifying it, index into lispy_user_signals. */ diff --git a/src/xterm.c b/src/xterm.c index b6aed004ed..b6fe5fda0f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2774,45 +2774,35 @@ x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo, Dropping on windows that do not support XDND - Since middle clicking is the universal shortcut for pasting in X, - one can drop data into a window that does not support XDND by: - - 1. After the mouse has been released to trigger the drop, obtain - ownership of XA_PRIMARY. - - 2. Send a ButtonPress event and then a ButtonRelease event to the - deepest subwindow containing the mouse to simulate a middle click. - The times for these events should be the time of the actual button - release +1 and +2, respectively. These values will not be used by - anybody else, so one can unambiguously recognize the resulting - XConvertSelection() request. - - 3. If a request for XA_PRIMARY arrives bearing the timestamp of - either the ButtonPress or the ButtonRelease event, treat it as a - request for XdndSelection. Note that you must use the X data - types instead of the MIME types in this case. (e.g. XA_STRING - instead of text/plain). */ -static void -x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_window, - int root_x, int root_y, Time before) + Since middle clicking is the universal shortcut for pasting + in X, one can drop data into a window that does not support + XDND by: + + 1. After the mouse has been released to trigger the drop, + obtain ownership of XA_PRIMARY. + + 2. Send a ButtonPress event and then a ButtonRelease event to + the deepest subwindow containing the mouse to simulate a + middle click. The times for these events should be the time + of the actual button release +1 and +2, respectively. These + values will not be used by anybody else, so one can + unambiguously recognize the resulting `XConvertSelection' + request. + + 3. If a request for XA_PRIMARY arrives bearing the timestamp + of either the ButtonPress or the ButtonRelease event, treat + it as a request for XdndSelection. Note that you must use + the X data types instead of the MIME types in this case. + (e.g. XA_STRING instead of text/plain). */ +void +x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo, + Lisp_Object frame, Lisp_Object value, + Lisp_Object targets, Window target_window, + int root_x, int root_y, Time before) { XEvent event; int dest_x, dest_y; Window child_return, child; - Lisp_Object frame; - int i; - - for (i = 0; i < x_dnd_n_targets; ++i) - { - if (x_dnd_targets[i] == XA_STRING - || x_dnd_targets[i] == dpyinfo->Xatom_TEXT - || x_dnd_targets[i] == dpyinfo->Xatom_COMPOUND_TEXT - || x_dnd_targets[i] == dpyinfo->Xatom_UTF8_STRING) - break; - } - - if (i == x_dnd_n_targets) - return; event.xbutton.type = ButtonPress; event.xbutton.serial = 0; @@ -2822,8 +2812,6 @@ x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_windo event.xbutton.x_root = root_x; event.xbutton.y_root = root_y; - XSETFRAME (frame, x_dnd_frame); - x_catch_errors (dpyinfo->display); child = dpyinfo->root_window; @@ -2868,6 +2856,55 @@ x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_windo x_uncatch_errors (); } +static void +x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_window, + int root_x, int root_y, Time before) +{ + struct input_event ie; + Lisp_Object targets, arg; + int i; + char **atom_names, *name; + + EVENT_INIT (ie); + targets = Qnil; + atom_names = alloca (sizeof *atom_names * x_dnd_n_targets); + + if (!XGetAtomNames (dpyinfo->display, x_dnd_targets, + x_dnd_n_targets, atom_names)) + return; + + for (i = x_dnd_n_targets; i > 0; --i) + { + targets = Fcons (build_string (atom_names[i - 1]), + targets); + XFree (atom_names[i - 1]); + } + + name = XGetAtomName (dpyinfo->display, + x_dnd_wanted_action); + + if (name) + { + arg = intern (name); + XFree (name); + } + else + arg = Qnil; + + ie.kind = UNSUPPORTED_DROP_EVENT; + ie.code = (unsigned) target_window; + ie.arg = list3 (assq_no_quit (QXdndSelection, + dpyinfo->terminal->Vselection_alist), + targets, arg); + ie.timestamp = before; + + XSETINT (ie.x, root_x); + XSETINT (ie.y, root_y); + XSETFRAME (ie.frame_or_window, x_dnd_frame); + + kbd_buffer_store_event (&ie); +} + static Window x_dnd_get_target_window (struct x_display_info *dpyinfo, int root_x, int root_y, int *proto_out, @@ -23273,4 +23310,19 @@ It should either be nil, or accept two arguments FRAME and POSITION, where FRAME is the frame the mouse is on top of, and POSITION is a mouse position list. */); Vx_dnd_movement_function = Qnil; + + DEFVAR_LISP ("x-dnd-unsupported-drop-function", Vx_dnd_unsupported_drop_function, + doc: /* Function called when trying to drop on an unsupported window. +This function is called whenever the user tries to drop +something on a window that does not support either the XDND or +Motif protocols for drag-and-drop. It should return a non-nil +value if the drop was handled by the function, and nil if it was +not. It should accept several arguments TARGETS, X, Y, ACTION, +WINDOW-ID and FRAME, where TARGETS is the list of targets that +was passed to `x-begin-drag', WINDOW-ID is the numeric XID of +the window that is being dropped on, X and Y are the root +window-relative coordinates where the drop happened, ACTION +is the action that was passed to `x-begin-drag', and FRAME is +the frame which initiated the drag-and-drop operation. */); + Vx_dnd_unsupported_drop_function = Qnil; } diff --git a/src/xterm.h b/src/xterm.h index 4eb16d0c14..d8898162d1 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1391,6 +1391,9 @@ extern void x_scroll_bar_configure (GdkEvent *); extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom, Lisp_Object, Atom *, const char **, size_t, bool); +extern void x_dnd_do_unsupported_drop (struct x_display_info *, Lisp_Object, + Lisp_Object, Lisp_Object, Window, int, + int, Time); extern void x_set_dnd_targets (Atom *, int); INLINE int commit 406da54bc63b1099b6e51b3d3e025712a16a1912 Author: Lars Ingebrigtsen Date: Wed Apr 6 13:47:46 2022 +0200 Fix minor-mode doc string quoting * lisp/emacs-lisp/easy-mmode.el (easy-mmode--mode-docstring): Fix double quoting of things like (default-value 'electric-pair-mode) (bug#54746). diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index b2302624b1..8a76eaf58c 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -129,7 +129,7 @@ it is disabled.") (if global "global " "") mode-pretty-name ;; Avoid having quotes turn into pretty quotes. - (string-replace "'" "\\\\='" (format "%S" getter))))) + (string-replace "'" "\\='" (format "%S" getter))))) (let ((start (point))) (insert argdoc) (when (fboundp 'fill-region) commit 45621c0b79b9c480501c77666a54562069653338 Author: Davide Masserut Date: Wed Apr 6 12:24:09 2022 +0200 Make the Foot terminal an alias of xterm-256color * lisp/faces.el (term-file-aliases): Make the foot terminal an alias of xterm-256color (bug#54739). diff --git a/lisp/faces.el b/lisp/faces.el index 30f8483159..48a8222243 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -46,7 +46,8 @@ the terminal-initialization file to be loaded." ("vt320" . "vt200") ("vt400" . "vt200") ("vt420" . "vt200") - ("alacritty" . "xterm")) + ("alacritty" . "xterm") + ("foot" . "xterm")) "Alist of terminal type aliases. Entries are of the form (TYPE . ALIAS), where both elements are strings. This means to treat a terminal of type TYPE as if it were of type ALIAS." commit 7eca680e5441a8c2315f3b39e5e1d5581661316c Author: Kien Nguyen Date: Wed Apr 6 11:58:02 2022 +0200 Make file-name-split returns driver name as well in Windows * lisp/files.el (file-name-split): Returns driver name as well in Windows. * lisp/net/browse-url.el (browse-url-file-url): Don't hexify colon character in file path for Windows (bug#54721). diff --git a/lisp/files.el b/lisp/files.el index a0bc5bf262..2aa6c9dedc 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5091,7 +5091,11 @@ On most systems, this will be true: ;; If there's nothing left to peel off, we're at the root and ;; we can stop. (when (and dir (equal dir filename)) - (push "" components) + (push (if (equal dir "") "" + ;; On Windows, the first component might be "c:" or + ;; the like. + (substring dir 0 -1)) + components) (setq filename nil)))) components)) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 4c348781a8..66898d7707 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -728,9 +728,18 @@ Use variable `browse-url-filename-alist' to map filenames to URLs." browse-url-filename-alist)) (setq file (browse-url-url-encode-chars file "[*\"()',=;?% ]")) ;; Encode all other file names properly. - (setq file (mapconcat #'url-hexify-string - (file-name-split file) - "/"))) + (let ((bits (file-name-split file))) + (setq file + (string-join + ;; On Windows, the first bit here might be "c:" or the + ;; like, so don't encode the ":" in the first bit. + (cons (let ((url-unreserved-chars + (if (file-name-absolute-p file) + (cons ?: url-unreserved-chars) + url-unreserved-chars))) + (url-hexify-string (car bits))) + (mapcar #'url-hexify-string (cdr bits))) + "/")))) (dolist (map browse-url-filename-alist) (when (and map (string-match (car map) file)) (setq file (replace-match (cdr map) t nil file)))) commit e32dcc752723cd255622fde73a324bdcb1e90664 Author: Davide Masserut Date: Wed Apr 6 11:37:38 2022 +0200 Add .bashrc detection to sh-mode * lisp/progmodes/sh-script.el (sh-mode): Add .bashrc string-match (bug#54727). diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 8dc5562143..9151fd0a34 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1549,7 +1549,7 @@ with your script for an edit-interpret-debug cycle." ;; Checks that use `buffer-file-name' follow. ((string-match "\\.m?spec\\'" buffer-file-name) "rpm") ((string-match "[.]sh\\>" buffer-file-name) "sh") - ((string-match "[.]bash\\>" buffer-file-name) "bash") + ((string-match "[.]bash\\(rc\\)?\\>" buffer-file-name) "bash") ((string-match "[.]ksh\\>" buffer-file-name) "ksh") ((string-match "[.]mkshrc\\>" buffer-file-name) "mksh") ((string-match "[.]t?csh\\(rc\\)?\\>" buffer-file-name) "csh") commit 51a98a92e9f4c821ff838d823ce42ca12a4de4ca Author: Markus Kopp Date: Wed Apr 6 17:27:19 2022 +0800 Use CUA functions to scroll pages with pixel-scroll-scroll-mode * lisp/pixel-scroll.el (pixel-scroll-interpolate-down) (pixel-scroll-interpolate-up): Use `cua-scroll-up' and `cua-scroll-down' to scroll if `pixel-scroll-precision-interpolate-page' is off. (bug#54696) diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index bfe48ef1f9..688a054896 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -90,6 +90,7 @@ (require 'mwheel) (require 'subr-x) (require 'ring) +(require 'cua-base) (defvar pixel-wait 0 "Idle time on each step of pixel scroll specified in second. @@ -803,14 +804,14 @@ It is a vector of the form [ VELOCITY TIME SIGN ]." (interactive) (if pixel-scroll-precision-interpolate-page (pixel-scroll-precision-interpolate (- (window-text-height nil t))) - (scroll-up))) + (cua-scroll-up))) (defun pixel-scroll-interpolate-up () "Interpolate a scroll upwards by one page." (interactive) (if pixel-scroll-precision-interpolate-page (pixel-scroll-precision-interpolate (window-text-height nil t)) - (scroll-down))) + (cua-scroll-down))) ;;;###autoload (define-minor-mode pixel-scroll-precision-mode commit f9da45df47270c1f58736e78bc4f6716e1828e40 Author: Po Lu Date: Wed Apr 6 17:17:41 2022 +0800 Prevent races when trying to set Motif drag window * src/xterm.c (xm_get_drag_window): Grab temp connection when setting the drag window. diff --git a/src/xterm.c b/src/xterm.c index 7eef2b488b..b6aed004ed 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1395,13 +1395,18 @@ xm_get_drag_window (struct x_display_info *dpyinfo) if (drag_window == None) { + block_input (); unrequest_sigio (); temp_display = XOpenDisplay (XDisplayString (dpyinfo->display)); request_sigio (); if (!temp_display) - return None; + { + unblock_input (); + return None; + } + XGrabServer (temp_display); XSetCloseDownMode (temp_display, RetainPermanent); attrs.override_redirect = True; drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display), @@ -1422,6 +1427,7 @@ xm_get_drag_window (struct x_display_info *dpyinfo) drag_window, &wattrs); rc = !x_had_errors_p (dpyinfo->display); x_uncatch_errors_after_check (); + unblock_input (); /* We connected to the wrong display, so just give up. */ if (!rc) commit fbf6b7d2f0fb73379995e869d56df036e3e8b343 Author: Michael Albinus Date: Wed Apr 6 09:51:09 2022 +0200 Revert unneeded change in tramp-integration.el * lisp/net/tramp-integration.el: Apply `connection-local-set-profiles' w/o retrieving old values. diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el index 089093a420..6be06d0e73 100644 --- a/lisp/net/tramp-integration.el +++ b/lisp/net/tramp-integration.el @@ -286,11 +286,9 @@ NAME must be equal to `tramp-current-connection'." 'tramp-connection-local-default-system-profile tramp-connection-local-default-system-variables) -(apply - #'connection-local-set-profiles +(connection-local-set-profiles '(:application tramp) - (cons 'tramp-connection-local-default-system-profile - (connection-local-get-profiles '(:application tramp)))) + 'tramp-connection-local-default-system-profile) (defconst tramp-connection-local-default-shell-variables '((shell-file-name . "/bin/sh") @@ -302,11 +300,9 @@ NAME must be equal to `tramp-current-connection'." tramp-connection-local-default-shell-variables) (with-eval-after-load 'shell - (apply - #'connection-local-set-profiles + (connection-local-set-profiles '(:application tramp) - (cons 'tramp-connection-local-default-shell-profile - (connection-local-get-profiles '(:application tramp))))) + 'tramp-connection-local-default-shell-profile)) ;; Tested with FreeBSD 12.2. (defconst tramp-bsd-process-attributes-ps-args commit 069e0ba9f3aa21c29a6b3a35f63a440c3ca9c8ab Author: Lars Ingebrigtsen Date: Wed Apr 6 09:27:32 2022 +0200 Fix URL-related typos in comments and messages * lisp/ffap.el (ffap-next): Fix typo in message. * lisp/finder.el (finder-commentary): Fix typo in comment. diff --git a/lisp/ffap.el b/lisp/ffap.el index b5d2a02cd1..30a9577d38 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -79,7 +79,7 @@ ;; (setq ffap-shell-prompt-regexp nil) ; disable shell prompt stripping ;; (setq ffap-gopher-regexp nil) ; disable gopher bookmark matching ;; -;; ffap uses `browse-url' (if found, else `w3-fetch') to fetch URL's. +;; ffap uses `browse-url' (if found, else `w3-fetch') to fetch URLs. ;; For a hairier `ffap-url-fetcher', try ffap-url.el (same ftp site). ;; Also, you can add `ffap-menu-rescan' to various hooks to fontify ;; the file and URL references within a buffer. @@ -282,7 +282,7 @@ For a fancy alternative, get `ffap-url.el'." :risky t) (defcustom ffap-next-regexp - ;; If you want ffap-next to find URL's only, try this: + ;; If you want ffap-next to find URLs only, try this: ;; (and ffap-url-regexp (string-match "\\\\`" ffap-url-regexp) ;; (concat "\\<" (substring ffap-url-regexp 2)))) ;; @@ -315,7 +315,7 @@ disable ffap most of the time." ;;; Find Next Thing in buffer (`ffap-next'): ;; -;; Original ffap-next-url (URL's only) from RPECK 30 Mar 1995. Since +;; Original ffap-next-url (URLs only) from RPECK 30 Mar 1995. Since ;; then, broke it up into ffap-next-guess (noninteractive) and ;; ffap-next (a command). It now work on files as well as url's. @@ -363,7 +363,7 @@ Actual search is done by the function `ffap-next-guess'." (sit-for 0) ; display point movement (find-file-at-point (ffap-prompter guess))) (goto-char pt) ; restore point - (message "No %sfiles or URL's found" + (message "No %sfiles or URLs found" (if wrap "" "more "))))) (defun ffap-next-url (&optional back wrap) diff --git a/lisp/finder.el b/lisp/finder.el index a40f8c64f2..899e829296 100644 --- a/lisp/finder.el +++ b/lisp/finder.el @@ -367,7 +367,7 @@ not `finder-known-keywords'." "Display FILE's commentary section. FILE should be in a form suitable for passing to `locate-library'." ;; FIXME: Merge this function into `describe-package', which is - ;; strictly better as it has links to URL's and is in a proper help + ;; strictly better as it has links to URLs and is in a proper help ;; buffer with navigation forward and backward, etc. (interactive (list