Subject: Re: bug#23403: 25.1.50; cua-mode does not interact with cursor-face and themes well

From: Mauro Aranda <[email-masked]>
Date: Mon, 10 Mar 2025 09:06:14 -0300

"Jeremy T. Braun" <[email-masked]> writes:

 > I've had issues where themes couldn't change cursor colors.  I finally
 > figured out the culprit, cua-mode.  Details on what I noticed and how I
 > found it follow.
 >
 >
 >
 > I believe the "correct" way for themes to interact with the cursor color
 > is to modify the :background attribute of the face named cursor.  See:
 > 
https://www.gnu.org/software/emacs/manual/html_node/emacs/Cursor-Display.html
 >
 > cua-mode defines a variable cua-normal-cursor-color.  By default this is
 > set to one of initial-cursor-color, cursor-color from initial-frame-alis
 > or default-frame-alist, the frame-parameter 'cursor-color, or "red" if
 > those are all not true.
 >
 > When cua-enable-cursor-indications is enabled, cua--update-indications
 > is run as a part of cua--post-command-handler, which is added to
 > post-command-hook.
 >
 > When run, cua-enable-cursor-indications typically calls set-cursor-color
 > to one of the cua-*-cursor-color variables.
 >
 > The result?  Themes can change the cursor-color (via the face or via
 > set-cursor-color, but after they are loaded/run, the post-command-hook
 > eventually runs cua--update-indications, which overwrites the theme's
 > new "normal" cursor color with whatever was previously stored in
 > cua-normal-cursor-color (for "normal" buffers, anyway).
 >
 > I first noticed this because I run emacs in --daemon mode a lot.  When
 > emacs is in --daemon mode, I think that .emacs/init.el is run in the
 > frame/context of the terminal or background emacs process. When my
 > init.el is run, (frame-parameter nil 'cursor-color) returns "white",
 > which cua-normal-cursor-color is set to.  When I switch between the
 > background-mode = dark/light color themes linked below, the cursor
 > always stays white, and it's illegible in the "light" theme.
 > https://github.com/sellout/emacs-color-theme-solarized
 >
 > When I launch emacs without --daemon, my init.el loads the theme first,
 > which sets frame-parameter.cursor-color to #839496, which initializes
 > cua-normal-cursor-color, which is legible in both dark and light modes.

IIUC, the issue here can be reproduced in a couple of ways. Here's one:
emacs -Q
M-x cua-mode
M-x customize-set-variable RET cua-enable-cursor-indications RET y
M-x load-theme RET deeper-blue

Notice that the cursor is black.  Compare with:
emacs -Q
M-x load-theme RET deeper-blue
M-x cua-mode
M-x customize-set-variable RET cua-enable-cursor-indications RET y

Now the cursor is green.  If you want, load any other theme, and see
that the cursor color doesn't change: it stays green.

 > I'm not sure how "best" to fix this.  Options I see:
 > * Change documentation on custom themes, requiring that in addition to
 >   modifying the cursor face, they should also modify cua-*-cursor-color.

Themes have pretty much no choice, since it seems to me that for a good
user experience, they need to make sure all cua-*-cursor-color options
interact well with their settings.

 > * Change cua-mode to be aware that themes may modify the cursor face,
 >   and either update cua-normal-cursor-face to reflect the cursor face's
 >   :background attribute, or maybe have cua--update-indications use
 >   something like:
 >     (or cua-normal-cursor-face (grab the :background attribute of
 >     cursor-face))
 >   And then the user can set/customize cua-normal-cursor-face to nil to
 >   allow the theme to control it.

This idea seems like an improvement.  Allow nil for this option, so that
it CUA understands it as "don't mess with the cursor color".

Opinions?