commit 304c373c98ffdba8f946072f15fd109c4cef533f (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Wed Feb 23 15:13:23 2022 +0800 Improve input extension version checks on GTK 3 * src/xterm.c (x_term_init): If newer versions of XInput 2 don't work, then look for an older one. diff --git a/src/xterm.c b/src/xterm.c index caacf8336c..d78c5d7250 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -16398,32 +16398,68 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) &xi_first_error)) { #ifdef HAVE_GTK3 - /* Catch errors caused by GTK requesting a different version of - XInput 2 than what Emacs was built with. */ - x_catch_errors (dpyinfo->display); + bool move_backwards = false; + int original_minor = minor; query: + + /* Catch errors caused by GTK requesting a different version of + XInput 2 than what Emacs was built with. Usually, the X + server tolerates these mistakes, but a BadValue error can + result if only one of GTK or Emacs wasn't built with support + for XInput 2.2. + + To work around the first, it suffices to increase the minor + version until the X server is happy if the XIQueryVersion + request results in an error. If that doesn't work, however, + then it's the latter, so decrease the minor until the version + that GTK requested is found. */ + x_catch_errors (dpyinfo->display); #endif rc = XIQueryVersion (dpyinfo->display, &major, &minor); #ifdef HAVE_GTK3 + /* Increase the minor version until we find one the X + server agrees with. If that didn't work, then + decrease the version until it either hits zero or + becomes agreeable to the X server. */ + if (x_had_errors_p (dpyinfo->display)) { - /* Some unreasonable value that will probably not be - exceeded in the future. */ - if (minor > 100) - rc = BadRequest; + x_uncatch_errors_after_check (); + + /* Since BadValue errors can't be generated if both the + prior and current requests specify a version of 2.2 or + later, this means the prior request specified a version + of the input extension less than 2.2. */ + if (minor >= 2) + { + move_backwards = true; + minor = original_minor; + + if (--minor < 0) + rc = BadRequest; + else + goto query; + } else { - /* Increase the minor version until we find one the X server - agrees with. */ - minor++; - goto query; + if (!move_backwards) + { + minor++; + goto query; + } + + if (--minor < 0) + rc = BadRequest; + else + goto query; + } } - - x_uncatch_errors (); + else + x_uncatch_errors_after_check (); #endif if (rc == Success) commit 6410b6ada00731bad7459af5502f3ef7da80fa89 Merge: e97580724d 3dfc8bff15 Author: Stefan Kangas Date: Wed Feb 23 06:36:45 2022 +0100 Merge from origin/emacs-28 3dfc8bff15 Fix indexing of module functions that return enumeration t... 86c0d9eb5f * doc/misc/transient.texi (Other Options): Fix a @ref. (B... 3b5e29eaa3 tramp.texi texinfo 4.13 compatibility 5edb9572ec Explain "Tramp" spelling in its manual commit e97580724ded250ffb17baf01d37b15325433dd9 Author: Po Lu Date: Wed Feb 23 13:13:19 2022 +0800 Fix display corruption with background alpha set on unsupported display * src/xfns.c (x_set_alpha_background): Make opaque if display doesn't support the required features. diff --git a/src/xfns.c b/src/xfns.c index 9afadd16e9..b2e3615fcf 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -737,6 +737,18 @@ x_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval) gui_set_alpha_background (f, arg, oldval); +#ifdef HAVE_XRENDER + /* Setting `alpha_background' to something other than opaque on a + display that doesn't support the required features leads to + confusing results. */ + if (f->alpha_background < 1.0 + && !FRAME_DISPLAY_INFO (f)->alpha_bits + && !FRAME_CHECK_XR_VERSION (f, 0, 2)) + f->alpha_background = 1.0; +#else + f->alpha_background = 1.0; +#endif + #ifdef USE_GTK /* This prevents GTK from painting the window's background, which interferes with transparent background in some environments */ commit 8adc3672ac1b2fb90d142cfe2a1a74d36e33b41b Author: Stefan Monnier Date: Tue Feb 22 22:52:40 2022 -0500 (add-hook): Fix regression * lisp/subr.el (add-hook): When the hook has no local part yet, don't set `local` to t, so we set the right part of the depth-sym. (remove-hook): Don't modify the depth alist by side-effect since I'm not completely sure it's safe. diff --git a/lisp/subr.el b/lisp/subr.el index 1b9b67b705..eb9af0b36d 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1905,7 +1905,9 @@ performance impact when running `add-hook' and `remove-hook'." (set (make-local-variable hook) (list t))) ;; Detect the case where make-local-variable was used on a hook ;; and do what we used to do. - (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook))) + (when (and (local-variable-if-set-p hook) + (not (and (consp (symbol-value hook)) + (memq t (symbol-value hook))))) (setq local t))) (let ((hook-value (if local (symbol-value hook) (default-value hook)))) ;; If the hook value is a single function, turn it into a list. @@ -2020,7 +2022,7 @@ one will be removed." (when di (setf (if local (symbol-value depth-sym) (default-value depth-sym)) - (delq di depth-alist))))) + (remq di depth-alist))))) ;; If the function is on the global hook, we need to shadow it locally ;;(when (and local (member function (default-value hook)) ;; (not (member (cons 'not function) hook-value))) commit 659eca9ed8df020a2f3edd84a82b3316820749c7 Author: Po Lu Date: Wed Feb 23 11:40:11 2022 +0800 * src/xterm.c: Expand commentary. diff --git a/src/xterm.c b/src/xterm.c index 7d4b43773e..caacf8336c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -26,6 +26,9 @@ along with GNU Emacs. If not, see . */ contains subroutines comprising the redisplay interface, setting up scroll bars and widgets, and handling input. + Some of what is explained below also applies to the other window + systems that Emacs supports, to varying degrees. YMMV. + INPUT Emacs handles input by running pselect in a loop, which returns @@ -84,7 +87,119 @@ along with GNU Emacs. If not, see . */ is no focus window, we treat each frame as having the input focus whenever the pointer enters it, and undo that treatment when the pointer leaves it. See the callers of x_detect_focus_change for - more details. */ + more details. + + REDISPLAY + + The redisplay engine communicates with X through the "redisplay + interface", which is a structure containing pointers to functions + which output graphics to a frame. + + Some of the functions included in the redisplay interface include + `x_clear_frame_area', which is called by the display engine when it + determines that a part of the display has to be cleared, + x_draw_window_cursor, which is called to perform the calculations + necessary to display the cursor glyph with a special "highlight" + (more on that later) and to set the input method spot location. + + Most of the actual display is performed by the function + `x_draw_glyph_string', also included in the redisplay interface. + It takes a list of glyphs of the same type and face, computes the + correct graphics context for the string through the function + `x_set_glyph_string_gc', and draws whichever glyphs it might + contain, along with decorations such as the box face, underline and + overline. That list is referred to as a "glyph string". + + GRAPHICS CONTEXTS + + A graphics context ("GC") is an X server-side object which contains + drawing attributes such as fill style, stipple, and foreground and + background pixel values. + + Usually, one graphics context is computed for each face when it is + first about to be displayed, and this graphics context is the one + which is used for future X drawing operations in a glyph string + with that face. (See `prepare_face_for_display' in xfaces.c). + + However, when drawing glyph strings for special display elements + such as the cursor, or mouse sensitive text, different GCs may be + used. When displaying the cursor, for example, the frame's cursor + graphics context is used for the common case where the cursor is + drawn with the default font, and the colors of the string's face + are the same as the default face. In all other cases, a temporary + graphics context is created with the foreground and background + colors of the cursor face adjusted to ensure that the cursor can be + distinguished from its surroundings and that the text inside the + cursor stays visible. + + Various graphics contexts are also calculated when the frame is + created by the function `x_make_gcs' in xfns.c, and are adjusted + whenever the foreground or background colors change. The "normal" + graphics context is used for operations performed without a face, + and always corresponds to the foreground and background colors of + the frame's default face, the "reverse" graphics context is used to + draw text in inverse video, and the cursor graphics context is used + to display the cursor in the most common case. + + COLOR ALLOCATION + + In X, pixel values for colors are not guaranteed to correspond to + their individual components. The rules for converting colors into + pixel values are defined by the visual class of each display opened + by Emacs. When a display is opened, a suitable visual is obtained + from the X server, and a colormap is created based on that visual, + which is then used for each frame created. + + The colormap is then used by the X server to convert pixel values + from a frame created by Emacs into actual colors which are output + onto the physical display. + + When the visual class is TrueColor, the colormap will be indexed + based on the red, green, and blue components of the pixel values, + and the colormap will be statically allocated as to contain linear + ramps for each component. As such, most of the color allocation + described below is bypassed, and the pixel values are computed + directly from the color. + + Otherwise, each time Emacs wants a pixel value that corresponds to + a color, Emacs has to ask the X server to obtain the pixel value + that corresponds to a "color cell" containing the color (or a close + approximation) from the colormap. Exactly how this is accomplished + further depends on the visual class, since some visuals have + immutable colormaps which contain color cells with pre-defined + values, while others have colormaps where the color cells are + dynamically allocated by individual X clients. + + With visuals that have a visual class of StaticColor and StaticGray + (where the former is the case), the X server is asked to procure + the pixel value of a color cell that contains the closest + approximation of the color which Emacs wants. On the other hand, + when the visual class is DirectColor, PseudoColor, or GrayScale, + where color cells are dynamically allocated by clients, Emacs asks + the X server to allocate a color cell containing the desired color, + and uses its pixel value. + + (If the color already exists, the X server returns an existing color + cell, but increases its reference count, so it still has to be + freed afterwards.) + + Otherwise, if no color could be allocated (due to the colormap + being full), Emacs looks for a color cell inside the colormap + closest to the desired color, and uses its pixel value instead. + + Since the capacity of a colormap is finite, X clients have to take + special precautions in order to not allocate too many color cells + that are never used. Emacs allocates its color cells when a face + is being realized or when a frame changes its foreground and + background colors, and releases them alongside the face or frame. + See calls to `unload_color' and `load_color' in xterm.c, xfaces.c + and xfns.c for more details. + + The driving logic behind color allocation is in + `x_alloc_nearest_color_1', while the optimization for TrueColor + visuals is in `x_make_truecolor_pixel'. Also see `x_query_colors`, + which is used to determine the color values for given pixel + values. */ #include #include commit 0f67a3df0ef161dde90454c48a7eb572ef406d1a Author: Dmitry Gutov Date: Wed Feb 23 03:53:05 2022 +0200 Unbreak project switcher when inside *xref* buffer * lisp/progmodes/xref.el (xref--ensure-default-directory): New function. (xref--show-xref-buffer, xref-show-definitions-buffer-at-bottom): Use it (bug#53626). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 3374ab2e84..aa98aa89f1 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1107,6 +1107,13 @@ Return an alist of the form ((GROUP . (XREF ...)) ...)." (cdr pair))) alist))) +(defun xref--ensure-default-directory (dd buffer) + ;; We might be in a let-binding which will restore the current value + ;; to a previous one (bug#53626). So do this later. + (run-with-timer + 0 nil + (lambda () (with-current-buffer buffer (setq default-directory dd))))) + (defun xref--show-xref-buffer (fetcher alist) (cl-assert (functionp fetcher)) (let* ((xrefs @@ -1117,7 +1124,7 @@ Return an alist of the form ((GROUP . (XREF ...)) ...)." (dd default-directory) buf) (with-current-buffer (get-buffer-create xref-buffer-name) - (setq default-directory dd) + (xref--ensure-default-directory dd (current-buffer)) (xref--xref-buffer-mode) (xref--show-common-initialize xref-alist fetcher alist) (pop-to-buffer (current-buffer)) @@ -1216,7 +1223,7 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'." (assoc-default 'display-action alist))) (t (with-current-buffer (get-buffer-create xref-buffer-name) - (setq default-directory dd) + (xref--ensure-default-directory dd (current-buffer)) (xref--transient-buffer-mode) (xref--show-common-initialize (xref--analyze xrefs) fetcher alist) (pop-to-buffer (current-buffer) commit b16e36476e1317ad40a04e2036b2dabf170935c2 Author: Po Lu Date: Wed Feb 23 08:58:06 2022 +0800 * src/xterm.c (x_term_init): Don't catch errors too many times. diff --git a/src/xterm.c b/src/xterm.c index fffa40840a..7d4b43773e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -16283,10 +16283,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) &xi_first_error)) { #ifdef HAVE_GTK3 - query: /* Catch errors caused by GTK requesting a different version of XInput 2 than what Emacs was built with. */ x_catch_errors (dpyinfo->display); + + query: #endif rc = XIQueryVersion (dpyinfo->display, &major, &minor); commit 1f00710ecfac12de12f4a2046b9b66802b8ffac6 Author: Po Lu Date: Wed Feb 23 08:56:06 2022 +0800 Fix X errors caused by GTK using newer versions of XI2 than Emacs * src/xterm.c (x_term_init): Handle errors from XIQueryVersion caused by Emacs requesting versions of XI2 older than 2.2 and what GTK requested. diff --git a/src/xterm.c b/src/xterm.c index 23721352f3..fffa40840a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -16264,6 +16264,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) dpyinfo->supports_xi2 = false; int rc; int major = 2; + int xi_first_event, xi_first_error; + #ifdef HAVE_XINPUT2_4 int minor = 4; #elif defined HAVE_XINPUT2_3 /* XInput 2.3 */ @@ -16275,12 +16277,39 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) #else /* Some old version of XI2 we're not interested in. */ int minor = 0; #endif - int fer, fee; if (XQueryExtension (dpyinfo->display, "XInputExtension", - &dpyinfo->xi2_opcode, &fer, &fee)) + &dpyinfo->xi2_opcode, &xi_first_event, + &xi_first_error)) { +#ifdef HAVE_GTK3 + query: + /* Catch errors caused by GTK requesting a different version of + XInput 2 than what Emacs was built with. */ + x_catch_errors (dpyinfo->display); +#endif + rc = XIQueryVersion (dpyinfo->display, &major, &minor); + +#ifdef HAVE_GTK3 + if (x_had_errors_p (dpyinfo->display)) + { + /* Some unreasonable value that will probably not be + exceeded in the future. */ + if (minor > 100) + rc = BadRequest; + else + { + /* Increase the minor version until we find one the X server + agrees with. */ + minor++; + goto query; + } + } + + x_uncatch_errors (); +#endif + if (rc == Success) { dpyinfo->supports_xi2 = true; commit 3dfc8bff15a74cbb6da3ebb3718fc30b5ebad195 (refs/remotes/origin/emacs-28) Author: Philipp Stephani Date: Tue Feb 22 21:39:32 2022 +0100 Fix indexing of module functions that return enumeration types. Return types that consist of more than one word need to be enclosed in braces, see Info node `(texinfo) Typed Functions'. Otherwise they are indexed incorrectly. * doc/lispref/internals.texi (Module Misc, Module Nonlocal): Enclose multi-word return types in braces. diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 39e26aaf8f..14d6c34e17 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -2052,7 +2052,7 @@ to quit, use the following function, which is available since Emacs 27.1. @anchor{process_input} -@deftypefn Function enum emacs_process_input_result process_input (emacs_env *@var{env}) +@deftypefn Function {enum emacs_process_input_result} process_input (emacs_env *@var{env}) This function processes pending input events. It returns @code{emacs_process_input_quit} if the user wants to quit or an error occurred while processing signals. In that case, we recommend that @@ -2127,7 +2127,7 @@ Therefore, we recommend that your module functions check for nonlocal exit conditions and recover from them, using the functions described below. -@deftypefn Function enum emacs_funcall_exit non_local_exit_check (emacs_env *@var{env}) +@deftypefn Function {enum emacs_funcall_exit} non_local_exit_check (emacs_env *@var{env}) This function returns the kind of nonlocal exit condition stored in @var{env}. The possible values are: @@ -2142,7 +2142,7 @@ The last @acronym{API} function exited via @code{throw}. @end vtable @end deftypefn -@deftypefn Function enum emacs_funcall_exit non_local_exit_get (emacs_env *@var{env}, emacs_value *@var{symbol}, emacs_value *@var{data}) +@deftypefn Function {enum emacs_funcall_exit} non_local_exit_get (emacs_env *@var{env}, emacs_value *@var{symbol}, emacs_value *@var{data}) This function returns the kind of nonlocal exit condition stored in @var{env}, like @code{non_local_exit_check} does, but it also returns the full information about the nonlocal exit, if any. If the return commit c20e96d186618e7f644188a7f71d5dcb6fa4eaf1 Author: Lars Ingebrigtsen Date: Tue Feb 22 15:44:14 2022 +0100 Enable "Revert Buffer" if file has different writability * lisp/menu-bar.el (menu-bar-file-menu): Enable "Revert Buffer" if the file has different writability than the buffer (bug#17148). diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index e26355293f..ab64928fe7 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -178,17 +178,23 @@ t)) :help "Recover edits from a crashed session")) (bindings--define-key menu [revert-buffer] - '(menu-item "Revert Buffer" revert-buffer - :enable (or (not (eq revert-buffer-function - 'revert-buffer--default)) - (not (eq - revert-buffer-insert-file-contents-function - 'revert-buffer-insert-file-contents--default-function)) - (and buffer-file-number - (or (buffer-modified-p) - (not (verify-visited-file-modtime - (current-buffer)))))) - :help "Re-read current buffer from its file")) + '(menu-item + "Revert Buffer" revert-buffer + :enable + (or (not (eq revert-buffer-function + 'revert-buffer--default)) + (not (eq + revert-buffer-insert-file-contents-function + 'revert-buffer-insert-file-contents--default-function)) + (and buffer-file-number + (or (buffer-modified-p) + (not (verify-visited-file-modtime + (current-buffer))) + ;; Enable if the buffer has a different + ;; writeability than the file. + (not (eq (not buffer-read-only) + (file-writable-p buffer-file-name)))))) + :help "Re-read current buffer from its file")) (bindings--define-key menu [write-file] '(menu-item "Save As..." write-file :enable (and (menu-bar-menu-frame-live-and-visible-p) commit 4bd7963e2e244ace94afa59124f2637543d74ba2 Author: Stefan Monnier Date: Tue Feb 22 10:18:43 2022 -0500 (add-hook, remove-hook): Fix leaks (bug#48666) * lisp/subr.el (add-hook, remove-hook): Rewrite the hook depth management so we only keep the info relevant to functions present on the hook. diff --git a/lisp/subr.el b/lisp/subr.el index a78af09c40..1b9b67b705 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1913,26 +1913,34 @@ performance impact when running `add-hook' and `remove-hook'." (setq hook-value (list hook-value))) ;; Do the actual addition if necessary (unless (member function hook-value) - (when (stringp function) ;FIXME: Why? - (setq function (purecopy function))) - ;; All those `equal' tests performed between functions can end up being - ;; costly since those functions may be large recursive and even cyclic - ;; structures, so we index `hook--depth-alist' with `eq'. (bug#46326) - (when (or (get hook 'hook--depth-alist) (not (zerop depth))) - ;; Note: The main purpose of the above `when' test is to avoid running - ;; this `setf' before `gv' is loaded during bootstrap. - (setf (alist-get function (get hook 'hook--depth-alist) 0) depth)) - (setq hook-value - (if (< 0 depth) - (append hook-value (list function)) - (cons function hook-value))) - (let ((depth-alist (get hook 'hook--depth-alist))) - (when depth-alist - (setq hook-value - (sort (if (< 0 depth) hook-value (copy-sequence hook-value)) - (lambda (f1 f2) - (< (alist-get f1 depth-alist 0 nil #'eq) - (alist-get f2 depth-alist 0 nil #'eq)))))))) + (let ((depth-sym (get hook 'hook--depth-alist))) + ;; While the `member' test above has to use `equal' for historical + ;; reasons, `equal' is a performance problem on large/cyclic functions, + ;; so we index `hook--depth-alist' with `eql'. (bug#46326) + (unless (zerop depth) + (unless depth-sym + (setq depth-sym (make-symbol "depth-alist")) + (set depth-sym nil) + (setf (get hook 'hook--depth-alist) depth-sym)) + (if local (make-local-variable depth-sym)) + (setf (alist-get function + (if local (symbol-value depth-sym) + (default-value depth-sym)) + 0) + depth)) + (setq hook-value + (if (< 0 depth) + (append hook-value (list function)) + (cons function hook-value))) + (when depth-sym + (let ((depth-alist (if local (symbol-value depth-sym) + (default-value depth-sym)))) + (when depth-alist + (setq hook-value + (sort (if (< 0 depth) hook-value (copy-sequence hook-value)) + (lambda (f1 f2) + (< (alist-get f1 depth-alist 0 nil #'eq) + (alist-get f2 depth-alist 0 nil #'eq)))))))))) ;; Set the actual variable (if local (progn @@ -2005,9 +2013,14 @@ one will be removed." (when old-fun ;; Remove auxiliary depth info to avoid leaks (bug#46414) ;; and to avoid the list growing too long. - (let* ((depths (get hook 'hook--depth-alist)) - (di (assq old-fun depths))) - (when di (put hook 'hook--depth-alist (delq di depths))))) + (let* ((depth-sym (get hook 'hook--depth-alist)) + (depth-alist (if depth-sym (if local (symbol-value depth-sym) + (default-value depth-sym)))) + (di (assq old-fun depth-alist))) + (when di + (setf (if local (symbol-value depth-sym) + (default-value depth-sym)) + (delq di depth-alist))))) ;; If the function is on the global hook, we need to shadow it locally ;;(when (and local (member function (default-value hook)) ;; (not (member (cons 'not function) hook-value))) @@ -2169,7 +2182,7 @@ can do the job." (not (macroexp-const-p append))) exp (let* ((sym (cadr list-var)) - (append (eval append)) + (append (eval append lexical-binding)) (msg (format-message "`add-to-list' can't use lexical var `%s'; use `push' or `cl-pushnew'" sym)) @@ -2718,7 +2731,7 @@ It can be retrieved with `(process-get PROCESS PROPNAME)'." (defconst read-key-full-map (let ((map (make-sparse-keymap))) - (define-key map [t] 'dummy) + (define-key map [t] #'ignore) ;Dummy binding. ;; ESC needs to be unbound so that escape sequences in ;; `input-decode-map' are still processed by `read-key-sequence'. @@ -4471,7 +4484,7 @@ is allowed once again. (Immediately, if `inhibit-quit' is nil.)" ;; Without this, it will not be handled until the next function ;; call, and that might allow it to exit thru a condition-case ;; that intends to handle the quit signal next time. - (eval '(ignore nil))))) + (eval '(ignore nil) t)))) (defmacro while-no-input (&rest body) "Execute BODY only as long as there's no pending input. commit 86c0d9eb5fc309413696694c53e1eee9070caea6 Author: Eli Zaretskii Date: Tue Feb 22 16:37:22 2022 +0200 * doc/misc/transient.texi (Other Options): Fix a @ref. (Bug#54108) diff --git a/doc/misc/transient.texi b/doc/misc/transient.texi index bf048841a6..f91d0e5c10 100644 --- a/doc/misc/transient.texi +++ b/doc/misc/transient.texi @@ -729,7 +729,7 @@ The default is: This displays the window at the bottom of the selected frame. Another useful @var{function} is @code{display-buffer-below-selected}, which is what @code{magit-popup} used by default. For more alternatives see -@ref{Display Action Functions,,,elisp,}, and see @ref{Buffer Display +@ref{Buffer Display Action Functions,,,elisp,}, and see @ref{Buffer Display Action Alists,,,elisp,}. Note that the buffer that was current before the transient buffer commit 09bd220d865520f2426ae99d97b8b8296058732f Author: Eli Zaretskii Date: Tue Feb 22 16:32:49 2022 +0200 ; * doc/lispref/modes.texi (Tabulated List Mode): Fix @xref. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 570ffe1726..c29936d5ca 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1074,7 +1074,7 @@ monospaced fonts, using a single font and text size. If you want to display a table using variable pitch fonts or images, @code{make-vtable} can be used instead. vtable also support having more than a single table in a buffer, or having a buffer that contains -both a table and additional text in it. @ref{Introduction,,, vtable} +both a table and additional text in it. @xref{Introduction,,, vtable}, for more information. Tabulated List mode is intended to be used as a parent mode by a more commit 257ae88d4e58a9b9eebf536475c457db2fd0102e Author: Andrea Rossetti Date: Tue Feb 22 15:22:50 2022 +0100 Improve ruler-mode dragging * lisp/ruler-mode.el (ruler-mode-mouse-drag-any-column) (ruler-mode-mouse-add-tab-stop, ruler-mode-mouse-del-tab-stop): Adjust callers. * lisp/ruler-mode.el (ruler-mode-window-col): Fix dragging when stepping outside the header line (bug#17788). Copyright-paperwork-exempt: yes diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el index afe1cd4bfd..f0efc20f03 100644 --- a/lisp/ruler-mode.el +++ b/lisp/ruler-mode.el @@ -279,21 +279,24 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges)))) -(defsubst ruler-mode-window-col (n) +(defsubst ruler-mode-window-col (event) "Return a column number relative to the selected window. -N is a column number relative to selected frame. +EVENT is the mouse event that gives the current column. If required, account for screen estate taken by `display-line-numbers'." - (if display-line-numbers + (let ((n (car (posn-col-row event)))) + (when display-line-numbers ;; FIXME: ruler-mode relies on N being an integer, so if the ;; 'line-number' face is customized to use a font that is larger ;; or smaller than that of the default face, the alignment might ;; be off by up to half a column, unless the font width is an ;; integral multiple or divisor of the default face's font. (setq n (- n (round (line-number-display-width 'columns))))) - (- n - (or (car (window-margins)) 0) - (fringe-columns 'left) - (scroll-bar-columns 'left))) + (- n + (if (eq (posn-area event) 'header-line) + (+ (or (car (window-margins)) 0) + (fringe-columns 'left) + (scroll-bar-columns 'left)) + 0)))) (defun ruler-mode-mouse-set-left-margin (start-event) "Set left margin end to the graduation where the mouse pointer is on. @@ -370,7 +373,7 @@ dragging. See also the variable `ruler-mode-dragged-symbol'." col newc oldc) (save-selected-window (select-window (posn-window start)) - (setq col (ruler-mode-window-col (car (posn-col-row start))) + (setq col (ruler-mode-window-col start) newc (+ col (ruler-mode-text-scaled-window-hscroll))) (and (>= col 0) (< col (ruler-mode-text-scaled-window-width)) @@ -455,7 +458,7 @@ Called on each mouse motion event START-EVENT." col newc) (save-selected-window (select-window (posn-window start)) - (setq col (ruler-mode-window-col (car (posn-col-row end))) + (setq col (ruler-mode-window-col end) newc (+ col (ruler-mode-text-scaled-window-hscroll))) (when (and (>= col 0) (< col (ruler-mode-text-scaled-window-width))) (set ruler-mode-dragged-symbol newc))))) @@ -471,7 +474,7 @@ START-EVENT is the mouse click event." (when (eq start end) ;; mouse click (save-selected-window (select-window (posn-window start)) - (setq col (ruler-mode-window-col (car (posn-col-row start))) + (setq col (ruler-mode-window-col start) ts (+ col (ruler-mode-text-scaled-window-hscroll))) (and (>= col 0) (< col (ruler-mode-text-scaled-window-width)) (not (member ts tab-stop-list)) @@ -492,7 +495,7 @@ START-EVENT is the mouse click event." (when (eq start end) ;; mouse click (save-selected-window (select-window (posn-window start)) - (setq col (ruler-mode-window-col (car (posn-col-row start))) + (setq col (ruler-mode-window-col start) ts (+ col (ruler-mode-text-scaled-window-hscroll))) (and (>= col 0) (< col (ruler-mode-text-scaled-window-width)) (member ts tab-stop-list) commit 3b5e29eaa36880183517680a3964d3de5f3b40df Author: Glenn Morris Date: Tue Feb 22 14:08:07 2022 +0000 tramp.texi texinfo 4.13 compatibility * doc/misc/tramp.texi (Frequently Asked Questions): Restore compatibility with Texinfo < 5. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 396ff0412c..28da4b385c 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -4336,8 +4336,11 @@ The official name is ``Tramp''. This is used in comments, docstrings, and everywhere speaking about @value{tramp}. However, for historical reasons this is formatted as ``@@sc@{Tramp@}'' -in the @value{tramp} manual@inlinefmt{info,, @ref{(texinfo) -Smallcaps}}. So it looks different there. +in the @value{tramp} manual. +@ifinfo +@pxref{Smallcaps, , , texinfo}. +@end ifinfo +So it looks different there. @item commit 161f5b4be4ea684357e47064aef0f6c5b1c570ec Author: Jeff Norden Date: Tue Feb 22 14:51:47 2022 +0100 Make outline-blank-line into defcustom * lisp/outline.el (outline-blank-line): Make into defcustom (bug#54095). Copyright-paperwork-exempt: yes diff --git a/lisp/outline.el b/lisp/outline.el index 4dbbaa26a0..696d109f1e 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -312,8 +312,11 @@ data reflects the `outline-regexp'.") (defvar outline-mode-hook nil "This hook is run when outline mode starts.") -(defvar outline-blank-line nil - "Non-nil means to leave unhidden blank line before heading.") +(defcustom outline-blank-line nil + "Non-nil means to leave an unhidden blank line before headings." + :type 'boolean + :safe #'booleanp + :version "22.1") ;;;###autoload (define-derived-mode outline-mode text-mode "Outline" commit 5edb9572ec3196594892d4782075adba9221e611 Author: Michael Albinus Date: Tue Feb 22 14:45:59 2022 +0100 Explain "Tramp" spelling in its manual * doc/misc/tramp.texi (Frequently Asked Questions): Explain "Tramp" spelling. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index b5af234b96..396ff0412c 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -4329,6 +4329,17 @@ there. @cindex FAQ @itemize @bullet +@item +What is the official name - ``Tramp'' or ``@value{tramp}''? + +The official name is ``Tramp''. This is used in comments, docstrings, +and everywhere speaking about @value{tramp}. + +However, for historical reasons this is formatted as ``@@sc@{Tramp@}'' +in the @value{tramp} manual@inlinefmt{info,, @ref{(texinfo) +Smallcaps}}. So it looks different there. + + @item Where is the latest @value{tramp}? commit c6465d65faf0808b2bc7226ca108322c19d75b41 Author: Lars Ingebrigtsen Date: Tue Feb 22 14:43:35 2022 +0100 Don't signal an error on re-builder startup with rx syntax * lisp/emacs-lisp/re-builder.el (reb-initialize-buffer): Make startup with rx syntax not signal an error (bug#54107). diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el index 38726ca048..24770fac67 100644 --- a/lisp/emacs-lisp/re-builder.el +++ b/lisp/emacs-lisp/re-builder.el @@ -323,7 +323,10 @@ Except for Lisp syntax this is the same as `reb-regexp'.") (reb-lisp-mode)) (t (reb-mode))) (reb-restart-font-lock) - (reb-do-update)) + ;; When using `rx' syntax, the initial syntax () is invalid. But + ;; don't signal an error in that case. + (ignore-errors + (reb-do-update))) (defun reb-mode-buffer-p () "Return non-nil if the current buffer is a RE Builder buffer." commit 85567d57981448200ba2617e45d5d4d3e5721cf7 Author: Po Lu Date: Tue Feb 22 19:17:41 2022 +0800 ; * src/xterm.h: Fix typo in recent change. diff --git a/src/xterm.h b/src/xterm.h index e2256ce2df..7303565ec2 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -32,6 +32,10 @@ along with GNU Emacs. If not, see . */ #include #include +#ifdef HAVE_XINPUT2 +#include +#endif + #ifdef USE_X_TOOLKIT #include #include /* CoreP.h needs this */ @@ -42,10 +46,6 @@ along with GNU Emacs. If not, see . */ #include #endif -#ifdef HAVE_XINPUT2 -#include -#endif - typedef Widget xt_or_gtk_widget; #endif commit dfa607c1646be82bce5044941b7609c9bb1ccaa3 Author: Po Lu Date: Tue Feb 22 19:13:01 2022 +0800 Fix build on glibc <2.10 * src/alloc.c (Fmalloc_info): Only enable if glibc supports malloc_info. (syms_of_alloc): Likewise. diff --git a/src/alloc.c b/src/alloc.c index a3410be7e2..9ed94dc8a1 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -7385,7 +7385,8 @@ Frames, windows, buffers, and subprocesses count as vectors make_int (strings_consed)); } -#if defined GNU_LINUX && defined __GLIBC__ +#if defined GNU_LINUX && defined __GLIBC__ && \ + (__GLIBC__ > 2 || __GLIBC_MINOR__ >= 10) DEFUN ("malloc-info", Fmalloc_info, Smalloc_info, 0, 0, "", doc: /* Report malloc information to stderr. This function outputs to stderr an XML-formatted @@ -7745,7 +7746,9 @@ N should be nonnegative. */); defsubr (&Sgarbage_collect_maybe); defsubr (&Smemory_info); defsubr (&Smemory_use_counts); -#if defined GNU_LINUX && defined __GLIBC__ +#if defined GNU_LINUX && defined __GLIBC__ && \ + (__GLIBC__ > 2 || __GLIBC_MINOR__ >= 10) + defsubr (&Smalloc_info); #endif defsubr (&Ssuspicious_object); commit 8fef9a5cd9a16b2f91f2ad4e7edbcc49c3963d42 Merge: f7b5553045 dfd76688be Author: Po Lu Date: Tue Feb 22 18:47:49 2022 +0800 Merge remote-tracking branch 'origin/master' commit f7b5553045e2903852f0a9a90b382d1617ff18a0 Author: Po Lu Date: Tue Feb 22 18:46:12 2022 +0800 Fix GTK build with GLib <2.44 * src/gtkutil.c (struct _EmacsMenuBar, EmacsMenuBar): New structs. (emacs_menu_bar_get_type): New function declaration. * src/gtkutil.c: Remove declaration of EmacsMenuBar class. diff --git a/src/gtkutil.c b/src/gtkutil.c index 72eb7ef2bb..d4726014c0 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -78,11 +78,17 @@ typedef struct pgtk_output xp_output; #ifdef HAVE_GTK3 static void emacs_menu_bar_get_preferred_width (GtkWidget *, gint *, gint *); +static GType emacs_menu_bar_get_type (void); -struct _EmacsMenuBar +typedef struct _EmacsMenuBar { GtkMenuBar parent; -}; +} EmacsMenuBar; + +typedef struct _EmacsMenuBarClass +{ + GtkMenuBarClass parent; +} EmacsMenuBarClass; G_DEFINE_TYPE (EmacsMenuBar, emacs_menu_bar, GTK_TYPE_MENU_BAR) #endif diff --git a/src/gtkutil.h b/src/gtkutil.h index f850ecc421..b74244d84d 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -83,10 +83,6 @@ typedef struct xg_menu_item_cb_data_ } xg_menu_item_cb_data; -#ifdef HAVE_GTK3 -G_DECLARE_FINAL_TYPE (EmacsMenuBar, emacs_menu_bar, EMACS, MENU_BAR, GtkMenuBar) -#endif - extern bool xg_uses_old_file_dialog (void); extern char *xg_get_file_name (struct frame *f, commit c914572a46ca1e9de14bfeb4a6e993714f146851 Author: Po Lu Date: Tue Feb 22 18:41:28 2022 +0800 Improve XInput2 version checking * configure.ac: Check for various important structures from all versions of libXi. * src/xfns.c (setup_xi_event_mask): * src/xwidget.c (x_draw_xwidget_glyph_string): * src/xterm.c (x_init_master_valuators, handle_one_xevent) (x_term_init): Replace XI version checks based on protocol headers with new constants. * src/xterm.h (HAVE_XINPUT2_1, HAVE_XINPUT2_2, HAVE_XINPUT2_3) (HAVE_XINPUT2_4): New definitions. diff --git a/configure.ac b/configure.ac index 945e2ff8d4..00711cccd5 100644 --- a/configure.ac +++ b/configure.ac @@ -4478,13 +4478,13 @@ if test "${HAVE_X11}" = "yes" && test "${with_xinput2}" != "no"; then AC_MSG_WARN([You are building Emacs with GTK+ 2 and the X Input Extension version 2. This might lead to problems if your version of GTK+ is not built with support for XInput 2.]) fi - # Detect both faulty installations of libXi where gesture event - # types are defined but gesture event structures are not, and - # also where gesture event structures are empty. - AC_CHECK_MEMBERS([XIGesturePinchEvent.delta_unaccel_y], - [AC_DEFINE(HAVE_USABLE_XI_GESTURE_PINCH_EVENT, 1, - [Define to 1 if XInput headers define gesture structures correctly.])], - [], [[#include ]]) + + # Now check for some members (which used in conjunction with + # protocol definitions) can be used to determine the version of + # XInput supported. + AC_CHECK_MEMBERS([XIScrollClassInfo.type, XITouchClassInfo.type, + XIBarrierReleasePointerInfo.deviceid, XIGestureClassInfo.type], + [], [], [#include ]) fi fi AC_SUBST(XINPUT_CFLAGS) diff --git a/src/xfns.c b/src/xfns.c index b0e7af9d8f..9afadd16e9 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -3565,13 +3565,13 @@ setup_xi_event_mask (struct frame *f) XISetMask (m, XI_PropertyEvent); XISetMask (m, XI_HierarchyChanged); XISetMask (m, XI_DeviceChanged); -#ifdef XI_TouchBegin +#ifdef HAVE_XINPUT2_2 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 2) { XISetMask (m, XI_TouchBegin); XISetMask (m, XI_TouchUpdate); XISetMask (m, XI_TouchEnd); -#ifdef XI_GesturePinchBegin +#ifdef HAVE_XINPUT2_4 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4) { XISetMask (m, XI_GesturePinchBegin); diff --git a/src/xterm.c b/src/xterm.c index dce0bf306a..23721352f3 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -629,7 +629,7 @@ x_init_master_valuators (struct x_display_info *dpyinfo) { switch (device->classes[c]->type) { -#ifdef XIScrollClass /* XInput 2.1 */ +#ifdef HAVE_XINPUT2_1 case XIScrollClass: { XIScrollClassInfo *info = @@ -648,7 +648,7 @@ x_init_master_valuators (struct x_display_info *dpyinfo) break; } #endif -#ifdef XITouchClass /* XInput 2.2 */ +#ifdef HAVE_XINPUT2_2 case XITouchClass: { XITouchClassInfo *info; @@ -739,7 +739,7 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid) return NULL; } -#ifdef XI_TouchBegin +#ifdef HAVE_XINPUT2_2 static void xi_link_touch_point (struct xi_device_t *device, @@ -11046,7 +11046,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!device) goto XI_OTHER; -#ifdef XI_TouchBegin +#ifdef HAVE_XINPUT2_2 if (xev->flags & XIPointerEmulated) goto XI_OTHER; #endif @@ -11929,7 +11929,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, { struct xi_device_t *device; struct xi_touch_point_t *tem, *last; - int c, i; + int c; +#ifdef HAVE_XINPUT2_1 + int i; +#endif device = xi_device_from_id (dpyinfo, device_changed->deviceid); @@ -11959,7 +11962,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, { switch (device_changed->classes[c]->type) { -#ifdef XIScrollClass +#ifdef HAVE_XINPUT2_1 case XIScrollClass: { XIScrollClassInfo *info; @@ -11979,7 +11982,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, } #endif -#ifdef XITouchClass +#ifdef HAVE_XINPUT2_2 case XITouchClass: { XITouchClassInfo *info; @@ -11993,7 +11996,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, } } -#ifdef XIScrollClass +#ifdef HAVE_XINPUT2_1 for (c = 0; c < device_changed->num_classes; ++c) { if (device_changed->classes[c]->type == XIValuatorClass) @@ -12043,7 +12046,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto XI_OTHER; } -#ifdef XI_TouchBegin +#ifdef HAVE_XINPUT2_2 case XI_TouchBegin: { struct xi_device_t *device; @@ -12205,13 +12208,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, } #endif -#ifdef XI_GesturePinchBegin + +#ifdef HAVE_XINPUT2_4 case XI_GesturePinchBegin: case XI_GesturePinchUpdate: { x_display_set_last_user_time (dpyinfo, xi_event->time); -#ifdef HAVE_USABLE_XI_GESTURE_PINCH_EVENT XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event; struct xi_device_t *device = xi_device_from_id (dpyinfo, pev->deviceid); @@ -12243,7 +12246,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, make_float (pev->scale), make_float (pev->delta_angle)); } -#endif + /* Once again GTK seems to crash when confronted by events it doesn't understand. */ *finish = X_EVENT_DROP; @@ -16261,13 +16264,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) dpyinfo->supports_xi2 = false; int rc; int major = 2; -#ifdef XI_GesturePinchBegin /* XInput 2.4 */ +#ifdef HAVE_XINPUT2_4 int minor = 4; -#elif XI_BarrierHit /* XInput 2.3 */ +#elif defined HAVE_XINPUT2_3 /* XInput 2.3 */ int minor = 3; -#elif defined XI_TouchBegin /* XInput 2.2 */ +#elif defined HAVE_XINPUT2_2 /* XInput 2.2 */ int minor = 2; -#elif defined XIScrollClass /* XInput 2.1 */ +#elif defined HAVE_XINPUT2_1 /* XInput 2.1 */ int minor = 1; #else /* Some old version of XI2 we're not interested in. */ int minor = 0; diff --git a/src/xterm.h b/src/xterm.h index 14457b32cc..e2256ce2df 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -42,6 +42,10 @@ along with GNU Emacs. If not, see . */ #include #endif +#ifdef HAVE_XINPUT2 +#include +#endif + typedef Widget xt_or_gtk_widget; #endif @@ -1465,6 +1469,21 @@ struct xi_device_t *xi_device_from_id (struct x_display_info *, int); (nr).width = (rwidth), \ (nr).height = (rheight)) +#ifdef HAVE_XINPUT2 +#if HAVE_XISCROLLCLASSINFO_TYPE && defined XIScrollClass +#define HAVE_XINPUT2_1 +#endif +#if HAVE_XITOUCHCLASSINFO_TYPE && defined XITouchClass +#define HAVE_XINPUT2_2 +#endif +#if HAVE_XIBARRIERRELEASEPOINTERINFO_DEVICEID && defined XIBarrierPointerReleased +#define HAVE_XINPUT2_3 +#endif +#if HAVE_XIGESTURECLASSINFO_TYPE && defined XIGestureClass +#define HAVE_XINPUT2_4 +#endif +#endif + INLINE_HEADER_END #endif /* XTERM_H */ diff --git a/src/xwidget.c b/src/xwidget.c index 9fbf6678ae..e812b13f23 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -2853,7 +2853,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) XISetMask (m, XI_ButtonRelease); XISetMask (m, XI_Enter); XISetMask (m, XI_Leave); -#ifdef XI_GesturePinchBegin +#ifdef HAVE_XINPUT2_4 if (FRAME_DISPLAY_INFO (s->f)->xi2_version >= 4) { XISetMask (m, XI_GesturePinchBegin);