emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 5fecdbcd81d 01/13: Merge from origin/emacs-29


From: Eli Zaretskii
Subject: master 5fecdbcd81d 01/13: Merge from origin/emacs-29
Date: Sat, 15 Apr 2023 13:06:28 -0400 (EDT)

branch: master
commit 5fecdbcd81db3d4a06277400c458d8ca7dcf7462
Merge: 4c086bf2951 5ef7ff05736
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    Merge from origin/emacs-29
    
    5ef7ff05736 ; Start a new ChangeLog.4 file.
    11126c6d30a Fix 'C-h k' for "Paste from Kill Menu" in context menus
    74ddfe811f9 ; * doc/misc/calc.texi (Rewrites Tutorial): Fix a typo (b...
    08cda286c3f Improve the documentation of the XDS support
    14d1c00e806 Allow reindentation of images inserted by 'mm-inline-image'
    b63a9eda01c Fix "C-h k" and "C-h c" with Paste from Kill Menu
    b36c21e27dc Change cursor color on NS port when it matches the face b...
    96714c106b7 Improve documentation of image-related commands
    6a2863ca016 Fix handling of sliced images
    5be79fd05a5 ; * etc/NEWS: Announce 'cyrillic-mongolian' IM.
    ca1a0fda98a ; Fix last change.
    ce63462dbda Add cyrillic-mongolian input method
    58801792706 ; Minor addition to the Emacs FAQ
    88847dee125 Jsonrpc: don't bind inhibit-read-only to t so early
    cb8c87a423a Allow active region when IM is used
    
    # Conflicts:
    #       etc/NEWS
---
 ChangeLog.4                 |  38 ++++++++++++++
 doc/emacs/files.texi        |  93 ++++++++++++++++++++++++++++++++++
 doc/lispref/display.texi    |  30 ++++++-----
 doc/lispref/frames.texi     |  88 +++++++++++++++++++++++---------
 doc/misc/calc.texi          |   2 +-
 doc/misc/efaq.texi          |  20 ++++++--
 etc/NEWS.29                 |  37 ++++++++------
 lisp/gnus/mm-view.el        |   2 +-
 lisp/image.el               |  25 +++++----
 lisp/image/image-crop.el    |  59 +++++++++++++++++-----
 lisp/international/quail.el |   3 +-
 lisp/jsonrpc.el             |   8 +--
 lisp/leim/quail/cyrillic.el | 119 +++++++++++++++++++++++++++++++++++++++++++
 lisp/mouse.el               |   3 +-
 lisp/subr.el                |  74 ++++++++++++++-------------
 lisp/x-dnd.el               | 120 +++++++++++++++++++++++++-------------------
 src/macfont.m               |  50 ++++++++++++------
 src/nsterm.m                |  20 +++++---
 18 files changed, 594 insertions(+), 197 deletions(-)

diff --git a/ChangeLog.4 b/ChangeLog.4
new file mode 100644
index 00000000000..0792df934ff
--- /dev/null
+++ b/ChangeLog.4
@@ -0,0 +1,38 @@
+2022-04-04  Eli Zaretskii  <eliz@gnu.org>
+
+       * Version 28.1 released.
+
+2022-04-03  Eli Zaretskii  <eliz@gnu.org>
+
+       Bump Emacs version to 28.1
+
+       * README:
+       * configure.ac:
+       * nt/README.W32:
+       * msdos/sed2v2.inp: Bump Emacs version to 28.1
+
+This file records repository revisions from
+commit f2ae39829812098d8269eafbc0fcb98959ee5bb7 (exclusive) to
+commit de7901abbc21114721057c907cc52455e228f826 (inclusive).
+See ChangeLog.3 for earlier changes.
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+
+  Copyright (C) 2022 Free Software Foundation, Inc.
+
+  This file is part of GNU Emacs.
+
+  GNU Emacs is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  GNU Emacs is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index a9ae4696a06..74315a05bbd 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -2289,10 +2289,15 @@ behavior by using the options @code{image-auto-resize} 
and
 @code{image-auto-resize-on-window-resize}.
 
 @findex image-transform-fit-to-window
+@kindex s w (Image mode)
 @findex image-transform-set-percent
+@kindex s p (Image mode)
 @findex image-transform-set-scale
+@kindex s s (Image mode)
 @findex image-transform-reset-to-initial
+@kindex s 0 (Image mode)
 @findex image-transform-reset-to-original
+@kindex s o (Image mode)
 To resize the image manually you can use the command
 @code{image-transform-fit-to-window} bound to @kbd{s w} that fits the
 image to both the window height and width.  To scale the image to a
@@ -2353,6 +2358,94 @@ frames at once.  You can go to a specific frame with 
@kbd{F}
 (@code{image-reverse-speed}) reverses it.  The command @kbd{a 0}
 (@code{image-reset-speed}) resets the speed to the original value.
 
+In addition to the above key bindings, which are specific to Image
+mode, images shown in any Emacs buffer have special key bindings when
+point is at or inside the image:
+
+@table @kbd
+@cindex resize images
+@cindex image resize
+@findex image-increase-size
+@kindex i + (Image mode)
+@item i +
+Increase the image size (@code{image-increase-size}) by 20%.  Prefix
+numeric argument controls the increment; the value of @var{n} means to
+multiply the size by the factor of @w{@code{1 + @var{n} / 10}}, so
+@w{@kbd{C-u 5 i +}} means to increase the size by 50%.
+
+@findex image-decrease-size
+@kindex i - (Image mode)
+@item i -
+Decrease the image size (@code{image-increase-size}) by 20%.  Prefix
+numeric argument controls the decrement; the value of @var{n} means to
+multiply the size by the factor of @w{@code{1 - @var{n} / 10}}, so
+@w{@kbd{C-u 3 i -}} means to decrease the size by 30%.
+
+@cindex rotating images
+@cindex image rotation
+@findex image-rotate
+@kindex i r (Image mode)
+@item i r
+Rotate the image by 90 degrees clockwise (@code{image-rotate}).
+With the prefix argument, rotate by 90 degrees counter-clockwise instead.
+Note that this command is not available for sliced images.
+
+@findex image-flip-horizontally
+@kindex i h (Image mode)
+@item i h
+Flip the image horizontally (@code{image-flip-horizontally}).  This
+presents the image as if reflected in a vertical mirror.
+Note that this command is not available for sliced images.
+
+@findex image-flip-vertically
+@kindex i v (Image mode)
+@item i v
+Flip the image vertically (@code{image-flip-vertically}).  This
+presents the image as if reflected in a horizontal mirror.
+Note that this command is not available for sliced images.
+
+@findex image-save
+@kindex i o (Image mode)
+@item i o
+Save the image to a file (@code{image-save}).  This command prompts
+you for the name of the file to save the image.
+
+@cindex cropping images
+@vindex image-crop-crop-command
+@findex image-crop
+@kindex i c (Image mode)
+@item i c
+Crop the image (@code{image-crop}).  This command is available only if
+your system has an external program installed that can be used for
+cropping and cutting of images; the user option
+@code{image-crop-crop-command} determines what program to use, and
+defaults to the ImageMagick's @command{convert} program.  The command
+displays the image with a rectangular frame superimposed on it, and
+lets you use the mouse to move and resize the frame.  Type @kbd{m} to
+cause mouse movements to move the frame instead of resizing it; type
+@kbd{s} to move a square frame instead.  When you are satisfied with
+the position and size of the cropping frame, type @kbd{@key{RET}} to
+actually crop the part under the frame; or type @kbd{q} to exit
+without cropping.  You can then save the cropped image using @w{@kbd{i
+o}} or @w{@kbd{M-x image-save}}.
+
+@findex image-cut
+@kindex i x (Image mode)
+@vindex image-cut-color
+@vindex image-crop-cut-command
+@item i x
+Cut a rectangle from the image (@code{image-cut}).  This works the
+same as @code{image-crop} (and also requires an external program,
+defined by the variable @code{image-crop-cut-command}, to perform the
+image cut), but instead of cropping the image, it removes the part
+inside the frame and fills that part with the color specified by
+@code{image-cut-color}.  With prefix argument, the command prompts for
+the color to use.
+@end table
+
+The size and rotation commands are ``repeating'', which means that you
+can continue adjusting the image without using the @kbd{i} prefix.
+
 @cindex ImageMagick support
 @vindex imagemagick-enabled-types
 @vindex imagemagick-types-inhibit
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 85fac4b30a6..8184021d998 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -6876,7 +6876,7 @@ This function puts image @var{image} in front of 
@var{pos} in the
 current buffer.  The argument @var{pos} should be an integer or a
 marker.  It specifies the buffer position where the image should appear.
 The argument @var{string} specifies the text that should hold the image
-as an alternative to the default.
+as an alternative to the default @samp{x}.
 
 The argument @var{image} must be an image descriptor, perhaps returned
 by @code{create-image} or stored by @code{defimage}.
@@ -6889,7 +6889,7 @@ buffer's text.
 
 Internally, this function creates an overlay, and gives it a
 @code{before-string} property containing text that has a @code{display}
-property whose value is the image.  (Whew!)
+property whose value is the image.  (Whew! that was a mouthful@dots{})
 @end defun
 
 @defun remove-images start end &optional buffer
@@ -6936,41 +6936,47 @@ This function returns @code{t} if point is on an image, 
and @code{nil}
 otherwise.
 @end defun
 
+@cindex operations on images
 Images inserted with the insertion functions above also get a local
 keymap installed in the text properties (or overlays) that span the
 displayed image.  This keymap defines the following commands:
 
 @table @kbd
+@findex image-increase-size
 @item i +
-Increase the image size (@code{image-increase-size}).  A prefix value
-of @samp{4} means to increase the size by 40%.  The default is 20%.
+Increase the image size (@code{image-increase-size})
 
+@findex image-decrease-size
 @item i -
-Decrease the image size (@code{image-increase-size}).  A prefix value
-of @samp{4} means to decrease the size by 40%.  The default is 20%.
+Decrease the image size (@code{image-decrease-size}).
 
+@findex image-rotate
 @item i r
-Rotate the image by 90 degrees clockwise (@code{image-rotate}).
-A prefix means to rotate by 90 degrees counter-clockwise instead.
+Rotate the image (@code{image-rotate}).
 
+@findex image-flip-horizontally
 @item i h
 Flip the image horizontally (@code{image-flip-horizontally}).
 
+@findex image-flip-vertically
 @item i v
 Flip the image vertically (@code{image-flip-vertically}).
 
+@findex image-save
 @item i o
 Save the image to a file (@code{image-save}).
 
+@findex image-crop
 @item i c
-Crop the image interactively (@code{image-crop}).
+Interactively crop the image (@code{image-crop}).
 
+@findex image-cut
 @item i x
-Cut a rectangle from the image interactively (@code{image-cut}).
+Interactively cut a rectangle from the image (@code{image-cut}).
 @end table
 
-The size and rotation commands are ``repeating'', which means that you
-can continue adjusting the image without using the @kbd{i} prefix.
+@xref{Image Mode,,, emacs, The GNU Emacs Manual}, for more details
+about these image-specific key bindings.
 
 @node Multi-Frame Images
 @subsection Multi-Frame Images
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 7cae94d2627..c78ab1c34ba 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -4112,7 +4112,7 @@ has the same meaning as the @var{action} argument to
   Emacs implements receiving text and URLs individually for each
 window system, and does not by default support receiving other kinds
 of data as drops.  To support receiving other kinds of data, use the
-X-specific interface described below:
+X-specific interface described below.
 
 @vindex x-dnd-test-function
 @vindex x-dnd-known-types
@@ -4141,29 +4141,71 @@ depending on the specific drag-and-drop protocol being 
used.  For
 example, the data type used for plain text may be either
 @code{"STRING"} or @code{"text/plain"}.
 
+@cindex XDS
+@cindex direct save protocol
 @vindex x-dnd-direct-save-function
-@c FIXME: This description is overly-complicated and confusing.  In
-@c particular, the two calls to the function basically sound
-@c identical, so it is unclear how should the function distinguish
-@c between the first and the second one.  The description of who asks
-@c whom to do what is also very hard to understand.  Needs rewording,
-@c and needs shorter sentences.  Perhaps examples could help.
-  However, @code{x-dnd-types-alist} does not handle a special kind of
-drop sent by a program that wants Emacs to tell it where to save a
-file in a specific location determined by the user.  These drops are
-instead handled by a function that is the value of the variable
-@code{x-dnd-direct-save-function}.  This function should accept two arguments.
-If the first argument is non-@code{nil}, then the second argument is a
-file name to save (with leading directories) that the other
-program recommends, and the
-function should return the full file name under which it should be
-saved.  After the function completes, Emacs will ask the other program
-to save the file under the name that was returned, and if the file was
-successfully saved, call the function again with the first argument
-set to a non-@code{nil} value and the second argument set to the file
-name that was returned.  The function should then perform whatever
-action is appropriate (i.e., opening the file or refreshing a
-directory listing.)
+  When Emacs runs on X window system, it supports the X Direct Save
+(@acronym{XDS}) protocol, which allows users to save a file by
+dragging and dropping it onto an Emacs window, such as a Dired window.
+To comply with the unique requirements of @acronym{XDS}, these
+drag-and-drop requests are processed specially: instead of being
+handled according to @code{x-dnd-types-alist}, they are handled by the
+@dfn{direct-save function} that is the value of the variable
+@code{x-dnd-direct-save-function}.  The value should be a function of
+two arguments, @var{need-name} and @var{filename}.  The @acronym{XDS}
+protocol uses a two-step procedure for dragging files:
+
+@enumerate 1
+@item
+The application from which the file is dragged asks Emacs to provide
+the full file name under which to save the file.  For this purpose,
+the direct-save function is called with its first argument
+@var{need-name} non-@code{nil}, and the second argument @var{filename}
+set to the basename of the file to be saved.  It should return the
+fully-expanded absolute file name under which to save the file.  For
+example, if a file is dragged to a Dired window, the natural directory
+for the file is the directory of the file shown at location of the
+drop.  If saving the file is not possible for some reason, the
+function should return @code{nil}, which will cancel the drag-and-drop
+operation.
+
+@item
+The application from which the file is dragged saves the file under
+the name returned by the first call to the direct-save function.  If
+it succeeds in saving the file, the direct-save function is called
+again, this time with the first argument @var{need-name} set to
+@code{nil} and the second argument @var{filename} set to the full
+absolute name of the saved file.  The function is then expected to do
+whatever is needed given the fact that file was saved.  For example,
+Dired should update the directory on display by showing the new file
+there.
+@end enumerate
+
+The default value of @code{x-dnd-direct-save-function} is
+@code{x-dnd-save-direct}.
+
+@defun x-dnd-save-direct need-name filename
+When called with the @var{need-name} argument non-@code{nil}, this
+function prompts the user for the absolute file name under which it
+should be saved.  If the specified file already exists, it
+additionally asks the user whether to overwrite it, and returns the
+absolute file name only if the user confirms the overwriting.
+
+When called with the @var{need-name} argument @code{nil}, it reverts
+the Dired listing if the current buffer is in Dired mode or one of its
+descendants, and otherwise visits the file by calling @code{find-file}
+(@pxref{Visiting Functions}).
+@end defun
+
+@defun x-dnd-save-direct-immediately need-name filename
+This function works like @code{x-dnd-save-direct}, but when called
+with its @var{need-name} argument non-@code{nil}, it doesn't prompt
+the user for the full name of the file to be saved; instead, it
+returns its argument @var{filename} expanded against the current
+buffer's default directory (@pxref{File Name Expansion}).  (It still
+asks for confirmation if a file by that name already exists in the
+default directory.)
+@end defun
 
 @cindex initiating drag-and-drop
   On capable window systems, Emacs also supports dragging contents
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 044c018080c..aacc0d0b0ec 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -5394,7 +5394,7 @@ a variable containing a vector of rules.
 1:  [merge, secsqr]          1:  [a/x + b/x := (a + b)/x, ... ]
     .                                 .
 
-    ' [merge,sinsqr] @key{RET}          =
+    ' [merge,secsqr] @key{RET}          =
 
 @end group
 @end smallexample
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 4a8c863230f..0a0c375d273 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -3133,13 +3133,23 @@ example, you can put the following in your init file:
 
 To avoid the slightly distracting visual effect of Emacs starting with
 its default frame size and then growing to fullscreen, you can add an
-@samp{Emacs.Geometry} entry to the Windows registry settings.
-@xref{X Resources,,, emacs, The GNU Emacs Manual}.
-
-To compute the correct values for width and height, first maximize the
-Emacs frame and then evaluate @code{(frame-height)} and
+@samp{Emacs.Geometry} entry to the Windows Registry settings.  @xref{X
+Resources,,, emacs, The GNU Emacs Manual}.  To compute the correct
+values for width and height you use in the Registry settings, first
+maximize the Emacs frame and then evaluate @code{(frame-height)} and
 @code{(frame-width)} with @kbd{M-:}.
 
+Alternatively, you can avoid the visual effect of Emacs changing its
+frame size entirely in your init file (i.e., without using the
+Registry), like this:
+
+@lisp
+(setq frame-resize-pixelwise t)
+(set-frame-position nil 0 0)
+(set-frame-size nil (display-pixel-width) (display-pixel-height) t)
+@end lisp
+
+
 @node Emacs in a Linux console
 @section How can I alleviate the limitations of the Linux console?
 @cindex Console, Linux console, TTY, fbterm
diff --git a/etc/NEWS.29 b/etc/NEWS.29
index dc4eb64a63a..84dbb94a71a 100644
--- a/etc/NEWS.29
+++ b/etc/NEWS.29
@@ -222,9 +222,9 @@ In previous Emacs versions, images have had the '+', '-' 
and 'r' keys
 bound when point is over an image.  In Emacs 29.1, additional commands
 were added, and this made it more likely that users would trigger the
 image commands by mistake.  To avoid this, all image commands have
-moved to the 'i' keymap, so '+' is now 'i +', '-' is now 'i -', and
-'r' is now 'i r'.  In addition, these commands are now repeating, so
-you can rotate an image twice by saying 'i r r', for instance.
+moved to the 'i' prefix keymap, so '+' is now 'i +', '-' is now 'i -',
+and 'r' is now 'i r'.  In addition, these commands are now repeating,
+so, for example, you can rotate an image twice by typing 'i r r'.
 
 +++
 ** Emacs now picks the correct coding-system for X input methods.
@@ -1577,6 +1577,11 @@ This input method is based on the russian-computer input 
method, and
 is intended for typing in the Chuvash language written in the Cyrillic
 script.
 
+---
+*** New input method 'cyrillic-mongolian'.
+This input method is for typing in the Mongolian language using the
+Cyrillic script.
+
 
 * Changes in Specialized Modes and Packages in Emacs 29.1
 
@@ -2623,11 +2628,6 @@ This controls whether or not to show a message when 
opening certain
 image formats saying how to edit it as text.  The default is to show
 this message for SVG and XPM.
 
-+++
-*** New commands: 'image-flip-horizontally' and 'image-flip-vertically'.
-These commands horizontally and vertically flip the image under point,
-and are bound to 'i h' and 'i v', respectively.
-
 +++
 *** New command 'image-transform-set-percent'.
 It allows setting the image size to a percentage of its original size,
@@ -2643,6 +2643,19 @@ The old name was confusing, and is now an obsolete 
function alias.
 
 ** Images
 
++++
+** New commands 'image-crop' and 'image-cut'.
+These commands allow interactively cropping/cutting the image at
+point.  The commands are bound to keys 'i c' and 'i x' (respectively)
+in the local keymap over images.  They rely on external programs, by
+default "convert" from ImageMagick, to do the actual cropping/eliding
+of the image file.
+
++++
+*** New commands: 'image-flip-horizontally' and 'image-flip-vertically'.
+These commands horizontally and vertically flip the image under point,
+and are bound to 'i h' and 'i v', respectively.
+
 +++
 *** Users can now add special image conversion functions.
 This is done via 'image-converter-add-handler'.
@@ -3238,14 +3251,6 @@ macro, which allows you to isolate package configuration 
in your init
 file in a way that is declarative, tidy, and performance-oriented.
 See the new Info manual "(use-package) Top" for more.
 
-+++
-** New commands 'image-crop' and 'image-cut'.
-These commands allow interactively cropping/cutting the image at
-point.  The commands are bound to keys 'i c' and 'i x' (respectively)
-in the local keymap over images.  They rely on external programs, by
-default "convert" from ImageMagick, to do the actual cropping/eliding
-of the image file.
-
 ---
 ** New package 'wallpaper'.
 This package provides the command 'wallpaper-set', which sets the
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index 8dfb0deb418..2c407353559 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -98,7 +98,7 @@ This is only used if `mm-inline-large-images' is set to
                    (truncate (* mm-inline-large-images-proportion
                                 (- (nth 3 edges) (nth 1 edges)))))))
          image))
-     " ")
+     "x")
     (insert "\n")
     (mm-handle-set-undisplayer
      handle
diff --git a/lisp/image.el b/lisp/image.el
index 838cc0f8942..a32ff1a35bb 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -172,22 +172,27 @@ or \"ffmpeg\") is installed."
 
 (define-error 'unknown-image-type "Unknown image type")
 
-(defvar-keymap image-map
-  :doc "Map put into text properties on images."
+(defvar-keymap image-slice-map
+  :doc "Map put into text properties on sliced images."
   "i" (define-keymap
         "-" #'image-decrease-size
         "+" #'image-increase-size
-        "r" #'image-rotate
         "o" #'image-save
         "c" #'image-crop
-        "x" #'image-cut
-        "h" #'image-flip-horizontally
-        "v" #'image-flip-vertically)
+        "x" #'image-cut)
   "C-<wheel-down>" #'image-mouse-decrease-size
   "C-<mouse-5>"    #'image-mouse-decrease-size
   "C-<wheel-up>"   #'image-mouse-increase-size
   "C-<mouse-4>"    #'image-mouse-increase-size)
 
+(defvar-keymap image-map
+  :doc "Map put into text properties on images."
+  :parent image-slice-map
+  "i" (define-keymap
+        "r" #'image-rotate
+        "h" #'image-flip-horizontally
+        "v" #'image-flip-vertically))
+
 (defun image-load-path-for-library (library image &optional path no-error)
   "Return a suitable search path for images used by LIBRARY.
 
@@ -665,7 +670,9 @@ is non-nil, this is inhibited."
                                      image)
                                    rear-nonsticky t
                                   inhibit-isearch ,inhibit-isearch
-                                   keymap ,image-map))))
+                                   keymap ,(if slice
+                                               image-slice-map
+                                             image-map)))))
 
 
 ;;;###autoload
@@ -701,8 +708,8 @@ The image is automatically split into ROWS x COLS slices."
          (insert string)
          (add-text-properties start (point)
                               `(display ,(list (list 'slice x y dx dy) image)
-                                        rear-nonsticky (display)
-                                         keymap ,image-map))
+                                        rear-nonsticky (display keymap)
+                                         keymap ,image-slice-map))
          (setq x (+ x dx))))
       (setq x 0.0
            y (+ y dy))
diff --git a/lisp/image/image-crop.el b/lisp/image/image-crop.el
index be6e22bc606..9ef848c5bc8 100644
--- a/lisp/image/image-crop.el
+++ b/lisp/image/image-crop.el
@@ -35,6 +35,7 @@
 (declare-function image-property "image.el" (image property))
 (declare-function image-size "image.c" (spec &optional pixels frame))
 (declare-function imagep "image.c" (spec))
+(declare-function image--get-image "image.el" (&optional position))
 
 (defgroup image-crop ()
   "Image cropping."
@@ -113,18 +114,36 @@ and the cropped image data.")
 (defun image-cut (&optional color)
   "Cut a rectangle from the image under point, filling it with COLOR.
 COLOR defaults to the value of `image-cut-color'.
-Interactively, with prefix argument, prompt for COLOR to use."
-  (interactive (list (and current-prefix-arg (read-color "Use color: "))))
+Interactively, with prefix argument, prompt for COLOR to use.
+
+This command presents the image with a rectangular area superimposed
+on it, and allows moving and resizing the area to define which
+part of it to cut.
+
+While moving/resizing the cutting area, the following key bindings
+are available:
+
+`q':   Exit without changing anything.
+`RET': Crop/cut the image.
+`m':   Make mouse movements move the rectangle instead of altering the
+       rectangle shape.
+`s':   Same as `m', but make the rectangle into a square first.
+
+After cutting the image, you can save it by `M-x image-save' or
+\\<image-map>\\[image-save] when point is over the image."
+  (interactive (list (and current-prefix-arg
+                          (read-color "Color to use for filling: "))))
   (image-crop (if (zerop (length color)) image-cut-color color)))
 
 ;;;###autoload
 (defun image-crop (&optional cut)
   "Crop the image under point.
-If CUT is non-nil, remove a rectangle from the image instead of
-cropping the image.  In that case CUT should be the name of a
-color to fill the rectangle.
+This command presents the image with a rectangular area superimposed
+on it, and allows moving and resizing the area to define which
+part of it to crop.
 
-While cropping the image, the following key bindings are available:
+While moving/resizing the cropping area, the following key bindings
+are available:
 
 `q':   Exit without changing anything.
 `RET': Crop/cut the image.
@@ -132,15 +151,29 @@ While cropping the image, the following key bindings are 
available:
        rectangle shape.
 `s':   Same as `m', but make the rectangle into a square first.
 
-After cropping an image, you can save it by `M-x image-save' or
-\\<image-map>\\[image-save] when point is over the image."
+After cropping the image, you can save it by `M-x image-save' or
+\\<image-map>\\[image-save] when point is over the image.
+
+When called from Lisp, if CUT is non-nil, remove a rectangle from
+the image instead of cropping the image.  In that case, CUT should
+be the name of a color to fill the rectangle."
   (interactive)
   (unless (image-type-available-p 'svg)
-    (error "SVG support is needed to crop images"))
-  (unless (executable-find (car image-crop-crop-command))
-    (error "Couldn't find %s command to crop the image"
-           (car image-crop-crop-command)))
-  (let ((image (get-text-property (point) 'display)))
+    (error "SVG support is needed to crop and cut images"))
+  (let* ((crop-cmd (car image-crop-crop-command))
+         (found (executable-find crop-cmd)))
+    (unless found
+      (error "Couldn't find `%s' command to crop/cut the image" crop-cmd))
+    (if (and (memq system-type '(windows-nt ms-dos))
+             ;; MS-Windows has an incompatible convert.exe, used to
+             ;; convert filesystems...
+             (string-equal crop-cmd "convert")
+             (= 0 (string-search "Invalid drive specification."
+                                 (shell-command-to-string
+                                  (format "%s %s" crop-cmd null-device)))))
+        (error "The program `%s' is not an image conversion program"
+               found)))
+  (let ((image (image--get-image)))
     (unless (imagep image)
       (user-error "No image under point"))
     (when (overlays-at (point))
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 2ffe3392335..317ea8495de 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -1995,7 +1995,8 @@ Remaining args are for FUNC."
 (defun quail-minibuffer-message (string)
   (message nil)
   (let ((point-max (point-max))
-       (inhibit-quit t))
+       (inhibit-quit t)
+        (deactivate-mark nil))
     (save-excursion
       (goto-char point-max)
       (insert string))
diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el
index 3965d38bc3e..ccf0f966574 100644
--- a/lisp/jsonrpc.el
+++ b/lisp/jsonrpc.el
@@ -574,15 +574,14 @@ With optional CLEANUP, kill any associated buffers."
     (cl-return-from jsonrpc--process-filter))
   (when (buffer-live-p (process-buffer proc))
     (with-current-buffer (process-buffer proc)
-      (let* ((inhibit-read-only t)
-             (jsonrpc--in-process-filter t)
+      (let* ((jsonrpc--in-process-filter t)
              (connection (process-get proc 'jsonrpc-connection))
              (expected-bytes (jsonrpc--expected-bytes connection)))
         ;; Insert the text, advancing the process marker.
         ;;
         (save-excursion
           (goto-char (process-mark proc))
-          (insert string)
+          (let ((inhibit-read-only t)) (insert string))
           (set-marker (process-mark proc) (point)))
         ;; Loop (more than one message might have arrived)
         ;;
@@ -631,7 +630,8 @@ With optional CLEANUP, kill any associated buffers."
                                     (jsonrpc-connection-receive connection
                                                                 
json-message)))))
                           (goto-char message-end)
-                          (delete-region (point-min) (point))
+                          (let ((inhibit-read-only t))
+                            (delete-region (point-min) (point)))
                           (setq expected-bytes nil))))
                      (t
                       ;; Message is still incomplete
diff --git a/lisp/leim/quail/cyrillic.el b/lisp/leim/quail/cyrillic.el
index ba0b9c9ca12..d0874124fc7 100644
--- a/lisp/leim/quail/cyrillic.el
+++ b/lisp/leim/quail/cyrillic.el
@@ -1844,6 +1844,125 @@ Doubling the postfix separates the letter and postfix
        ("E**" ["У*"])
        ("e**" ["у*"]))
 
+
+;; Mongolian layout: Mongolian alphabet has 2 letters: Ө Ү,
+;; and the layout is quite different from other cyrillic layouts.
+;; Written by Garid Zorigoo.
+(quail-define-package
+ "cyrillic-mongolian" "Mongolian"  "MN-" t
+ "Input method for cyrillic Mongolian"
+ nil t nil nil nil nil nil nil nil nil t)
+
+;;  №  -  "  ₮  :    .  _  ,  %  ?  е  щ
+;;   Ф  Ц  У  Ж  Э    Н  Г  Ш  Ү  З  К  Ъ
+;;    Й  Ы  Б  Ө  А    Х  Р  О  Л  Д  П
+;;     Я  Ч  Ё  С  М    И  Т  Ь  В  Ю
+
+
+(quail-define-rules
+ ;; (lowercase 1st row)
+ ("q" ?ф)
+ ("w" ?ц)
+ ("e" ?у)
+ ("r" ?ж)
+ ("t" ?э)
+ ("y" ?н)
+ ("u" ?г)
+ ("i" ?ш)
+ ("o" ?ү)
+ ("p" ?з)
+ ("[" ?к)
+ ("]" ?ъ)
+ ;; (lowercase 2nd row)
+ ("a" ?й)
+ ("s" ?ы)
+ ("d" ?б)
+ ("f" ?ө)
+ ("g" ?а)
+ ("h" ?х)
+ ("j" ?р)
+ ("k" ?о)
+ ("l" ?л)
+ (";" ?д)
+ ("'" ?п)
+ ;; (lowercase 3rd row)
+ ("z" ?я)
+ ("x" ?ч)
+ ("c" ?ё)
+ ("v" ?с)
+ ("b" ?м)
+ ("n" ?и)
+ ("m" ?т)
+ ("," ?ь)
+ ("." ?в)
+ ("/" ?ю)
+
+
+ ;; (uppercase 1st row)
+ ("Q" ?Ф)
+ ("W" ?Ц)
+ ("E" ?У)
+ ("R" ?Ж)
+ ("T" ?Э)
+ ("Y" ?Н)
+ ("U" ?Г)
+ ("I" ?Ш)
+ ("O" ?Ү)
+ ("P" ?З)
+ ("{" ?К)
+ ("}" ?Ъ)
+ ;; (uppercase 2nd row)
+ ("A" ?Й)
+ ("S" ?Ы)
+ ("D" ?Б)
+ ("F" ?Ө)
+ ("G" ?А)
+ ("H" ?Х)
+ ("J" ?Р)
+ ("K" ?О)
+ ("L" ?Л)
+ (":" ?Д)
+ ("\"" ?П)
+ ;; (uppercase 3rd row)
+ ("Z" ?Я)
+ ("X" ?Ч)
+ ("C" ?Ё)
+ ("V" ?С)
+ ("B" ?М)
+ ("N" ?И)
+ ("M" ?Т)
+ ("<" ?Ь)
+ (">" ?В)
+ ("?" ?Ю)
+
+
+ ;;  (number row without shift)
+ ("1" ?№)
+ ("2" ?-)
+ ("3" ?\")
+ ("4" ?₮)
+ ("5" ?:)
+ ("6" ?.)
+ ("7" ?_)
+ ("8" ?,)
+ ("9" ?%)
+ ("0" ??)
+ ("-" ?е)
+ ("=" ?щ)
+ ;;  (number row with shift)
+ ("!" ?1)
+ ("@" ?2)
+ ("#" ?3)
+ ("$" ?4)
+ ("%" ?5)
+ ("^" ?6)
+ ("&" ?7)
+ ("*" ?8)
+ ("(" ?9)
+ (")" ?0)
+ ("_" ?Е)
+ ("+" ?Щ))
+
 ;; Local Variables:
 ;; coding: utf-8
 ;; End:
diff --git a/lisp/mouse.el b/lisp/mouse.el
index 9c1a72bb368..3c30361ad7d 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -533,7 +533,8 @@ Some context functions add menu items below the separator."
           (i 0))
       (dolist (item (reverse yank-menu))
         (when (consp item)
-          (define-key submenu (vector (setq i (1+ i)))
+          (define-key submenu
+            (vector (intern (format "kill-%d" (setq i (1+ i)))))
             `(menu-item ,(cadr item)
                         ,(lambda () (interactive)
                            (mouse-yank-from-menu click (car item)))))))
diff --git a/lisp/subr.el b/lisp/subr.el
index f90026534e8..a7a67c570b6 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1555,31 +1555,32 @@ EVENT may be an event or an event type.  If EVENT is a 
symbol
 that has never been used in an event that has been read as input
 in the current Emacs session, then this function may fail to include
 the `click' modifier."
-  (let ((type event))
-    (if (listp type)
-       (setq type (car type)))
-    (if (symbolp type)
-        ;; Don't read event-symbol-elements directly since we're not
-        ;; sure the symbol has already been parsed.
-       (cdr (internal-event-symbol-parse-modifiers type))
-      (let ((list nil)
-           (char (logand type (lognot (logior ?\M-\0 ?\C-\0 ?\S-\0
-                                              ?\H-\0 ?\s-\0 ?\A-\0)))))
-       (if (not (zerop (logand type ?\M-\0)))
-           (push 'meta list))
-       (if (or (not (zerop (logand type ?\C-\0)))
-               (< char 32))
-           (push 'control list))
-       (if (or (not (zerop (logand type ?\S-\0)))
-               (/= char (downcase char)))
-           (push 'shift list))
-       (or (zerop (logand type ?\H-\0))
-           (push 'hyper list))
-       (or (zerop (logand type ?\s-\0))
-           (push 'super list))
-       (or (zerop (logand type ?\A-\0))
-           (push 'alt list))
-       list))))
+  (unless (stringp event)
+    (let ((type event))
+      (if (listp type)
+         (setq type (car type)))
+      (if (symbolp type)
+          ;; Don't read event-symbol-elements directly since we're not
+          ;; sure the symbol has already been parsed.
+         (cdr (internal-event-symbol-parse-modifiers type))
+        (let ((list nil)
+             (char (logand type (lognot (logior ?\M-\0 ?\C-\0 ?\S-\0
+                                                ?\H-\0 ?\s-\0 ?\A-\0)))))
+         (if (not (zerop (logand type ?\M-\0)))
+             (push 'meta list))
+         (if (or (not (zerop (logand type ?\C-\0)))
+                 (< char 32))
+             (push 'control list))
+         (if (or (not (zerop (logand type ?\S-\0)))
+                 (/= char (downcase char)))
+             (push 'shift list))
+         (or (zerop (logand type ?\H-\0))
+             (push 'hyper list))
+         (or (zerop (logand type ?\s-\0))
+             (push 'super list))
+         (or (zerop (logand type ?\A-\0))
+             (push 'alt list))
+         list)))))
 
 (defun event-basic-type (event)
   "Return the basic type of the given event (all modifiers removed).
@@ -1587,17 +1588,18 @@ The value is a printing character (not upper case) or a 
symbol.
 EVENT may be an event or an event type.  If EVENT is a symbol
 that has never been used in an event that has been read as input
 in the current Emacs session, then this function may return nil."
-  (if (consp event)
-      (setq event (car event)))
-  (if (symbolp event)
-      (car (get event 'event-symbol-elements))
-    (let* ((base (logand event (1- ?\A-\0)))
-          (uncontrolled (if (< base 32) (logior base 64) base)))
-      ;; There are some numbers that are invalid characters and
-      ;; cause `downcase' to get an error.
-      (condition-case ()
-         (downcase uncontrolled)
-       (error uncontrolled)))))
+  (unless (stringp event)
+    (if (consp event)
+        (setq event (car event)))
+    (if (symbolp event)
+        (car (get event 'event-symbol-elements))
+      (let* ((base (logand event (1- ?\A-\0)))
+            (uncontrolled (if (< base 32) (logior base 64) base)))
+        ;; There are some numbers that are invalid characters and
+        ;; cause `downcase' to get an error.
+        (condition-case ()
+           (downcase uncontrolled)
+         (error uncontrolled))))))
 
 (defsubst mouse-movement-p (object)
   "Return non-nil if OBJECT is a mouse movement event."
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
index b213b155249..9286a1858cf 100644
--- a/lisp/x-dnd.el
+++ b/lisp/x-dnd.el
@@ -34,20 +34,20 @@
 
 ;;; Customizable variables
 (defcustom x-dnd-test-function #'x-dnd-default-test-function
-  "The function drag and drop uses to determine if to accept or reject a drop.
-The function takes three arguments, WINDOW, ACTION and TYPES.
-WINDOW is where the mouse is when the function is called.  WINDOW
-may be a frame if the mouse isn't over a real window (i.e. menu
-bar, tool bar or scroll bar).  ACTION is the suggested action
-from the drag and drop source, one of the symbols move, copy,
-link or ask.  TYPES is a vector of available types for the drop.
-
-Each element of TYPE should either be a string (containing the
+  "Function to be used by drag-and-drop to determine whether to accept a drop.
+The function takes three arguments: WINDOW, ACTION, and TYPES.
+WINDOW is where the window under the mouse is when the function is called.
+WINDOW may be a frame if the mouse isn't over a real window (e.g., menu
+bar, tool bar, scroll bar, etc.).
+ACTION is the suggested action from the drag and drop source, one of the
+symbols `move', `copy', `link' or `ask'.
+TYPES is a vector of available types for the drop.
+Each element of TYPES should either be a string (containing the
 name of the type's X atom), or a symbol, whose name will be used.
 
 The function shall return nil to reject the drop or a cons with
-two values, the wanted action as car and the wanted type as cdr.
-The wanted action can be copy, move, link, ask or private.
+two values, the wanted action as `car' and the wanted type as `cdr'.
+The wanted action can be `copy', `move', `link', `ask' or `private'.
 
 The default value for this variable is `x-dnd-default-test-function'."
   :version "22.1"
@@ -70,14 +70,18 @@ The default value for this variable is 
`x-dnd-default-test-function'."
     (,(purecopy "DndTypeFile") . x-dnd-handle-offix-file)
     (,(purecopy "DndTypeFiles") . x-dnd-handle-offix-files)
     (,(purecopy "DndTypeText") . dnd-insert-text))
-  "Which function to call to handle a drop of that type.
-If the type for the drop is not present, or the function is nil,
-the drop is rejected.  The function takes three arguments, WINDOW, ACTION
-and DATA.  WINDOW is where the drop occurred, ACTION is the action for
-this drop (copy, move, link, private or ask) as determined by a previous
-call to `x-dnd-test-function'.  DATA is the drop data.
-The function shall return the action used (copy, move, link or private)
-if drop is successful, nil if not."
+  "Functions to call to handle drag-and-drop of known types.
+If the type of the drop is not present in the alist, or the
+function corresponding to the type is nil, the drop of that
+type will be rejected.
+
+Each function takes three arguments: WINDOW, ACTION, and DATA.
+WINDOW is the window where the drop occurred.
+ACTION is the action for this drop (`copy', `move', `link', `private'
+or `ask'), as determined by a previous call to `x-dnd-test-function'.
+DATA is the drop data.
+The function shall return the action it used (one of the above,
+excluding `ask') if drop is successful, nil if not."
   :version "22.1"
   :type 'alist
   :group 'x)
@@ -122,22 +126,27 @@ like xterm) for text."
   :group 'x)
 
 (defcustom x-dnd-direct-save-function #'x-dnd-save-direct
-  "Function called when a file is dropped that Emacs must save.
-It is called with two arguments: the first is either nil or t,
-and the second is a string.
-
-If the first argument is t, the second argument is the name the
-dropped file should be saved under.  The function should return a
-complete file name describing where the file should be saved.
-
-It can also return nil, which means to cancel the drop.
-
-If the first argument is nil, the second is the name of the file
-that was dropped."
+  "Function called when a file is dropped via XDS protocol.
+The value should be a function of two arguments that supports
+the X Direct Save (XDS) protocol.  The function will be called
+twice during the protocol execution.
+
+When the function is called with the first argument non-nil,
+it should return an absolute file name whose base name is
+the value of the second argument, a string.  The return value
+is the file name for the dragged file to be saved.  The function
+can also return nil if saving the file should be refused for some
+reason; in that case the drop will be canceled.
+
+When the function is called with the first argument nil, the
+second argument specifies the file name where the file was saved;
+the function should then do whatever is appropriate when such a
+file is saved, like show the file in the Dired buffer or visit
+the file."
   :version "29.1"
-  :type '(choice (const :tag "Prompt for name before saving"
+  :type '(choice (const :tag "Prompt for file name to save"
                         x-dnd-save-direct)
-                 (const :tag "Save and open immediately without prompting"
+                 (const :tag "Save in `default-directory' without prompting"
                         x-dnd-save-direct-immediately)
                  (function :tag "Other function"))
   :group 'x)
@@ -222,14 +231,14 @@ any protocol specific data.")
   (cdr (x-dnd-get-state-cons-for-frame frame-or-window)))
 
 (defun x-dnd-default-test-function (_window _action types)
-  "The default test function for drag and drop.
+  "The default test function for drag-and-drop.
 WINDOW is where the mouse is when this function is called.  It
 may be a frame if the mouse is over the menu bar, scroll bar or
 tool bar.  ACTION is the suggested action from the source, and
 TYPES are the types the drop data can have.  This function only
 accepts drops with types in `x-dnd-known-types'.  It always
 returns the action `private', unless `types' contains a value
-inside `x-dnd-copy-types'."
+inside `x-dnd-copy-types', in which case it may return `copy'."
   (let ((type (x-dnd-choose-type types)))
     (when type (let ((list x-dnd-copy-types))
                  (catch 'out
@@ -1564,17 +1573,24 @@ was taken, or the direct save failed."
       (when (not (equal file-name original-file-name))
         (delete-file file-name)))))
 
-(defun x-dnd-save-direct (need-name name)
-  "Handle dropping a file that should be saved immediately.
-NEED-NAME tells whether or not the file was not yet saved.  NAME
-is either the name of the file, or the name the drop source wants
-us to save under.
+(defun x-dnd-save-direct (need-name filename)
+  "Handle dropping a file FILENAME that should be saved first, asking the user.
+NEED-NAME non-nil means the caller requests the full absolute
+file name of FILENAME under which to save it; FILENAME is just
+the base name in that case.  The function then prompts the user
+for where to save to file and returns the result to the caller.
+
+NEED-NAME nil means the file was saved as FILENAME (which should
+be the full absolute file name in that case).  The function then
+refreshes the Dired display, if the current buffer is in Dired
+mode, or visits the file otherwise.
 
-Prompt the user for a file name, then open it."
+This function is intended to be the value of `x-dnd-direct-save-function',
+which see."
   (if need-name
       (let ((file-name (read-file-name "Write file: "
                                        default-directory
-                                       nil nil name)))
+                                       nil nil filename)))
         (when (file-exists-p file-name)
           (unless (y-or-n-p (format-message
                              "File `%s' exists; overwrite? " file-name))
@@ -1584,18 +1600,18 @@ Prompt the user for a file name, then open it."
     ;; interface can be found.
     (if (derived-mode-p 'dired-mode)
         (revert-buffer)
-      (find-file name))))
+      (find-file filename))))
 
-(defun x-dnd-save-direct-immediately (need-name name)
-  "Save and open a dropped file, like `x-dnd-save-direct'.
-NEED-NAME tells whether or not the file was not yet saved.  NAME
-is either the name of the file, or the name the drop source wants
-us to save under.
+(defun x-dnd-save-direct-immediately (need-name filename)
+  "Handle dropping a file FILENAME that should be saved first.
+Like `x-dnd-save-direct', but do not prompt for the file name;
+instead, return its absolute file name for saving in the current
+directory.
 
-Unlike `x-dnd-save-direct', do not prompt for the name by which
-to save the file.  Simply save it in the current directory."
+This function is intended to be the value of `x-dnd-direct-save-function',
+which see."
   (if need-name
-      (let ((file-name (expand-file-name name)))
+      (let ((file-name (expand-file-name filename)))
         (when (file-exists-p file-name)
           (unless (y-or-n-p (format-message
                              "File `%s' exists; overwrite? " file-name))
@@ -1605,7 +1621,7 @@ to save the file.  Simply save it in the current 
directory."
     ;; interface can be found.
     (if (derived-mode-p 'dired-mode)
         (revert-buffer)
-      (find-file name))))
+      (find-file filename))))
 
 (defun x-dnd-handle-octet-stream-for-drop (save-to)
   "Save the contents of the XDS selection to SAVE-TO.
diff --git a/src/macfont.m b/src/macfont.m
index d0cdbcd08c7..9f9f6f4efaf 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -632,21 +632,35 @@ get_cgcolor_from_nscolor (NSColor *nsColor, struct frame 
*f)
 
 #define CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND(context, face)           \
   do {                                                                  \
-    CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face));       \
-    CGContextSetFillColorWithColor (context, refcol_) ;                 \
-    CGColorRelease (refcol_);                                           \
+    CGColorRef refcol = get_cgcolor (NS_FACE_FOREGROUND (face));        \
+    CGContextSetFillColorWithColor (context, refcol);                   \
+    CGColorRelease (refcol);                                            \
   } while (0)
 #define CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND(context, face)           \
   do {                                                                  \
-    CGColorRef refcol_ = get_cgcolor (NS_FACE_BACKGROUND (face));       \
-    CGContextSetFillColorWithColor (context, refcol_);                  \
-    CGColorRelease (refcol_);                                           \
+    CGColorRef refcol = get_cgcolor (NS_FACE_BACKGROUND (face));        \
+    CGContextSetFillColorWithColor (context, refcol);                   \
+    CGColorRelease (refcol);                                            \
+  } while (0)
+#define CG_SET_FILL_COLOR_WITH_FRAME_CURSOR(context, frame)             \
+  do {                                                                  \
+    CGColorRef refcol                                                   \
+      = get_cgcolor_from_nscolor (FRAME_CURSOR_COLOR (frame), frame);   \
+    CGContextSetFillColorWithColor (context, refcol);                   \
+    CGColorRelease (refcol);                                            \
+  } while (0)
+#define CG_SET_FILL_COLOR_WITH_FRAME_BACKGROUND(context, frame)         \
+  do {                                                                  \
+    CGColorRef refcol                                                   \
+      = get_cgcolor_from_nscolor (FRAME_BACKGROUND_COLOR (frame), frame); \
+    CGContextSetFillColorWithColor (context, refcol);                   \
+    CGColorRelease (refcol);                                            \
   } while (0)
 #define CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND(context, face)         \
   do {                                                                  \
-    CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face));       \
-    CGContextSetStrokeColorWithColor (context, refcol_);                \
-    CGColorRelease (refcol_);                                           \
+    CGColorRef refcol = get_cgcolor (NS_FACE_FOREGROUND (face));        \
+    CGContextSetStrokeColorWithColor (context, refcol);                 \
+    CGColorRelease (refcol);                                            \
   } while (0)
 
 
@@ -2933,9 +2947,12 @@ macfont_draw (struct glyph_string *s, int from, int to, 
int x, int y,
     {
       if (s->hl == DRAW_CURSOR)
         {
-         CGColorRef colorref = get_cgcolor_from_nscolor (FRAME_CURSOR_COLOR 
(f), f);
-         CGContextSetFillColorWithColor (context, colorref);
-         CGColorRelease (colorref);
+          if (face && (NS_FACE_BACKGROUND (face)
+                       == [(NSColor *) FRAME_CURSOR_COLOR (f)
+                                       unsignedLong]))
+            CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face);
+          else
+            CG_SET_FILL_COLOR_WITH_FRAME_CURSOR (context, f);
         }
       else
         CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
@@ -2949,9 +2966,12 @@ macfont_draw (struct glyph_string *s, int from, int to, 
int x, int y,
       CGContextScaleCTM (context, 1, -1);
       if (s->hl == DRAW_CURSOR)
         {
-         CGColorRef colorref = get_cgcolor_from_nscolor 
(FRAME_BACKGROUND_COLOR (f), f);
-         CGContextSetFillColorWithColor (context, colorref);
-         CGColorRelease (colorref);
+          if (face && (NS_FACE_BACKGROUND (face)
+                       == [(NSColor *) FRAME_CURSOR_COLOR (f)
+                                       unsignedLong]))
+            CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
+          else
+            CG_SET_FILL_COLOR_WITH_FRAME_BACKGROUND (context, f);
         }
       else
         CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face);
diff --git a/src/nsterm.m b/src/nsterm.m
index 87bdb44eadc..ecbf80ff72d 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3750,14 +3750,18 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, 
char force_p)
        {
           struct face *face = s->face;
           if (!face->stipple)
-           {
-             if (s->hl != DRAW_CURSOR)
-               [(NS_FACE_BACKGROUND (face) != 0
-                 ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
-                 : FRAME_BACKGROUND_COLOR (s->f)) set];
-             else
-               [FRAME_CURSOR_COLOR (s->f) set];
-           }
+            {
+              if (s->hl != DRAW_CURSOR)
+                [(NS_FACE_BACKGROUND (face) != 0
+                  ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+                  : FRAME_BACKGROUND_COLOR (s->f)) set];
+              else if (face && (NS_FACE_BACKGROUND (face)
+                                == [(NSColor *) FRAME_CURSOR_COLOR (s->f)
+                                                unsignedLong]))
+                [[NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (face)] 
set];
+              else
+                [FRAME_CURSOR_COLOR (s->f) set];
+            }
           else
             {
               struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]