commit 8218aa14ed5fa2057695471f7b80e874d51bff39 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Fri Jun 21 08:50:55 2024 +0300 ; Avoid byte-compiler warning in comint.el * lisp/comint.el (subr-x): Actually require it (bug#71576). diff --git a/lisp/comint.el b/lisp/comint.el index 05b8edb747c..8860b3edb11 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -105,7 +105,7 @@ (require 'ansi-color) (require 'ansi-osc) (require 'regexp-opt) ;For regexp-opt-charset. -(eval-when-compile (require 'subr-x)) +(require 'subr-x) ;;; Buffer Local Variables: ;;============================================================================ commit e22b072423a6764632328d4e0fecc06a6e7efe9b Author: Jim Porter Date: Thu Jun 13 21:26:53 2024 -0700 Ensure navigating by paragraphs in Eshell stops at prompts and paragraphs The previous implementation in 6ae2b74ed20 only stopped at prompts, which isn't the right behavior (bug#61545). * lisp/eshell/em-prompt.el (eshell-forward-paragraph) (eshell-backward-paragraph): Reimplement to handle prompts and paragraphs (the latter by calling the original 'forward-paragraph'). * test/lisp/eshell/em-prompt-tests.el (em-prompt-test/next-previous-prompt/multiline): Rename. (em-prompt-test/forward-backward-paragraph-1): New function. (em-prompt-test/forward-backward-paragraph) (em-prompt-test/forward-backward-paragraph/multiline): New tests. diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el index b6556d29544..7de2bd4dc21 100644 --- a/lisp/eshell/em-prompt.el +++ b/lisp/eshell/em-prompt.el @@ -167,17 +167,39 @@ negative, find the Nth next match." (defun eshell-forward-paragraph (&optional n) "Move to the beginning of the Nth next prompt in the buffer. -Like `forward-paragraph', but navigates using fields." +Like `forward-paragraph', but also stops at the beginning of each prompt." (interactive "p") - (eshell-next-prompt n) - (goto-char (field-beginning (point) t))) + (unless n (setq n 1)) + (let (;; We'll handle the "paragraph" starts ourselves. + (paragraph-start regexp-unmatchable) + (inhibit-field-text-motion t)) + (cond + ((> n 0) + (while (and (> n 0) (< (point) (point-max))) + (let ((next-paragraph (save-excursion (forward-paragraph) (point))) + (next-prompt (save-excursion + (if-let ((match (text-property-search-forward + 'field 'prompt t t))) + (prop-match-beginning match) + (point-max))))) + (goto-char (min next-paragraph next-prompt))) + (setq n (1- n)))) + ((< n 0) + (while (and (< n 0) (> (point) (point-min))) + (let ((prev-paragraph (save-excursion (backward-paragraph) (point))) + (prev-prompt (save-excursion + (if (text-property-search-backward + 'field 'prompt t) + (point) + (point-min))))) + (goto-char (max prev-paragraph prev-prompt))) + (setq n (1+ n))))))) (defun eshell-backward-paragraph (&optional n) "Move to the beginning of the Nth previous prompt in the buffer. Like `backward-paragraph', but navigates using fields." (interactive "p") - (eshell-previous-prompt n) - (goto-char (field-beginning (point) t))) + (eshell-forward-paragraph (- (or n 1)))) (defun eshell-next-prompt (&optional n) "Move to end of Nth next prompt in the buffer." diff --git a/test/lisp/eshell/em-prompt-tests.el b/test/lisp/eshell/em-prompt-tests.el index 964609e6410..fbadade061f 100644 --- a/test/lisp/eshell/em-prompt-tests.el +++ b/test/lisp/eshell/em-prompt-tests.el @@ -39,6 +39,9 @@ ;;; Tests: + +;; Prompt output + (ert-deftest em-prompt-test/field-properties () "Check that field properties are properly set on Eshell output/prompts." (with-temp-eshell @@ -104,6 +107,9 @@ This tests the case when `eshell-highlight-prompt' is nil." 'front-sticky '(read-only field font-lock-face) 'rear-nonsticky '(read-only field font-lock-face))))))) + +;; Prompt navigation + (defun em-prompt-test/next-previous-prompt-1 () "Helper for checking forward/backward navigation of old prompts." (with-temp-eshell @@ -150,11 +156,52 @@ This tests the case when `eshell-highlight-prompt' is nil." "Check that navigating forward/backward through old prompts works correctly." (em-prompt-test/next-previous-prompt-1)) -(ert-deftest em-prompt-test/next-previous-prompt-multiline () +(ert-deftest em-prompt-test/next-previous-prompt/multiline () "Check old prompt forward/backward navigation for multiline prompts." (em-prompt-test--with-multiline (em-prompt-test/next-previous-prompt-1))) +(defun em-prompt-test/forward-backward-paragraph-1 () + "Helper for checking forward/backward navigation by paragraphs." + (with-temp-eshell + (cl-flet ((at-prompt-for-command-p (command) + (and (equal (point) (field-beginning)) + (equal (get-text-property (point) 'field) 'prompt) + (save-excursion + (goto-char (field-end)) + (equal (field-string) command))))) + (eshell-insert-command "echo 'high five'") + (eshell-insert-command "echo 'up high\n\ndown low'") + (eshell-insert-command "echo 'too slow'") + (insert "echo goodby") ; A partially-entered command. + (ert-info ("Go back to the last prompt") + (eshell-backward-paragraph) + (should (at-prompt-for-command-p "echo goodby"))) + (ert-info ("Go back to the paragraph break") + (eshell-backward-paragraph 2) + (should (looking-at "\ndown low\n"))) + (ert-info ("Go forward to the third prompt") + (eshell-forward-paragraph) + (should (at-prompt-for-command-p "echo 'too slow'\n"))) + (ert-info ("Go backward to before the first prompt") + (eshell-backward-paragraph 5) + (should (looking-back "Welcome to the Emacs shell\n"))) + (ert-info ("Go backward to the beginning of the buffer") + (eshell-backward-paragraph) + (should (bobp))) + (ert-info ("Go forward to the second prompt") + (eshell-forward-paragraph 3) + (should (at-prompt-for-command-p "echo 'up high\n\ndown low'\n")))))) + +(ert-deftest em-prompt-test/forward-backward-paragraph () + "Check that navigating forward/backward through paragraphs works correctly." + (em-prompt-test/forward-backward-paragraph-1)) + +(ert-deftest em-prompt-test/forward-backward-paragraph/multiline () + "Check paragraph forward/backward navigation for multiline prompts." + (em-prompt-test--with-multiline + (em-prompt-test/forward-backward-paragraph-1))) + (defun em-prompt-test/forward-backward-matching-input-1 () "Helper for checking forward/backward navigation via regexps." (with-temp-eshell commit 1a55e957ae57ec32ae960eabdb170b5b427392d4 Author: Jim Porter Date: Sat Jun 15 11:03:33 2024 -0700 Limit the amount of text we examine when looking for password prompts Both Comint and Eshell do this, and it can significantly slow down commands that write a lot of output (bug#71576). * lisp/comint.el (comint-password-prompt-max-length): New variable... (comint-watch-for-password-prompt): ... use it. Additionally, use the matched result for the Emacs-based password prompt. * lisp/eshell/esh-mode.el (eshell-password-prompt-max-length): New variable... (eshell-watch-for-password-prompt): ... use it. * etc/NEWS: Announce this change. diff --git a/etc/NEWS b/etc/NEWS index 7bbfc285935..e9507e80d1f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1002,9 +1002,16 @@ more information on this notation. --- *** Performance improvements for interactive output in Eshell. Interactive output in Eshell should now be significantly faster, -especially for built-in commands that can print large amounts of output -(e.g. "cat"). In addition, these commands can now update the display -periodically to show their progress. +especially for commands that can print large amounts of output +(e.g. "cat"). For external commands, Eshell saves time by only looking +for password prompts in the last 256 characters of each block of output. +To restore the previous behavior when checking for password prompts, set +'eshell-password-prompt-max-length' to 'most-positive-fixnum'. + +--- +*** Eshell built-in commands can now display progress. +Eshell built-in commands like "cat" and "ls" now update the display +periodically while running to show their progress. +++ *** New special reference type '#'. @@ -1160,6 +1167,14 @@ environment variable 'HISTFILE'. In a 'shell' buffer, this user option is connection-local. +--- +*** Performance improvements for interactive output. +Interactive output in Shell mode now scans more selectively for password +prompts by only examining the last 256 characters of each block of +output, reducing the time spent when printing large amounts of output. +To restore the old behavior, set 'comint-password-prompt-max-length' to +'most-positive-fixnum'. + ** Make mode *** The Makefile browser is now obsolete. diff --git a/lisp/comint.el b/lisp/comint.el index 3804932e01c..05b8edb747c 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -426,6 +426,11 @@ This is used by `comint-watch-for-password-prompt'." :type 'regexp :group 'comint) +(defvar comint-password-prompt-max-length 256 + "The maximum amount of text to examine when matching password prompts. +This is used by `comint-watch-for-password-prompt' to reduce the amount +of time spent searching for password prompts.") + ;; Here are the per-interpreter hooks. (defvar comint-get-old-input (function comint-get-old-input-default) "Function that returns old text in Comint mode. @@ -2563,23 +2568,26 @@ to detect the need to (prompt and) send a password. Ignores any carriage returns (\\r) in STRING. This function could be in the list `comint-output-filter-functions'." - (when (let ((case-fold-search t)) - (string-match comint-password-prompt-regexp - (string-replace "\r" "" string))) - ;; Use `run-at-time' in order not to pause execution of the - ;; process filter with a minibuffer - (run-at-time - 0 nil - (lambda (current-buf) - (with-current-buffer current-buf - (let ((comint--prompt-recursion-depth - (1+ comint--prompt-recursion-depth))) - (if (> comint--prompt-recursion-depth 10) - (message "Password prompt recursion too deep") - (when (get-buffer-process (current-buffer)) - (comint-send-invisible - (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+"))))))) - (current-buffer)))) + (let ((string (string-limit string comint-password-prompt-max-length t)) + prompt) + (when (let ((case-fold-search t)) + (string-match comint-password-prompt-regexp + (string-replace "\r" "" string))) + (setq prompt (string-trim (match-string 0 string) + "[ \n\r\t\v\f\b\a]+" "\n+")) + ;; Use `run-at-time' in order not to pause execution of the + ;; process filter with a minibuffer + (run-at-time + 0 nil + (lambda (current-buf) + (with-current-buffer current-buf + (let ((comint--prompt-recursion-depth + (1+ comint--prompt-recursion-depth))) + (if (> comint--prompt-recursion-depth 10) + (message "Password prompt recursion too deep") + (when (get-buffer-process (current-buffer)) + (comint-send-invisible prompt)))))) + (current-buffer))))) ;; Low-level process communication diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index ec1a07b7e2f..34ce82cfbc4 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -198,6 +198,11 @@ This is used by `eshell-watch-for-password-prompt'." :type 'directory :group 'eshell) +(defvar eshell-password-prompt-max-length 256 + "The maximum amount of text to examine when matching password prompts. +This is used by `eshell-watch-for-password-prompt' to reduce the amount +of time spent searching for password prompts.") + (defvar eshell-first-time-p t "A variable which is non-nil the first time Eshell is loaded.") @@ -949,19 +954,20 @@ buffer's process if STRING contains a password prompt defined by This function could be in the list `eshell-output-filter-functions'." (when (eshell-head-process) (save-excursion - (let ((case-fold-search t)) - (goto-char eshell-last-output-block-begin) - (beginning-of-line) - (if (re-search-forward eshell-password-prompt-regexp - eshell-last-output-end t) - ;; Use `run-at-time' in order not to pause execution of - ;; the process filter with a minibuffer - (run-at-time - 0 nil - (lambda (current-buf) - (with-current-buffer current-buf - (eshell-send-invisible))) - (current-buffer))))))) + (goto-char (max eshell-last-output-block-begin + (- eshell-last-output-end + eshell-password-prompt-max-length))) + (when (let ((case-fold-search t)) + (re-search-forward eshell-password-prompt-regexp + eshell-last-output-end t)) + ;; Use `run-at-time' in order not to pause execution of the + ;; process filter with a minibuffer. + (run-at-time + 0 nil + (lambda (current-buf) + (with-current-buffer current-buf + (eshell-send-invisible))) + (current-buffer)))))) (custom-add-option 'eshell-output-filter-functions 'eshell-watch-for-password-prompt) commit 72f2b01e318054e2e040f7de676e9c4919533161 Author: Tomas Fabrizio Orsi Date: Sat Jun 8 12:11:18 2024 -0300 Allow giving "ping" flags with `C-u M-x ping` * lisp/net/net-utils.el (ping): With a prefix argument, prompt the user for flags to pass to the "ping" command. (Bug#71438) * etc/NEWS: Document the above change. Copyright-paperwork-exempt: yes diff --git a/etc/NEWS b/etc/NEWS index 3b18972860f..7bbfc285935 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1961,6 +1961,11 @@ The following new XML schemas are now supported: ** color.el now supports the Oklab color representation. +--- +** 'M-x ping' can now give "ping" additional flags. +Typing 'C-u M-x ping' prompts first for the host, and then for the flags +to give to "ping". + * New Modes and Packages in Emacs 30.1 diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el index 83842cd6788..fe68054af3e 100644 --- a/lisp/net/net-utils.el +++ b/lisp/net/net-utils.el @@ -425,22 +425,35 @@ This variable is only used if the variable options))) ;;;###autoload -(defun ping (host) - "Ping HOST. -If your system's ping continues until interrupted, you can try setting -`ping-program-options'." +(defun ping (host &optional flags) + "Ping HOST using `ping-program'. + +The user option `ping-program-options' is passed as flags to +`ping-program'. With a \\[universal-argument] prefix arg, prompt the +user for the flags to pass. + +When called from Lisp, the optional argument FLAGS, if non-nil, is a +list of strings that will be passed as flags for the `ping-program'. If +FLAGS is nil, `ping-program-options' will be used. + +If your system's ping continues until interrupted, you can try using a +prefix argument or setting `ping-program-options'." (interactive (list (let ((default (ffap-machine-at-point))) - (read-string (format-prompt "Ping host" default) nil nil default)))) - (let ((options - (if ping-program-options + (read-string (format-prompt "Ping host" default) nil nil default)) + (when current-prefix-arg + (split-string + (read-string (format-prompt "Ping options" ping-program-options) + nil nil ping-program-options))))) + (let ((full-command + (if (or (equal flags (list "")) (not flags)) (append ping-program-options (list host)) - (list host)))) + (append flags (list host))))) (net-utils-run-program (concat "Ping" " " host) (concat "** Ping ** " ping-program " ** " host) ping-program - options))) + full-command))) ;;;###autoload (defun nslookup-host (host &optional name-server) commit a6296fda5ee4d54902f23028948643e1ac0de320 Author: Juri Linkov Date: Thu Jun 20 19:49:30 2024 +0300 * lisp/hi-lock.el (hi-lock-revert-buffer-rehighlight): Restore same faces. After reverting the buffer apply all previous patterns with exactly the same faces as were assigned to patterns before. diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el index 3c26cc84509..64b84cdf859 100644 --- a/lisp/hi-lock.el +++ b/lisp/hi-lock.el @@ -868,11 +868,10 @@ SPACES-REGEXP is a regexp to substitute spaces in font-lock search." Apply the previous patterns after reverting the buffer." (when-let ((patterns hi-lock-interactive-lighters)) (lambda () - (setq hi-lock-interactive-lighters nil - hi-lock-interactive-patterns nil) - (let ((hi-lock-auto-select-face t)) - (dolist (pattern (reverse patterns)) - (highlight-regexp (car pattern) (hi-lock-read-face-name))))))) + (when hi-lock-interactive-lighters + (hi-lock-unface-buffer t)) + (dolist (pattern (reverse patterns)) + (highlight-regexp (car pattern) (cadr (nth 1 (caddr pattern)))))))) (defvar hi-lock--hashcons-hash (make-hash-table :test 'equal :weakness t) commit 6c85b0311127332621e79217e7a208b679c89d5a Author: Stefan Kangas Date: Thu Jun 20 15:59:57 2024 +0200 Fix misspelled function name in comp.c * src/comp.c (retrieve_block): Rename from 'retrive_block'. Update all callers. diff --git a/src/comp.c b/src/comp.c index 9ebb2f7fed6..df7fa3a5199 100644 --- a/src/comp.c +++ b/src/comp.c @@ -878,7 +878,7 @@ bcall0 (Lisp_Object f) } static gcc_jit_block * -retrive_block (Lisp_Object block_name) +retrieve_block (Lisp_Object block_name) { Lisp_Object value = Fgethash (block_name, comp.func_blocks_h, Qnil); @@ -2298,7 +2298,7 @@ emit_limple_insn (Lisp_Object insn) if (EQ (op, Qjump)) { /* Unconditional branch. */ - gcc_jit_block *target = retrive_block (arg[0]); + gcc_jit_block *target = retrieve_block (arg[0]); gcc_jit_block_end_with_jump (comp.block, NULL, target); } else if (EQ (op, Qcond_jump)) @@ -2306,8 +2306,8 @@ emit_limple_insn (Lisp_Object insn) /* Conditional branch. */ gcc_jit_rvalue *a = emit_mvar_rval (arg[0]); gcc_jit_rvalue *b = emit_mvar_rval (arg[1]); - gcc_jit_block *target1 = retrive_block (arg[2]); - gcc_jit_block *target2 = retrive_block (arg[3]); + gcc_jit_block *target1 = retrieve_block (arg[2]); + gcc_jit_block *target2 = retrieve_block (arg[3]); if ((!NILP (CALL1I (comp-cstr-imm-vld-p, arg[0])) && NILP (CALL1I (comp-cstr-imm, arg[0]))) @@ -2330,8 +2330,8 @@ emit_limple_insn (Lisp_Object insn) gcc_jit_context_new_rvalue_from_int (comp.ctxt, comp.ptrdiff_type, XFIXNUM (arg[0])); - gcc_jit_block *target1 = retrive_block (arg[1]); - gcc_jit_block *target2 = retrive_block (arg[2]); + gcc_jit_block *target1 = retrieve_block (arg[1]); + gcc_jit_block *target2 = retrieve_block (arg[2]); gcc_jit_rvalue *test = gcc_jit_context_new_comparison ( comp.ctxt, NULL, @@ -2360,8 +2360,8 @@ emit_limple_insn (Lisp_Object insn) gcc_jit_context_new_rvalue_from_int (comp.ctxt, comp.int_type, h_num); - gcc_jit_block *handler_bb = retrive_block (arg[2]); - gcc_jit_block *guarded_bb = retrive_block (arg[3]); + gcc_jit_block *handler_bb = retrieve_block (arg[2]); + gcc_jit_block *guarded_bb = retrieve_block (arg[3]); emit_limple_push_handler (handler, handler_type, handler_bb, guarded_bb, arg[0]); } @@ -4346,7 +4346,7 @@ compile_function (Lisp_Object func) declare_block (block_name); } - gcc_jit_block_add_assignment (retrive_block (Qentry), + gcc_jit_block_add_assignment (retrieve_block (Qentry), NULL, comp.func_relocs_local, gcc_jit_lvalue_as_rvalue (comp.func_relocs)); @@ -4361,7 +4361,7 @@ compile_function (Lisp_Object func) xsignal1 (Qnative_ice, build_string ("basic block is missing or empty")); - comp.block = retrive_block (block_name); + comp.block = retrieve_block (block_name); while (CONSP (insns)) { Lisp_Object insn = XCAR (insns); commit 199fcbe2d30ff021491b345decf22024913ca40f Author: Po Lu Date: Thu Jun 20 21:29:39 2024 +0800 Fix NS build * src/nsfns.m (Fx_create_frame, ns_create_tip_frame): Remove references to deleted variable. (bug#71638) diff --git a/src/nsfns.m b/src/nsfns.m index d9c1296056c..add7a93dfba 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1312,14 +1312,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. block_input (); #ifdef NS_IMPL_COCOA - mac_register_font_driver (f); + mac_register_font_driver (f); #else - register_font_driver (&nsfont_driver, f); + register_font_driver (&nsfont_driver, f); #endif - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -3022,9 +3019,6 @@ Frames are listed from topmost (first) to bottommost (last). */) #endif unblock_input (); - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); commit 41cbfead7e2bce2f563e37a9a737a00a7b86e7f1 Author: Stefan Kangas Date: Thu Jun 20 13:30:11 2024 +0200 Remove more references to Windows 95 * doc/lispref/frames.texi (Window System Selections): * doc/misc/ediff.texi (Patch and Diff Programs): * doc/misc/efaq-w32.texi (Third-party multibyte, Swap Caps NT) (Subprocesses and floppy drive): * etc/PROBLEMS: * lisp/printing.el (pr-path-alist, pr-command): * lisp/ps-print.el: Remove more references to Windows 95, which is not supported by Emacs. diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 2686ae93a33..342f88eb8c0 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -4096,7 +4096,7 @@ the very rare cases when the information provided by the clipboard data is unusable for some reason. The default value of this variable is the system code page under -MS-Windows 95, 98 or Me, @code{utf-16le-dos} on Windows +MS-Windows 98 or Me, @code{utf-16le-dos} on Windows NT/W2K/XP/Vista/7/8/10/11, @code{iso-latin-1-dos} on MS-DOS, and @code{nil} elsewhere. @end defopt diff --git a/doc/misc/ediff.texi b/doc/misc/ediff.texi index e8ecb218674..749025c870b 100644 --- a/doc/misc/ediff.texi +++ b/doc/misc/ediff.texi @@ -1877,7 +1877,7 @@ Customize interface instead of using @code{setq} directly.) This variable specifies the coding system to use when reading the output that the programs @code{diff3} and @code{diff} send to Emacs. The default is @code{raw-text}, and this should work fine in Unix and in most -cases under Windows NT/95/98/2000. There are @code{diff} programs +cases under Windows NT/98/2000. There are @code{diff} programs for which the default option doesn't work under Windows. In such cases, @code{raw-text-dos} might work. If not, you will have to experiment with other coding systems or use GNU diff. diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi index 9756345042e..c5ba6c8609f 100644 --- a/doc/misc/efaq-w32.texi +++ b/doc/misc/efaq-w32.texi @@ -630,7 +630,7 @@ REGEDIT4 @end itemize @node Swap Caps 98 -@subsubsection Windows 95/98/ME +@subsubsection Windows 98/ME Microsoft has a tool called keyremap that is part of their Kernel Toys add-ons for Windows 95. The tool has also been confirmed to work on Windows 98. @@ -1078,7 +1078,7 @@ mirrors}. @vindex w32-enable-unicode-output You probably only need to do this on the non-Unicode versions of Windows -(95, 98 and ME), and even then, various Windows and Internet Explorer +(98 and ME), and even then, various Windows and Internet Explorer updates have made third party software unnecessary in most cases. If you are having trouble displaying text, try defining a fontset with the font for the languages that the third party software handles @@ -1321,9 +1321,9 @@ floppy in the drive, check to see if your virus software is causing the problem. @node Killing subprocesses -@section Killing subprocesses on Windows 95/98/Me -@cindex subprocess, killing on Windows 95/98/ME -@cindex killing subprocesses, Windows 95/98/ME +@section Killing subprocesses on Windows 98/Me +@cindex subprocess, killing on Windows 98/ME +@cindex killing subprocesses, Windows 98/ME @cindex shutdown, complaints about cmdproxy.exe running Emacs cannot guarantee that a subprocess gets killed on Windows 95 and diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 9cbcee51fe8..59bd2cd497c 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -4343,14 +4343,14 @@ for menus. Help text is only available in later versions of Windows. This character seems to be trapped by the kernel in Windows 95. You can enter M-f6 by typing ESC f6. -*** MS-Windows 95/98/ME: subprocesses do not terminate properly. +*** MS-Windows 98/ME: subprocesses do not terminate properly. This is a limitation of the Operating System, and can cause problems when shutting down Windows. Ensure that all subprocesses are exited cleanly before exiting Emacs. For more details, see the Emacs on MS Windows FAQ (info manual "efaq-w32"). -*** MS-Windows 95/98/ME: crashes when Emacs invokes non-existent programs. +*** MS-Windows 98/ME: crashes when Emacs invokes non-existent programs. When a program you are trying to run is not found on the PATH, Windows might respond by crashing or locking up your system. In diff --git a/lisp/printing.el b/lisp/printing.el index d9bc97d48af..404d1be619f 100644 --- a/lisp/printing.el +++ b/lisp/printing.el @@ -1320,10 +1320,10 @@ ENTRY It's a symbol, used to identify this entry. Unix system. `cygwin' this entry is used when Emacs is running on Windows - 95/98/NT/2000 with Cygwin. + 98/NT/2000 with Cygwin. `windows' this entry is used when Emacs is running on Windows - 95/98/NT/2000. + 98/NT/2000. DIRECTORY It should be a string or a symbol. If it's a symbol, it should exist an equal entry in `pr-path-alist'. If it's a string, @@ -5462,7 +5462,7 @@ otherwise, gives an error. When using `pr-path-alist' to find COMMAND, the entries `cygwin', `windows' and `unix' are used (see `pr-path-alist' for documentation). -If Emacs is running on Windows 95/98/NT/2000, tries to find COMMAND, +If Emacs is running on Windows 98/NT/2000, tries to find COMMAND, COMMAND.exe, COMMAND.bat and COMMAND.com in this order." (if (string= command "") command diff --git a/lisp/ps-print.el b/lisp/ps-print.el index b73d28280ef..97b19e362bb 100644 --- a/lisp/ps-print.el +++ b/lisp/ps-print.el @@ -191,7 +191,7 @@ ;; inserted at end of PostScript generated. Non-nil means do so. The default ;; is nil (don't insert). ;; -;; If you're using Emacs for Windows 95/98/NT or MS-DOS, don't forget to +;; If you're using Emacs for Windows 98/NT or MS-DOS, don't forget to ;; customize the following variables: `ps-printer-name', ;; `ps-printer-name-option', `ps-lpr-command', `ps-lpr-switches' and ;; `ps-spool-config'. See these variables documentation in the code or by commit 74af691b90e69eb70d47782419edfab7d6503dc2 Author: Eli Zaretskii Date: Thu Jun 20 13:42:04 2024 +0300 Fix last change * src/xdisp.c (handle_line_prefix): Set the 'align_visually_p' only after pushing the iterator. (pop_it): Reset the 'align_visually_p' flag. (Bug#71605) diff --git a/src/xdisp.c b/src/xdisp.c index 5987813cd28..18ac5b69d7e 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -7288,6 +7288,7 @@ pop_it (struct it *it) it->bidi_p = p->bidi_p; it->paragraph_embedding = p->paragraph_embedding; it->from_disp_prop_p = p->from_disp_prop_p; + it->align_visually_p = false; if (it->bidi_p) { bidi_pop_it (&it->bidi_it); @@ -24488,17 +24489,14 @@ static void handle_line_prefix (struct it *it) { Lisp_Object prefix; + bool wrap_prop = false; if (it->continuation_lines_width > 0) { prefix = get_line_prefix_it_property (it, Qwrap_prefix); if (NILP (prefix)) prefix = Vwrap_prefix; - /* Interpreting :align-to relative to the beginning of the logical - line effectively renders this feature unusable, so we make an - exception for this use of :align-to. */ - if (!NILP (prefix)) - it->align_visually_p = true; + wrap_prop = true; } else { @@ -24513,6 +24511,11 @@ handle_line_prefix (struct it *it) iterator stack overflows. So, don't wrap the prefix. */ it->line_wrap = TRUNCATE; it->avoid_cursor_p = true; + /* Interpreting :align-to relative to the beginning of the logical + line effectively renders this feature unusable, so we make an + exception for this use of :align-to. */ + if (wrap_prop && CONSP (prefix) && EQ (XCAR (prefix), Qspace)) + it->align_visually_p = true; } } commit 775aeabcfbf84c950610738cd130bf652c77bfa5 Author: Eli Zaretskii Date: Thu Jun 20 12:52:06 2024 +0300 Fix use of ':align-to' in 'wrap-prefix' * src/dispextern.h (struct it): New flag 'align_visually_p'. * src/xdisp.c (handle_line_prefix): Set the 'align_visually_p' flag for 'wrap-prefix'. (produce_stretch_glyph): If 'align_visually_p' flag is set, count the :align-to offset from the beginning of the screen line, not from BOL. (Bug#71605) * doc/lispref/display.texi (Truncation, Specified Space): Document the special handling of ':align-to' in 'wrap-prefix'. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index d5c96d13e02..34096196df4 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -192,7 +192,9 @@ never used.) Its value may be a string or an image (@pxref{Other Display Specs}), or a stretch of whitespace such as specified by the @code{:width} or @code{:align-to} display properties (@pxref{Specified Space}). The value is interpreted in the same way as a @code{display} -text property. @xref{Display Property}. +text property, with one important difference: the horizontal position +specified by @code{:align-to} is measured from the visual beginning of +the screen line. @xref{Display Property}. A wrap prefix may also be specified for regions of text, using the @code{wrap-prefix} text or overlay property. This takes precedence @@ -5354,7 +5356,9 @@ Scrolling}), @var{hpos} is measured from the beginning of the logical line, not from the visual beginning of the screen line. This way, alignment produced by @code{:align-to} is consistent with functions that count columns, such as @code{current-column} and -@code{move-to-column} (@pxref{Columns}). +@code{move-to-column} (@pxref{Columns}). (There's a single exception +from this rule: when @code{:align-to} is used to specify whitespace of +the @code{wrap-prefix} variable or text property, @pxref{Truncation}.) @end table You should use one and only one of the above properties. You can diff --git a/src/dispextern.h b/src/dispextern.h index 85012130689..51dc354d37c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2629,6 +2629,11 @@ struct it the current row. */ bool_bf line_number_produced_p : 1; + /* If true, the :align-to argument should be counted relative to the + beginning of the screen line, not the logical line. Used by + 'wrap-prefix'. */ + bool_bf align_visually_p : 1; + enum line_wrap_method line_wrap; /* The ID of the default face to use. One of DEFAULT_FACE_ID, diff --git a/src/xdisp.c b/src/xdisp.c index 0148cd76ada..5987813cd28 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -24494,6 +24494,11 @@ handle_line_prefix (struct it *it) prefix = get_line_prefix_it_property (it, Qwrap_prefix); if (NILP (prefix)) prefix = Vwrap_prefix; + /* Interpreting :align-to relative to the beginning of the logical + line effectively renders this feature unusable, so we make an + exception for this use of :align-to. */ + if (!NILP (prefix)) + it->align_visually_p = true; } else { @@ -31972,7 +31977,9 @@ produce_stretch_glyph (struct it *it) && calc_pixel_width_or_height (&tem, it, prop, font, true, &align_to)) { - int x = it->current_x + it->continuation_lines_width; + int x = it->current_x + (it->align_visually_p + ? 0 + : it->continuation_lines_width); int x0 = x; /* Adjust for line numbers, if needed. */ if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) commit b8affdb7b5760b3681ada9dcba78dd3c07405b61 Author: Po Lu Date: Thu Jun 20 17:20:10 2024 +0800 * src/frame.c (gui_set_font): Reference image cache after reassignment. diff --git a/src/frame.c b/src/frame.c index cf894db6836..7f4bf274ad9 100644 --- a/src/frame.c +++ b/src/frame.c @@ -4838,6 +4838,7 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) new image cache with IWIDTH. */ FRAME_IMAGE_CACHE (f)->refcount--; FRAME_IMAGE_CACHE (f) = share_image_cache (f); + FRAME_IMAGE_CACHE (f)->refcount++; } } commit e6169e9de198bd32f65167ba0e36090e4471dad5 Author: Po Lu Date: Thu Jun 20 17:03:54 2024 +0800 ; * src/frame.c (make_frame): Typo. diff --git a/src/frame.c b/src/frame.c index 1bb92e1f9b0..cf894db6836 100644 --- a/src/frame.c +++ b/src/frame.c @@ -983,7 +983,7 @@ make_frame (bool mini_p) f->tooltip = false; f->was_invisible = false; f->child_frame_border_width = -1; - f->face_caches = NULL; + f->face_cache = NULL; f->image_cache = NULL; f->last_tab_bar_item = -1; #ifndef HAVE_EXT_TOOL_BAR commit cebca072c33937b84995a62c35c16441d23bb86d Author: Po Lu Date: Thu Jun 20 17:03:36 2024 +0800 Correctly cache images when frames vary in their font metrics * src/alloc.c (mark_frame): Mark this frame's image cache, if it exist. (mark_terminals): Cease marking T->image_cache. * src/androidfns.c (unwind_create_frame, Fx_create_frame) (android_create_tip_frame): * src/haikufns.c (unwind_create_frame, haiku_create_frame) (haiku_create_tip_frame): * src/nsfns.m (unwind_create_frame): * src/pgtkfns.c (unwind_create_frame, Fx_create_frame) (x_create_tip_frame): * src/xfns.c (unwind_create_frame, Fx_create_frame) (x_create_tip_frame): * src/w32fns.c (unwind_create_frame, Fx_create_frame) (w32_create_tip_frame): Remove adjustments of the frame image cache's reference count rendered redundant by the assignment of image caches to individual frames rather than terminals. * src/dispextern.h (struct image_cache) : New field. * src/frame.c (gui_set_font): In lieu of clearing F's image cache unconditionally, establish whether the column width as considered by compute_image_size has changed, and if so, adjust or reassign the frame's image cache. (make_frame): Clear F->image_cache. * src/frame.h (struct frame) : New field. (FRAME_IMAGE_CACHE): Return F->image_cache. * src/image.c (make_image_cache): Clear C->scaling_col_width. (cache_image): Adjust to new means of assigning image caches to frames. * src/termhooks.h (struct terminal) : Delete field. * src/xfaces.c (init_frame_faces): Do image cache assignment with all new frames. diff --git a/src/alloc.c b/src/alloc.c index 9304e4e42bb..666f77bfce1 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -7055,6 +7055,13 @@ mark_frame (struct Lisp_Vector *ptr) for (tem = f->conversion.actions; tem; tem = tem->next) mark_object (tem->data); #endif + +#ifdef HAVE_WINDOW_SYSTEM + /* Mark this frame's image cache, though it might be common to several + frames with the same font size. */ + if (FRAME_IMAGE_CACHE (f)) + mark_image_cache (FRAME_IMAGE_CACHE (f)); +#endif /* HAVE_WINDOW_SYSTEM */ } static void @@ -7515,12 +7522,6 @@ mark_terminals (void) for (t = terminal_list; t; t = t->next_terminal) { eassert (t->name != NULL); -#ifdef HAVE_WINDOW_SYSTEM - /* If a terminal object is reachable from a stacpro'ed object, - it might have been marked already. Make sure the image cache - gets marked. */ - mark_image_cache (t->image_cache); -#endif /* HAVE_WINDOW_SYSTEM */ if (!vectorlike_marked_p (&t->header)) mark_vectorlike (&t->header); } diff --git a/src/androidfns.c b/src/androidfns.c index 84558350dc0..7595e176618 100644 --- a/src/androidfns.c +++ b/src/androidfns.c @@ -32,9 +32,6 @@ along with GNU Emacs. If not, see . */ #ifndef ANDROID_STUBIFY -/* Some kind of reference count for the image cache. */ -static ptrdiff_t image_cache_refcount; - /* The frame of the currently visible tooltip, or nil if none. */ static Lisp_Object tip_frame; @@ -654,17 +651,6 @@ unwind_create_frame (Lisp_Object frame) /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) { - /* If the frame's image cache refcount is still the same as our - private shadow variable, it means we are unwinding a frame - for which we didn't yet call init_frame_faces, where the - refcount is incremented. Therefore, we increment it here, so - that free_frame_faces, called in x_free_frame_resources - below, will not mistakenly decrement the counter that was not - incremented yet to account for this new frame. */ - if (FRAME_IMAGE_CACHE (f) != NULL - && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) - FRAME_IMAGE_CACHE (f)->refcount++; - android_free_frame_resources (f); free_glyphs (f); return Qt; @@ -944,10 +930,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, register_font_driver (&androidfont_driver, f); register_font_driver (&android_sfntfont_driver, f); - image_cache_refcount = (FRAME_IMAGE_CACHE (f) - ? FRAME_IMAGE_CACHE (f)->refcount - : 0); - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -2023,9 +2005,6 @@ android_create_tip_frame (struct android_display_info *dpyinfo, register_font_driver (&androidfont_driver, f); register_font_driver (&android_sfntfont_driver, f); - image_cache_refcount - = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); diff --git a/src/dispextern.h b/src/dispextern.h index 35e1893c83c..85012130689 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3292,6 +3292,11 @@ struct image_cache /* Reference count (number of frames sharing this cache). */ ptrdiff_t refcount; + + /* Column width by which images whose QCscale property is Qdefault + will be scaled, which is 10 or FRAME_COLUMN_WIDTH of each frame + assigned this image cache, whichever is greater. */ + int scaling_col_width; }; /* Size of bucket vector of image caches. Should be prime. */ @@ -3708,6 +3713,9 @@ int smaller_face (struct frame *, int, int); int face_with_height (struct frame *, int, int); int lookup_derived_face (struct window *, struct frame *, Lisp_Object, int, bool); +#ifdef HAVE_WINDOW_SYSTEM +extern struct image_cache *share_image_cache (struct frame *f); +#endif /* HAVE_WINDOW_SYSTEM */ void init_frame_faces (struct frame *); void free_frame_faces (struct frame *); void recompute_basic_faces (struct frame *); diff --git a/src/frame.c b/src/frame.c index 25620217680..1bb92e1f9b0 100644 --- a/src/frame.c +++ b/src/frame.c @@ -983,6 +983,8 @@ make_frame (bool mini_p) f->tooltip = false; f->was_invisible = false; f->child_frame_border_width = -1; + f->face_caches = NULL; + f->image_cache = NULL; f->last_tab_bar_item = -1; #ifndef HAVE_EXT_TOOL_BAR f->last_tool_bar_item = -1; @@ -4732,7 +4734,7 @@ void gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { Lisp_Object font_object; - int fontset = -1; + int fontset = -1, iwidth; /* Set the frame parameter back to the old value because we may fail to use ARG as the new parameter value. */ @@ -4811,9 +4813,33 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) /* Recalculate toolbar height. */ f->n_tool_bar_rows = 0; - /* Clean F's image cache of images whose values derive from the font - width. */ - clear_image_cache (f, Qauto); + /* Re-initialize F's image cache. Since `set_new_font_hook' might + have changed the frame's column width, by which images are scaled, + it might likewise need to be assigned a different image cache, or + have its existing cache adjusted, if by coincidence it is its sole + user. */ + + iwidth = max (10, FRAME_COLUMN_WIDTH (f)); + if (FRAME_IMAGE_CACHE (f) + && (iwidth != FRAME_IMAGE_CACHE (f)->scaling_col_width)) + { + eassert (FRAME_IMAGE_CACHE (f)->refcount >= 1); + if (FRAME_IMAGE_CACHE (f)->refcount == 1) + { + /* This frame is the only user of this image cache. */ + FRAME_IMAGE_CACHE (f)->scaling_col_width = iwidth; + /* Clean F's image cache of images whose values are derived + from the font width. */ + clear_image_cache (f, Qauto); + } + else + { + /* Release the current image cache, and reuse or allocate a + new image cache with IWIDTH. */ + FRAME_IMAGE_CACHE (f)->refcount--; + FRAME_IMAGE_CACHE (f) = share_image_cache (f); + } + } /* Ensure we redraw it. */ clear_current_matrices (f); diff --git a/src/frame.h b/src/frame.h index 63bcce259af..1d920d1a6bc 100644 --- a/src/frame.h +++ b/src/frame.h @@ -288,6 +288,12 @@ struct frame /* Cache of realized faces. */ struct face_cache *face_cache; +#ifdef HAVE_WINDOW_SYSTEM + /* Cache of realized images, which may be shared with other + frames. */ + struct image_cache *image_cache; +#endif /* HAVE_WINDOW_SYSTEM */ + /* Tab-bar item index of the item on which a mouse button was pressed. */ int last_tab_bar_item; @@ -909,7 +915,7 @@ default_pixels_per_inch_y (void) #define FRAME_KBOARD(f) ((f)->terminal->kboard) /* Return a pointer to the image cache of frame F. */ -#define FRAME_IMAGE_CACHE(F) ((F)->terminal->image_cache) +#define FRAME_IMAGE_CACHE(F) ((F)->image_cache) #define XFRAME(p) \ (eassert (FRAMEP (p)), XUNTAG (p, Lisp_Vectorlike, struct frame)) diff --git a/src/haikufns.c b/src/haikufns.c index 870b6f58f02..4a31def4def 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -73,9 +73,6 @@ static Lisp_Object tip_last_parms; static void haiku_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); static void haiku_set_title (struct frame *, Lisp_Object, Lisp_Object); -/* The number of references to an image cache. */ -static ptrdiff_t image_cache_refcount; - static Lisp_Object get_geometry_from_preferences (struct haiku_display_info *dpyinfo, Lisp_Object parms) @@ -627,29 +624,8 @@ unwind_create_frame (Lisp_Object frame) /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) { -#if defined GLYPH_DEBUG && defined ENABLE_CHECKING - struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); -#endif - - /* If the frame's image cache refcount is still the same as our - private shadow variable, it means we are unwinding a frame - for which we didn't yet call init_frame_faces, where the - refcount is incremented. Therefore, we increment it here, so - that free_frame_faces, called in free_frame_resources later, - will not mistakenly decrement the counter that was not - incremented yet to account for this new frame. */ - if (FRAME_IMAGE_CACHE (f) != NULL - && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) - FRAME_IMAGE_CACHE (f)->refcount++; - haiku_free_frame_resources (f); free_glyphs (f); - -#if defined GLYPH_DEBUG && defined ENABLE_CHECKING - /* Check that reference counts are indeed correct. */ - if (dpyinfo->terminal->image_cache) - eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); -#endif } } @@ -807,9 +783,6 @@ haiku_create_frame (Lisp_Object parms) #endif register_font_driver (&haikufont_driver, f); - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -1098,9 +1071,6 @@ haiku_create_tip_frame (Lisp_Object parms) #endif register_font_driver (&haikufont_driver, f); - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); diff --git a/src/image.c b/src/image.c index 879531d5264..2945447b962 100644 --- a/src/image.c +++ b/src/image.c @@ -2195,6 +2195,8 @@ make_image_cache (void) c->used = c->refcount = 0; c->images = xmalloc (c->size * sizeof *c->images); c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets); + /* This value should never be encountered. */ + c->scaling_col_width = -1; return c; } @@ -3620,7 +3622,10 @@ cache_image (struct frame *f, struct image *img) ptrdiff_t i; if (!c) - c = FRAME_IMAGE_CACHE (f) = make_image_cache (); + { + c = FRAME_IMAGE_CACHE (f) = share_image_cache (f); + c->refcount++; + } /* Find a free slot in c->images. */ for (i = 0; i < c->used; ++i) diff --git a/src/nsfns.m b/src/nsfns.m index 24fabbe2eaa..d9c1296056c 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -87,8 +87,6 @@ Updated by Christian Limpach (chris@nice.ch) static Lisp_Object as_script, *as_result; static int as_status; -static ptrdiff_t image_cache_refcount; - static struct ns_display_info *ns_display_info_for_name (Lisp_Object); /* ========================================================================== @@ -1137,29 +1135,8 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) { -#if defined GLYPH_DEBUG && defined ENABLE_CHECKING - struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); -#endif - - /* If the frame's image cache refcount is still the same as our - private shadow variable, it means we are unwinding a frame - for which we didn't yet call init_frame_faces, where the - refcount is incremented. Therefore, we increment it here, so - that free_frame_faces, called in ns_free_frame_resources - below, will not mistakenly decrement the counter that was not - incremented yet to account for this new frame. */ - if (FRAME_IMAGE_CACHE (f) != NULL - && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) - FRAME_IMAGE_CACHE (f)->refcount++; - ns_free_frame_resources (f); free_glyphs (f); - -#if defined GLYPH_DEBUG && defined ENABLE_CHECKING - /* Check that reference counts are indeed correct. */ - eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); -#endif - return Qt; } diff --git a/src/pgtkfns.c b/src/pgtkfns.c index bdc6c5836fa..49467988cae 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -38,8 +38,6 @@ along with GNU Emacs. If not, see . */ #include "xsettings.h" #include "atimer.h" -static ptrdiff_t image_cache_refcount; - static int x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color); static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object); @@ -1019,17 +1017,6 @@ unwind_create_frame (Lisp_Object frame) /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) { - /* If the frame's image cache refcount is still the same as our - private shadow variable, it means we are unwinding a frame - for which we didn't yet call init_frame_faces, where the - refcount is incremented. Therefore, we increment it here, so - that free_frame_faces, called in x_free_frame_resources - below, will not mistakenly decrement the counter that was not - incremented yet to account for this new frame. */ - if (FRAME_IMAGE_CACHE (f) != NULL - && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) - FRAME_IMAGE_CACHE (f)->refcount++; - pgtk_free_frame_resources (f); free_glyphs (f); return Qt; @@ -1389,9 +1376,6 @@ This function is an internal primitive--use `make-frame' instead. */ ) register_font_driver (&ftcrhbfont_driver, f); #endif /* HAVE_HARFBUZZ */ - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -2746,9 +2730,6 @@ x_create_tip_frame (struct pgtk_display_info *dpyinfo, Lisp_Object parms, struct register_font_driver (&ftcrhbfont_driver, f); #endif /* HAVE_HARFBUZZ */ - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; - gui_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); diff --git a/src/termhooks.h b/src/termhooks.h index d828c62ce33..d6a9300bac9 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -523,11 +523,6 @@ struct terminal /* The terminal's keyboard object. */ struct kboard *kboard; -#ifdef HAVE_WINDOW_SYSTEM - /* Cache of images. */ - struct image_cache *image_cache; -#endif /* HAVE_WINDOW_SYSTEM */ - /* Device-type dependent data shared amongst all frames on this terminal. */ union display_info { diff --git a/src/w32fns.c b/src/w32fns.c index 5b0e4a895d0..b784a9a563d 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -270,7 +270,6 @@ unsigned int msh_mousewheel = 0; static unsigned menu_free_timer = 0; #ifdef GLYPH_DEBUG -static ptrdiff_t image_cache_refcount; static int dpyinfo_refcount; #endif @@ -5918,17 +5917,6 @@ unwind_create_frame (Lisp_Object frame) { #ifdef GLYPH_DEBUG struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); - - /* If the frame's image cache refcount is still the same as our - private shadow variable, it means we are unwinding a frame - for which we didn't yet call init_frame_faces, where the - refcount is incremented. Therefore, we increment it here, so - that free_frame_faces, called in w32_free_frame_resources - below, will not mistakenly decrement the counter that was not - incremented yet to account for this new frame. */ - if (FRAME_IMAGE_CACHE (f) != NULL - && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) - FRAME_IMAGE_CACHE (f)->refcount++; #endif w32_free_frame_resources (f); @@ -5937,10 +5925,6 @@ unwind_create_frame (Lisp_Object frame) #ifdef GLYPH_DEBUG /* Check that reference counts are indeed correct. */ eassert (dpyinfo->reference_count == dpyinfo_refcount); - eassert ((dpyinfo->terminal->image_cache == NULL - && image_cache_refcount == 0) - || (dpyinfo->terminal->image_cache != NULL - && dpyinfo->terminal->image_cache->refcount == image_cache_refcount)); #endif return Qt; } @@ -6128,8 +6112,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, record_unwind_protect (do_unwind_create_frame, frame); #ifdef GLYPH_DEBUG - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ @@ -7222,8 +7204,6 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms) f->tooltip = true; #ifdef GLYPH_DEBUG - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ FRAME_KBOARD (f) = kb; diff --git a/src/xfaces.c b/src/xfaces.c index e305cc7456f..1e0196a1171 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -634,6 +634,37 @@ x_free_gc (struct frame *f, struct android_gc *gc) Frames and faces ***********************************************************************/ +#ifdef HAVE_WINDOW_SYSTEM + +/* Find an existing image cache registered for a frame on F's display + and with a `scaling_col_width' of F's FRAME_COLUMN_WIDTH, or, in the + absence of an eligible image cache, allocate an image cache with the + same width value. */ + +struct image_cache * +share_image_cache (struct frame *f) +{ + int width = max (10, FRAME_COLUMN_WIDTH (f)); + Lisp_Object tail, frame; + struct image_cache *cache; + + FOR_EACH_FRAME (tail, frame) + { + struct frame *x = XFRAME (frame); + + if (FRAME_TERMINAL (x) == FRAME_TERMINAL (f) + && FRAME_IMAGE_CACHE (x) + && FRAME_IMAGE_CACHE (x)->scaling_col_width == width) + return FRAME_IMAGE_CACHE (x); + } + + cache = make_image_cache (); + cache->scaling_col_width = width; + return cache; +} + +#endif /* HAVE_WINDOW_SYSTEM */ + /* Initialize face cache and basic faces for frame F. */ void @@ -644,14 +675,10 @@ init_frame_faces (struct frame *f) FRAME_FACE_CACHE (f) = make_face_cache (f); #ifdef HAVE_WINDOW_SYSTEM - /* Make the image cache. */ + /* Make or share an image cache. */ if (FRAME_WINDOW_P (f)) { - /* We initialize the image cache when creating the first frame - on a terminal, and not during terminal creation. This way, - `x-open-connection' on a tty won't create an image cache. */ - if (FRAME_IMAGE_CACHE (f) == NULL) - FRAME_IMAGE_CACHE (f) = make_image_cache (); + FRAME_IMAGE_CACHE (f) = share_image_cache (f); ++FRAME_IMAGE_CACHE (f)->refcount; } #endif /* HAVE_WINDOW_SYSTEM */ diff --git a/src/xfns.c b/src/xfns.c index 4fdcf07e8fb..5ba4a78ac9d 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -127,7 +127,6 @@ extern LWLIB_ID widget_id_tick; #define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) -static ptrdiff_t image_cache_refcount; #ifdef GLYPH_DEBUG static int dpyinfo_refcount; #endif @@ -4754,29 +4753,12 @@ unwind_create_frame (Lisp_Object frame) /* If frame is ``official'', nothing to do. */ if (NILP (Fmemq (frame, Vframe_list))) { -#if defined GLYPH_DEBUG && defined ENABLE_CHECKING - struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); -#endif - - /* If the frame's image cache refcount is still the same as our - private shadow variable, it means we are unwinding a frame - for which we didn't yet call init_frame_faces, where the - refcount is incremented. Therefore, we increment it here, so - that free_frame_faces, called in x_free_frame_resources - below, will not mistakenly decrement the counter that was not - incremented yet to account for this new frame. */ - if (FRAME_IMAGE_CACHE (f) != NULL - && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) - FRAME_IMAGE_CACHE (f)->refcount++; - x_free_frame_resources (f); free_glyphs (f); - #if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Check that reference counts are indeed correct. */ eassert (dpyinfo->reference_count == dpyinfo_refcount); - eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); -#endif +#endif /* GLYPH_DEBUG && ENABLE_CHECKING */ return Qt; } @@ -5112,9 +5094,6 @@ This function is an internal primitive--use `make-frame' instead. */) #endif /* HAVE_FREETYPE */ #endif /* not USE_CAIRO */ register_font_driver (&xfont_driver, f); - - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; #ifdef GLYPH_DEBUG dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ @@ -8484,8 +8463,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) #endif /* not USE_CAIRO */ register_font_driver (&xfont_driver, f); - image_cache_refcount = - FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; #ifdef GLYPH_DEBUG dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */