all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#70622: [PATCH] New window parameter 'cursor-type'
@ 2024-04-28  6:27 Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-28  7:22 ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-28  6:27 UTC (permalink / raw)
  To: 70622

[-- Attachment #1: Type: text/plain, Size: 157 bytes --]

Tags: patch

This patch makes it possible to set the cursor type in a specific window,
without affecting other windows that may be showing the same buffer.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-New-window-parameter-cursor-type.patch --]
[-- Type: text/patch, Size: 3675 bytes --]

From 518a6708c6d94f152c9cb9ca7a8c73aeffa4a03a Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH] New window parameter 'cursor-type'

* src/xdisp.c (get_window_cursor_type): Consult new window
parameter 'cursor-type'.
* doc/lispref/windows.texi (Window Parameters): Document it.
* etc/NEWS: Announce it.
---
 doc/lispref/windows.texi |  9 +++++++++
 etc/NEWS                 |  6 ++++++
 src/xdisp.c              | 28 ++++++++++++++++++----------
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..19154692056 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -6691,6 +6691,15 @@ Window Parameters
 window and should be used, with due care, exclusively by those
 applications.  It might be replaced by an improved solution in future
 versions of Emacs.
+
+@item cursor-type
+@vindex cursor-type@r{, a window parameter}
+If this parameter is set to a cons cell, its @sc{car} specifies the
+shape of the cursor in this window, using the same format as the
+buffer-local variable @code{cursor-type}.  @xref{Cursor Parameters}.
+Use this window parameter instead of the @code{cursor-type} variable or
+frame parameter when a buffer is displayed in multiple windows and you
+want to change the cursor for one window without affecting the others.
 @end table
 
 
diff --git a/etc/NEWS b/etc/NEWS
index 9c356e64bde..e08998e4b6f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,12 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New window parameter 'cursor-type'.
+If this parameter is set to a cons cell, its 'car' specifies the shape
+of the window's cursor, using the same format as the buffer-local
+variable 'cursor-type'.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/xdisp.c b/src/xdisp.c
index 85802ec5083..ac2b2d186ff 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33605,7 +33605,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   struct frame *f = XFRAME (w->frame);
   struct buffer *b = XBUFFER (w->contents);
   int cursor_type = DEFAULT_CURSOR;
-  Lisp_Object alt_cursor;
+  Lisp_Object alt_cursor, win_cursor;
   bool non_selected = false;
 
   *active_cursor = true;
@@ -33644,18 +33644,26 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  win_cursor = window_parameter (w, Qcursor_type);
+  if (CONSP (win_cursor))
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      cursor_type = get_specified_cursor_type (XCAR (win_cursor), width);
     }
   else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
+    {
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
+    }
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-28  6:27 bug#70622: [PATCH] New window parameter 'cursor-type' Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-28  7:22 ` Eli Zaretskii
  2024-04-28 15:00   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-04-28  7:22 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: 70622

> Date: Sun, 28 Apr 2024 08:27:53 +0200
> From:  Eshel Yaron via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> 
> This patch makes it possible to set the cursor type in a specific window,
> without affecting other windows that may be showing the same buffer.

Thanks, I have a few comments and questions below.

> --- a/doc/lispref/windows.texi
> +++ b/doc/lispref/windows.texi
> @@ -6691,6 +6691,15 @@ Window Parameters
>  window and should be used, with due care, exclusively by those
>  applications.  It might be replaced by an improved solution in future
>  versions of Emacs.
> +
> +@item cursor-type
> +@vindex cursor-type@r{, a window parameter}
> +If this parameter is set to a cons cell, its @sc{car} specifies the
> +shape of the cursor in this window, using the same format as the
> +buffer-local variable @code{cursor-type}.  @xref{Cursor Parameters}.
> +Use this window parameter instead of the @code{cursor-type} variable or
> +frame parameter when a buffer is displayed in multiple windows and you
> +want to change the cursor for one window without affecting the others.
>  @end table

This doesn't say what happens when the buffer-local variable and the
window parameter don't agree.

Also, the "Cursor Parameters" node should mention this window-specific
parameter, with a cross-reference.

> +*** New window parameter 'cursor-type'.
> +If this parameter is set to a cons cell, its 'car' specifies the shape
> +of the window's cursor, using the same format as the buffer-local
> +variable 'cursor-type'.

Why only cons cells are supported?

> +  win_cursor = window_parameter (w, Qcursor_type);
> +  if (CONSP (win_cursor))
>      {
> -      cursor_type = FRAME_DESIRED_CURSOR (f);
> -      *width = FRAME_CURSOR_WIDTH (f);
> +      cursor_type = get_specified_cursor_type (XCAR (win_cursor), width);
>      }

Same question here.

And I have a question: is this supposed to work for non-selected
windows as well?  The documentation you added says nothing about that,
but I wonder what was the intent?  The reason I ask is that we have two
buffer-local variables, not one, for both selected and non-selected
windows, whereas your patch provides just one window parameter.  How
will it interact with the buffer-local variables in both cases?

Also, what about the cursor in mini-windows?

In addition, what is supposed to happen when this new window-parameter
is changed? is the cursor supposed to be redrawn in the new shape
immediately, i.e. do you expect redisplay to happen right away to
update the relevant window?  If so, I'm not sure the patch ensures
such an update.  In particular, non-selected windows are not
guaranteed to be updated by redisplay cycles, unless redisplay is
told, either directly or indirectly, about the need to do so.  To test
this, bind to a simple key, like F8, a command that changes the
window-parameter, and see if the change takes effect as soon as you
expect.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-28  7:22 ` Eli Zaretskii
@ 2024-04-28 15:00   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-28 15:29     ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-28 15:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 70622

[-- Attachment #1: Type: text/plain, Size: 4504 bytes --]

Hi,

Eli Zaretskii <eliz@gnu.org> writes:

>> Date: Sun, 28 Apr 2024 08:27:53 +0200
>> From:  Eshel Yaron via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>>
>> This patch makes it possible to set the cursor type in a specific window,
>> without affecting other windows that may be showing the same buffer.
>
> Thanks, I have a few comments and questions below.
>

Thanks for reviewing.

>> --- a/doc/lispref/windows.texi
>> +++ b/doc/lispref/windows.texi
>> @@ -6691,6 +6691,15 @@ Window Parameters
>>  window and should be used, with due care, exclusively by those
>>  applications.  It might be replaced by an improved solution in future
>>  versions of Emacs.
>> +
>> +@item cursor-type
>> +@vindex cursor-type@r{, a window parameter}
>> +If this parameter is set to a cons cell, its @sc{car} specifies the
>> +shape of the cursor in this window, using the same format as the
>> +buffer-local variable @code{cursor-type}.  @xref{Cursor Parameters}.
>> +Use this window parameter instead of the @code{cursor-type} variable or
>> +frame parameter when a buffer is displayed in multiple windows and you
>> +want to change the cursor for one window without affecting the others.
>>  @end table
>
> This doesn't say what happens when the buffer-local variable and the
> window parameter don't agree.

Right, I've made this more explicit in the updated patch below.

> Also, the "Cursor Parameters" node should mention this window-specific
> parameter, with a cross-reference.

Done.

>> +*** New window parameter 'cursor-type'.
>> +If this parameter is set to a cons cell, its 'car' specifies the shape
>> +of the window's cursor, using the same format as the buffer-local
>> +variable 'cursor-type'.
>
> Why only cons cells are supported?
>

We need a convenient way to specify both "window parameter not set" and
"window parameter set and says not to show a cursor".  Naturally, we
want to use nil for "window parameter not set", but then nil is what the
variable cursor-type uses for "don't to show a cursor".  So we embed the
space of possible values for the variable in a cons cell to clearly
disambiguate the variable's nil from the window parameter's nil.
Namely, if the window parameter is set to '(nil) that means not to show
a cursor, in contrast with a plain nil which means the window parameter
is unset.

>> +  win_cursor = window_parameter (w, Qcursor_type);
>> +  if (CONSP (win_cursor))
>>      {
>> -      cursor_type = FRAME_DESIRED_CURSOR (f);
>> -      *width = FRAME_CURSOR_WIDTH (f);
>> +      cursor_type = get_specified_cursor_type (XCAR (win_cursor), width);
>>      }
>
> Same question here.
>

See above.

> And I have a question: is this supposed to work for non-selected
> windows as well?  The documentation you added says nothing about that,
> but I wonder what was the intent?

Yes, it's supposed to work for non-selected windows as well.  Do you
think that's worth mentioning explicitly in the documentation?

> The reason I ask is that we have two buffer-local variables, not one,
> for both selected and non-selected windows, whereas your patch
> provides just one window parameter.  How will it interact with the
> buffer-local variables in both cases?

That's a really good point.  WRT cursor-in-non-selected-windows, I think
there are two viable options:

1. Give cursor-in-non-selected-windows precedence over the new window
   parameter, and add another window parameter to override
   cursor-in-non-selected-windows.
2. Give the new window parameter precedence also over
   cursor-in-non-selected-windows.

In the updated patch, I went with option 2, so if you set the
cursor-type window parameter, that overrides any buffer-local variable,
whether or not the window is selected.  I think that's sensible enough,
WDYT?

> Also, what about the cursor in mini-windows?

This applies also to the mini-window.  In the updated patch, I've
extended it to take effect also when the minibuffer is not selected but
cursor-in-echo-area is non-nil.

> In addition, what is supposed to happen when this new window-parameter
> is changed? is the cursor supposed to be redrawn in the new shape
> immediately, i.e. do you expect redisplay to happen right away to
> update the relevant window?

Not necessarily.  In cases where we want to ensure the cursor is redrawn
immediately in a non-selected window, we can use force-window-update
after setting the window parameter.  Should that be mentioned in the
documentation as well?



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v2-0001-New-window-parameter-cursor-type.patch --]
[-- Type: text/x-patch, Size: 5306 bytes --]

From 0838e20f9d23b5be81ab6ff7460d0dc0d519754b Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH v2] New window parameter 'cursor-type'

* src/xdisp.c (get_window_cursor_type): Consult new window
parameter 'cursor-type'.
* doc/lispref/windows.texi (Window Parameters): Document it.
* doc/lispref/frames.texi (Cursor Parameters): Mention it.
* etc/NEWS: Announce it.  (Bug#70622)
---
 doc/lispref/frames.texi  |  5 +++--
 doc/lispref/windows.texi | 12 ++++++++++++
 etc/NEWS                 |  6 ++++++
 src/xdisp.c              | 37 +++++++++++++++++++++++++------------
 4 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index cae93acae9f..b79879063fb 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2341,8 +2341,9 @@ Cursor Parameters
 @end table
 
 @vindex cursor-type
-The @code{cursor-type} frame parameter may be overridden by the
-variables @code{cursor-type} and
+The @code{cursor-type} frame parameter may be overridden by the window
+parameter @code{cursor-type} (@pxref{Definition of cursor-type window
+parameter}), and by the variables @code{cursor-type} and
 @code{cursor-in-non-selected-windows}:
 
 @defopt cursor-type
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..b66b81aca6e 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -6691,6 +6691,18 @@ Window Parameters
 window and should be used, with due care, exclusively by those
 applications.  It might be replaced by an improved solution in future
 versions of Emacs.
+
+@item cursor-type
+@vindex cursor-type@r{, a window parameter}
+@anchor{Definition of cursor-type window parameter}
+If this parameter is set to a cons cell, its @sc{car} specifies the
+shape of the cursor in this window, using the same format as the
+buffer-local variable @code{cursor-type}.  @xref{Cursor Parameters}.
+Use this window parameter instead of the @code{cursor-type} variable or
+frame parameter when a buffer is displayed in multiple windows and you
+want to change the cursor for one window without affecting the others.
+This window parameter takes precedence over the @code{cursor-type}
+variable as well as @code{cursor-in-non-selected-windows}.
 @end table
 
 
diff --git a/etc/NEWS b/etc/NEWS
index 9c356e64bde..e08998e4b6f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,12 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New window parameter 'cursor-type'.
+If this parameter is set to a cons cell, its 'car' specifies the shape
+of the window's cursor, using the same format as the buffer-local
+variable 'cursor-type'.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/xdisp.c b/src/xdisp.c
index 85802ec5083..9e4e145d93d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33605,7 +33605,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   struct frame *f = XFRAME (w->frame);
   struct buffer *b = XBUFFER (w->contents);
   int cursor_type = DEFAULT_CURSOR;
-  Lisp_Object alt_cursor;
+  Lisp_Object alt_cursor, win_cursor;
   bool non_selected = false;
 
   *active_cursor = true;
@@ -33617,7 +33617,12 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
 	{
-	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
+	  win_cursor = window_parameter (w, Qcursor_type);
+	  if (CONSP (win_cursor))
+	    {
+	      return get_specified_cursor_type (XCAR (win_cursor), width);
+	    }
+	  else if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
 	    {
 	      *width = FRAME_CURSOR_WIDTH (f);
 	      return FRAME_DESIRED_CURSOR (f);
@@ -33644,22 +33649,30 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  win_cursor = window_parameter (w, Qcursor_type);
+  if (CONSP (win_cursor))
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      cursor_type = get_specified_cursor_type (XCAR (win_cursor), width);
     }
   else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
+    {
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
+    }
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-  if (non_selected)
+  if (non_selected && !CONSP (win_cursor))
     {
       alt_cursor = BVAR (b, cursor_in_non_selected_windows);
       if (!EQ (Qt, alt_cursor))
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-28 15:00   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-28 15:29     ` Eli Zaretskii
  2024-04-28 19:05       ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-29  9:48       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 29+ messages in thread
From: Eli Zaretskii @ 2024-04-28 15:29 UTC (permalink / raw)
  To: Eshel Yaron, martin rudalics; +Cc: 70622

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: 70622@debbugs.gnu.org
> Date: Sun, 28 Apr 2024 17:00:33 +0200
> 
> > Why only cons cells are supported?
> 
> We need a convenient way to specify both "window parameter not set" and
> "window parameter set and says not to show a cursor".  Naturally, we
> want to use nil for "window parameter not set", but then nil is what the
> variable cursor-type uses for "don't to show a cursor".

We have the same problem in the frame parameter by this name, and we
solve it there without these complications.  Why should the window
parameter be different?  It's confusing and hard to remember.

> > And I have a question: is this supposed to work for non-selected
> > windows as well?  The documentation you added says nothing about that,
> > but I wonder what was the intent?
> 
> Yes, it's supposed to work for non-selected windows as well.  Do you
> think that's worth mentioning explicitly in the documentation?

Not just that, but it also means one cannot specify a different cursor
type for a window when it's selected and when not selected, unlike
with buffers.  Is this anomaly justified?

> > The reason I ask is that we have two buffer-local variables, not one,
> > for both selected and non-selected windows, whereas your patch
> > provides just one window parameter.  How will it interact with the
> > buffer-local variables in both cases?
> 
> That's a really good point.  WRT cursor-in-non-selected-windows, I think
> there are two viable options:
> 
> 1. Give cursor-in-non-selected-windows precedence over the new window
>    parameter, and add another window parameter to override
>    cursor-in-non-selected-windows.
> 2. Give the new window parameter precedence also over
>    cursor-in-non-selected-windows.
> 
> In the updated patch, I went with option 2, so if you set the
> cursor-type window parameter, that overrides any buffer-local variable,
> whether or not the window is selected.  I think that's sensible enough,
> WDYT?

I tend to think option 1 is better, but I'm curious what others think.
Martin, WDYT?

> > In addition, what is supposed to happen when this new window-parameter
> > is changed? is the cursor supposed to be redrawn in the new shape
> > immediately, i.e. do you expect redisplay to happen right away to
> > update the relevant window?
> 
> Not necessarily.  In cases where we want to ensure the cursor is redrawn
> immediately in a non-selected window, we can use force-window-update
> after setting the window parameter.  Should that be mentioned in the
> documentation as well?

I think it would be better to make sure the parameter takes effect
immediately.  Documenting the force-window-update thing should be
fallback, if the immediate effect is impossible.

>        if (w == XWINDOW (echo_area_window))
>  	{
> -	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
> +	  win_cursor = window_parameter (w, Qcursor_type);
> +	  if (CONSP (win_cursor))
> +	    {
> +	      return get_specified_cursor_type (XCAR (win_cursor), width);
> +	    }

We don't use braces for a single-line block.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-28 15:29     ` Eli Zaretskii
@ 2024-04-28 19:05       ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-29  6:31         ` Eli Zaretskii
  2024-04-29  9:48       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-28 19:05 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: martin rudalics, 70622

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: 70622@debbugs.gnu.org
>> Date: Sun, 28 Apr 2024 17:00:33 +0200
>>
>> > Why only cons cells are supported?
>>
>> We need a convenient way to specify both "window parameter not set" and
>> "window parameter set and says not to show a cursor".  Naturally, we
>> want to use nil for "window parameter not set", but then nil is what the
>> variable cursor-type uses for "don't to show a cursor".
>
> We have the same problem in the frame parameter by this name, and we
> solve it there without these complications.  Why should the window
> parameter be different?

This is a little different, though.  Indeed, the frame parameter also
uses nil to denote "no cursor".  The variable, which overrides the frame
parameter, uses t to delegate to the frame parameter, so it supports all
values of the frame parameter (including nil), plus t.  But unlike a
variable, we can't make the window parameter default to t (or any other
non-nil value) as easily.

> It's confusing and hard to remember.

I went with this format because it lets you use all values of the
cursor-type variable in a uniform manner (just wrap it in a list).
Alternatively, we can use the exact same format for the window
parameter as we do for the variable, except we interpret a window
parameter nil value as "window parameter unset", not "no cursor", and
instead add another value for the window parameter, 'none, that'll
correspond to the nil value of the variable (so window parameter 'none
would say not to show the cursor).  This is in line with what we have
for the mode-line-format variable and window parameter, for example.
Does this alternative sound better?

>> > And I have a question: is this supposed to work for non-selected
>> > windows as well?  The documentation you added says nothing about that,
>> > but I wonder what was the intent?
>>
>> Yes, it's supposed to work for non-selected windows as well.  Do you
>> think that's worth mentioning explicitly in the documentation?
>
> Not just that, but it also means one cannot specify a different cursor
> type for a window when it's selected and when not selected, unlike
> with buffers.  Is this anomaly justified?

See below.

>> > The reason I ask is that we have two buffer-local variables, not one,
>> > for both selected and non-selected windows, whereas your patch
>> > provides just one window parameter.  How will it interact with the
>> > buffer-local variables in both cases?
>>
>> That's a really good point.  WRT cursor-in-non-selected-windows, I think
>> there are two viable options:
>>
>> 1. Give cursor-in-non-selected-windows precedence over the new window
>>    parameter, and add another window parameter to override
>>    cursor-in-non-selected-windows.
>> 2. Give the new window parameter precedence also over
>>    cursor-in-non-selected-windows.
>>
>> In the updated patch, I went with option 2, so if you set the
>> cursor-type window parameter, that overrides any buffer-local variable,
>> whether or not the window is selected.  I think that's sensible enough,
>> WDYT?
>
> I tend to think option 1 is better, but I'm curious what others think.

All right.  I can implement that option instead, if that's deemed
preferable.  The way I see it, option 1 makes it easy to set the
cursor for a window and have it change based on whether or not the
window is selected, but it requires a bit more work to set the cursor
for that window once and for all if you don't want it to change based
on window selection.  Option 2 is the other way around: it's easier in
case you want to set the cursor type for a window regardless of
whether it is selected or not.  So there's a small tradeoff here.

> Martin, WDYT?
>

[...]

> I think it would be better to make sure the parameter takes effect
> immediately.  Documenting the force-window-update thing should be
> fallback, if the immediate effect is impossible.

OK, I'll look into it.

>>        if (w == XWINDOW (echo_area_window))
>>      {
>> -	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
>> +	  win_cursor = window_parameter (w, Qcursor_type);
>> +	  if (CONSP (win_cursor))
>> +	    {
>> +	      return get_specified_cursor_type (XCAR (win_cursor), width);
>> +	    }
>
> We don't use braces for a single-line block.

Thanks, I'll fix that in the next iteration of this patch.


Best,

Eshel





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-28 19:05       ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-29  6:31         ` Eli Zaretskii
  2024-04-29  8:18           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-04-29  6:31 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: rudalics, 70622

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: martin rudalics <rudalics@gmx.at>,  70622@debbugs.gnu.org
> Date: Sun, 28 Apr 2024 21:05:59 +0200
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> From: Eshel Yaron <me@eshelyaron.com>
> >> Cc: 70622@debbugs.gnu.org
> >> Date: Sun, 28 Apr 2024 17:00:33 +0200
> >>
> >> > Why only cons cells are supported?
> >>
> >> We need a convenient way to specify both "window parameter not set" and
> >> "window parameter set and says not to show a cursor".  Naturally, we
> >> want to use nil for "window parameter not set", but then nil is what the
> >> variable cursor-type uses for "don't to show a cursor".
> >
> > We have the same problem in the frame parameter by this name, and we
> > solve it there without these complications.  Why should the window
> > parameter be different?
> 
> This is a little different, though.  Indeed, the frame parameter also
> uses nil to denote "no cursor".  The variable, which overrides the frame
> parameter, uses t to delegate to the frame parameter, so it supports all
> values of the frame parameter (including nil), plus t.  But unlike a
> variable, we can't make the window parameter default to t (or any other
> non-nil value) as easily.

I still don't think I understand the difficultly.  The "window
parameter not set" can be detected by testing whether cursor-type is
an element in the alist returned by window-parameters, couldn't it?

> > It's confusing and hard to remember.
> 
> I went with this format because it lets you use all values of the
> cursor-type variable in a uniform manner (just wrap it in a list).

It is confusing to have several parameters and variables with a
similar semantics that each require special quirks to get the same
effect.  We should try to make the forms of the values of such
variables and parameters be uniform.

> Alternatively, we can use the exact same format for the window
> parameter as we do for the variable, except we interpret a window
> parameter nil value as "window parameter unset", not "no cursor", and
> instead add another value for the window parameter, 'none, that'll
> correspond to the nil value of the variable (so window parameter 'none
> would say not to show the cursor).

That's possible, but doesn't the absence of cursor-type parameter from
window-parameters already allow to solve that?

> This is in line with what we have
> for the mode-line-format variable and window parameter, for example.

Where do we use this convention for window parameters?





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-29  6:31         ` Eli Zaretskii
@ 2024-04-29  8:18           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-29  9:08             ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-29  8:18 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, 70622

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: martin rudalics <rudalics@gmx.at>,  70622@debbugs.gnu.org
>> Date: Sun, 28 Apr 2024 21:05:59 +0200
>>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>> >> From: Eshel Yaron <me@eshelyaron.com>
>> >> Cc: 70622@debbugs.gnu.org
>> >> Date: Sun, 28 Apr 2024 17:00:33 +0200
>> >>
>> >> > Why only cons cells are supported?
>> >>
>> >> We need a convenient way to specify both "window parameter not set" and
>> >> "window parameter set and says not to show a cursor".  Naturally, we
>> >> want to use nil for "window parameter not set", but then nil is what the
>> >> variable cursor-type uses for "don't to show a cursor".
>> >
>> > We have the same problem in the frame parameter by this name, and we
>> > solve it there without these complications.  Why should the window
>> > parameter be different?
>>
>> This is a little different, though.  Indeed, the frame parameter also
>> uses nil to denote "no cursor".  The variable, which overrides the frame
>> parameter, uses t to delegate to the frame parameter, so it supports all
>> values of the frame parameter (including nil), plus t.  But unlike a
>> variable, we can't make the window parameter default to t (or any other
>> non-nil value) as easily.
>
> I still don't think I understand the difficultly.  The "window
> parameter not set" can be detected by testing whether cursor-type is
> an element in the alist returned by window-parameters, couldn't it?

Perhaps I'm missing something, but I think it's not so simple.  We
can't/shouldn't interpret a value of nil differently from no alist entry
at all, since there's no way to remove alist entries (in order to unset
the window parameter) from lisp, right?

>> > It's confusing and hard to remember.
>>
>> I went with this format because it lets you use all values of the
>> cursor-type variable in a uniform manner (just wrap it in a list).
>
> It is confusing to have several parameters and variables with a
> similar semantics that each require special quirks to get the same
> effect.  We should try to make the forms of the values of such
> variables and parameters be uniform.

Agreed.  If we could use exactly the same format for the values of the
variable and window parameter that would be best.  But AFAIU we need
some encoding (special quirk) when translating from variable values (VV)
to window parameter values (WPV), due to the competing interpretations
for nil.  The first encoding I proposed is simple and uniform: cons to
go from VV to WPV, car to go the other way.  The alternative encoding I
proposed below, following mode-line-format, is trivial for most VV, but
not uniform, because one needs to translate nil to 'none when going from
VV to WPV.

>> Alternatively, we can use the exact same format for the window
>> parameter as we do for the variable, except we interpret a window
>> parameter nil value as "window parameter unset", not "no cursor", and
>> instead add another value for the window parameter, 'none, that'll
>> correspond to the nil value of the variable (so window parameter 'none
>> would say not to show the cursor).
>
> That's possible, but doesn't the absence of cursor-type parameter from
> window-parameters already allow to solve that?

See above.  Please let me know if I'm mistaken about the possibility of
differentiating a value of nil from the absence of an alist entry.

>> This is in line with what we have
>> for the mode-line-format variable and window parameter, for example.
>
> Where do we use this convention for window parameters?

See "(elisp) Window Parameters":

‘mode-line-format’
     This parameter replaces the value of the buffer-local variable
     ‘mode-line-format’ (*note Mode Line Basics::) of this window's
     buffer whenever this window is displayed.  The symbol ‘none’ means
     to suppress display of a mode line for this window.

Here the window parameter has the same set of possible values as the
variable, except the window parameter also has the value 'none, which
corresponds to the variable's nil value.  The nil value of the window
parameter means "window parameter not set".





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-29  8:18           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-29  9:08             ` Eli Zaretskii
  2024-04-29  9:48               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-04-29  9:08 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: rudalics, 70622

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: rudalics@gmx.at,  70622@debbugs.gnu.org
> Date: Mon, 29 Apr 2024 10:18:33 +0200
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > I still don't think I understand the difficultly.  The "window
> > parameter not set" can be detected by testing whether cursor-type is
> > an element in the alist returned by window-parameters, couldn't it?
> 
> Perhaps I'm missing something, but I think it's not so simple.  We
> can't/shouldn't interpret a value of nil differently from no alist entry
> at all, since there's no way to remove alist entries (in order to unset
> the window parameter) from lisp, right?

Why is the ability to remove important?

> > It is confusing to have several parameters and variables with a
> > similar semantics that each require special quirks to get the same
> > effect.  We should try to make the forms of the values of such
> > variables and parameters be uniform.
> 
> Agreed.  If we could use exactly the same format for the values of the
> variable and window parameter that would be best.  But AFAIU we need
> some encoding (special quirk) when translating from variable values (VV)
> to window parameter values (WPV), due to the competing interpretations
> for nil.  The first encoding I proposed is simple and uniform: cons to
> go from VV to WPV, car to go the other way.  The alternative encoding I
> proposed below, following mode-line-format, is trivial for most VV, but
> not uniform, because one needs to translate nil to 'none when going from
> VV to WPV.
> 
> >> Alternatively, we can use the exact same format for the window
> >> parameter as we do for the variable, except we interpret a window
> >> parameter nil value as "window parameter unset", not "no cursor", and
> >> instead add another value for the window parameter, 'none, that'll
> >> correspond to the nil value of the variable (so window parameter 'none
> >> would say not to show the cursor).
> >
> > That's possible, but doesn't the absence of cursor-type parameter from
> > window-parameters already allow to solve that?
> 
> See above.  Please let me know if I'm mistaken about the possibility of
> differentiating a value of nil from the absence of an alist entry.
> 
> >> This is in line with what we have
> >> for the mode-line-format variable and window parameter, for example.
> >
> > Where do we use this convention for window parameters?
> 
> See "(elisp) Window Parameters":
> 
> ‘mode-line-format’
>      This parameter replaces the value of the buffer-local variable
>      ‘mode-line-format’ (*note Mode Line Basics::) of this window's
>      buffer whenever this window is displayed.  The symbol ‘none’ means
>      to suppress display of a mode line for this window.
> 
> Here the window parameter has the same set of possible values as the
> variable, except the window parameter also has the value 'none, which
> corresponds to the variable's nil value.  The nil value of the window
> parameter means "window parameter not set".

If this is unavoidable (which I'm not yet sure), we can use this.  But
let's first hear from Martin, maybe there are better ideas.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-28 15:29     ` Eli Zaretskii
  2024-04-28 19:05       ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-29  9:48       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-29  9:48 UTC (permalink / raw)
  To: Eli Zaretskii, Eshel Yaron; +Cc: 70622

 >> WRT cursor-in-non-selected-windows, I think
 >> there are two viable options:
 >>
 >> 1. Give cursor-in-non-selected-windows precedence over the new window
 >>     parameter, and add another window parameter to override
 >>     cursor-in-non-selected-windows.
 >> 2. Give the new window parameter precedence also over
 >>     cursor-in-non-selected-windows.
 >>
 >> In the updated patch, I went with option 2, so if you set the
 >> cursor-type window parameter, that overrides any buffer-local variable,
 >> whether or not the window is selected.  I think that's sensible enough,
 >> WDYT?
 >
 > I tend to think option 1 is better, but I'm curious what others think.
 > Martin, WDYT?

I'd give 'cursor-in-non-selected-windows' precedence over the new window
parameter and not add another window parameter to override it.  IIUC
that's what a buffer-local value of 'cursor-in-non-selected-windows'
currently does to a 'cursor-type' frame parameter.

 >> Not necessarily.  In cases where we want to ensure the cursor is redrawn
 >> immediately in a non-selected window, we can use force-window-update
 >> after setting the window parameter.  Should that be mentioned in the
 >> documentation as well?
 >
 > I think it would be better to make sure the parameter takes effect
 > immediately.  Documenting the force-window-update thing should be
 > fallback, if the immediate effect is impossible.

I think 'set-window-parameter' should handle 'cursor-type' specially -
when it changes, it should set that window's redisplay flag.

martin





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-29  9:08             ` Eli Zaretskii
@ 2024-04-29  9:48               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-29 11:10                 ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-29  9:48 UTC (permalink / raw)
  To: Eli Zaretskii, Eshel Yaron; +Cc: 70622

 >> Here the window parameter has the same set of possible values as the
 >> variable, except the window parameter also has the value 'none, which
 >> corresponds to the variable's nil value.  The nil value of the window
 >> parameter means "window parameter not set".
 >
 > If this is unavoidable (which I'm not yet sure), we can use this.  But
 > let's first hear from Martin, maybe there are better ideas.

Since I'm responsible for the 'none' convention (which I dislike) I have
no better ideas.  Would it help to make cursor_type a slot in the window
structure and provide a 'set-window-cursor-type' function?

martin





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-29  9:48               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-29 11:10                 ` Eli Zaretskii
  2024-04-30  9:03                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-04-29 11:10 UTC (permalink / raw)
  To: martin rudalics; +Cc: me, 70622

> Date: Mon, 29 Apr 2024 11:48:19 +0200
> Cc: 70622@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  >> Here the window parameter has the same set of possible values as the
>  >> variable, except the window parameter also has the value 'none, which
>  >> corresponds to the variable's nil value.  The nil value of the window
>  >> parameter means "window parameter not set".
>  >
>  > If this is unavoidable (which I'm not yet sure), we can use this.  But
>  > let's first hear from Martin, maybe there are better ideas.
> 
> Since I'm responsible for the 'none' convention (which I dislike) I have
> no better ideas.  Would it help to make cursor_type a slot in the window
> structure and provide a 'set-window-cursor-type' function?

So that cursor-type is no longer a window-parameter?





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-29 11:10                 ` Eli Zaretskii
@ 2024-04-30  9:03                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-04-30 12:12                     ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-04-30  9:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: me, 70622

 > So that cursor-type is no longer a window-parameter?

Yes.  IIUC it would mean that we have to initialize the cursor_type slot
of a new window to t.  With the window parameter solution one would have
to add a new 'cursor-type' parameter with a value of t whenever making a
new window.  This would break with the convention that non-nil window
parameters are used for handling "special" behaviors only.

martin





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-30  9:03                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-04-30 12:12                     ` Eli Zaretskii
  2024-05-09  7:44                       ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-04-30 12:12 UTC (permalink / raw)
  To: martin rudalics; +Cc: me, 70622

> Date: Tue, 30 Apr 2024 11:03:44 +0200
> Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > So that cursor-type is no longer a window-parameter?
> 
> Yes.  IIUC it would mean that we have to initialize the cursor_type slot
> of a new window to t.  With the window parameter solution one would have
> to add a new 'cursor-type' parameter with a value of t whenever making a
> new window.  This would break with the convention that non-nil window
> parameters are used for handling "special" behaviors only.

I'm fine with this approach, thanks.  It will also solve nicely the
problem of redisplaying the affected window ASAP.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-04-30 12:12                     ` Eli Zaretskii
@ 2024-05-09  7:44                       ` Eli Zaretskii
  2024-05-09 10:56                         ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-09  7:44 UTC (permalink / raw)
  To: me; +Cc: rudalics, 70622

> Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
> Date: Tue, 30 Apr 2024 15:12:12 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> 
> > Date: Tue, 30 Apr 2024 11:03:44 +0200
> > Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
> > From: martin rudalics <rudalics@gmx.at>
> > 
> >  > So that cursor-type is no longer a window-parameter?
> > 
> > Yes.  IIUC it would mean that we have to initialize the cursor_type slot
> > of a new window to t.  With the window parameter solution one would have
> > to add a new 'cursor-type' parameter with a value of t whenever making a
> > new window.  This would break with the convention that non-nil window
> > parameters are used for handling "special" behaviors only.
> 
> I'm fine with this approach, thanks.  It will also solve nicely the
> problem of redisplaying the affected window ASAP.

Eshel, could you please update your patch along these lines?

Thanks.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-09  7:44                       ` Eli Zaretskii
@ 2024-05-09 10:56                         ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-09 11:25                           ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-09 10:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, 70622

[-- Attachment #1: Type: text/plain, Size: 992 bytes --]

Hi,

Eli Zaretskii <eliz@gnu.org> writes:

>> Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
>> Date: Tue, 30 Apr 2024 15:12:12 +0300
>> From: Eli Zaretskii <eliz@gnu.org>
>> 
>> > Date: Tue, 30 Apr 2024 11:03:44 +0200
>> > Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
>> > From: martin rudalics <rudalics@gmx.at>
>> > 
>> >  > So that cursor-type is no longer a window-parameter?
>> > 
>> > Yes.  IIUC it would mean that we have to initialize the cursor_type slot
>> > of a new window to t.  With the window parameter solution one would have
>> > to add a new 'cursor-type' parameter with a value of t whenever making a
>> > new window.  This would break with the convention that non-nil window
>> > parameters are used for handling "special" behaviors only.
>> 
>> I'm fine with this approach, thanks.  It will also solve nicely the
>> problem of redisplaying the affected window ASAP.
>
> Eshel, could you please update your patch along these lines?

Yes, how does the attached patch look?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v3-0001-New-functions-set-window-cursor-type.patch --]
[-- Type: text/x-patch, Size: 7421 bytes --]

From 418170a9860d368eb268b01f7b3d00f5c4d9e169 Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH v3] New functions '(set-)window-cursor-type'

* src/window.h (struct window): Add 'cursor_type' slot.
(wset_cursor_type): New inline function.
* src/xdisp.c (get_window_cursor_type): Consult 'cursor_type'.
* src/window.c (make_window): Initialize 'cursor_type' to t.
(Fset_window_cursor_type, Fwindow_cursor_type): New functions.
(syms_of_window): List their symbols.
* doc/lispref/windows.texi (Window Point): Document them.
* doc/lispref/frames.texi (Cursor Parameters): Mention
new 'set-window-cursor-type'.
* etc/NEWS: Announce new functions.  (Bug#70622)
---
 doc/lispref/frames.texi  |  6 +++---
 doc/lispref/windows.texi | 12 ++++++++++++
 etc/NEWS                 |  5 +++++
 src/window.c             | 30 ++++++++++++++++++++++++++++++
 src/window.h             |  9 +++++++++
 src/xdisp.c              | 29 ++++++++++++++++++-----------
 6 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index cae93acae9f..df6a94ed0f7 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2341,9 +2341,9 @@ Cursor Parameters
 @end table
 
 @vindex cursor-type
-The @code{cursor-type} frame parameter may be overridden by the
-variables @code{cursor-type} and
-@code{cursor-in-non-selected-windows}:
+The @code{cursor-type} frame parameter may be overridden by
+@code{set-window-cursor-type}, and by the variables @code{cursor-type}
+and @code{cursor-in-non-selected-windows}:
 
 @defopt cursor-type
 This buffer-local variable controls how the cursor looks in a selected
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..745dca49f9a 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -5142,6 +5142,18 @@ Window Point
 so @code{window-point} will stay behind text inserted there.
 @end defvar
 
+@defun set-window-cursor-type window type
+This function sets the cursor shape for @var{window}.  This setting
+takes precedence over the @code{cursor-type} variable, and @var{type}
+has the same format as the value of that variable.  If @var{window} is
+@code{nil}, it means to set the cursor type for the selected window.
+@end defun
+
+@defun window-cursor-type &optional window
+This function returns the cursor type of @var{window}, defaulting to the
+selected window.
+@end defun
+
 @node Window Start and End
 @section The Window Start and End Positions
 @cindex window start position
diff --git a/etc/NEWS b/etc/NEWS
index 9c356e64bde..3cf97b605e7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,11 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
+'set-window-cursor-type' sets a per-window cursor type, and
+'window-cursor-type' queries this setting for a given window.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/window.c b/src/window.c
index cf12841bd51..e71f1b152a6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4425,6 +4425,7 @@ make_window (void)
   wset_old_pointm (w, Fmake_marker ());
   wset_vertical_scroll_bar_type (w, Qt);
   wset_horizontal_scroll_bar_type (w, Qt);
+  wset_cursor_type (w, Qt);
   /* These Lisp fields are marked specially so they're not set to nil by
      allocate_window.  */
   wset_prev_buffers (w, Qnil);
@@ -8050,6 +8051,33 @@ DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
 		w->fringes_persistent ? Qt : Qnil);
 }
 
+DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
+       Sset_window_cursor_type, 2, 2, 0,
+       doc: /* Set the `cursor-type' of WINDOW to TYPE.
+
+This setting takes precedence over the variable `cursor-type', and TYPE
+has the same format as the value of that variable.  WINDOW nil means use
+the selected window.  */)
+  (Lisp_Object window, Lisp_Object type)
+{
+  struct window *w = decode_live_window (window);
+
+  wset_cursor_type (w, type);
+
+  /* Redisplay with updated cursor type.  */
+  wset_redisplay (w);
+
+  return type;
+}
+
+DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
+       0, 1, 0,
+       doc: /* Return the `cursor-type' of WINDOW.
+WINDOW must be a live window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_live_window (window)->cursor_type;
+}
 
 \f
 /***********************************************************************
@@ -8976,4 +9004,6 @@ syms_of_window (void)
   defsubr (&Swindow_parameters);
   defsubr (&Swindow_parameter);
   defsubr (&Sset_window_parameter);
+  defsubr (&Swindow_cursor_type);
+  defsubr (&Sset_window_cursor_type);
 }
diff --git a/src/window.h b/src/window.h
index 19283725931..297f3c66044 100644
--- a/src/window.h
+++ b/src/window.h
@@ -323,6 +323,9 @@ #define WINDOW_H_INCLUDED
        as the normal may yield a matrix which is too small.  */
     int nrows_scale_factor, ncols_scale_factor;
 
+    /* `cursor-type' to use in this window.  */
+    Lisp_Object cursor_type;
+
     /* Intended cursor position.   This is a position within the
        glyph matrix.  */
     struct cursor_pos cursor;
@@ -542,6 +545,12 @@ wset_horizontal_scroll_bar_type (struct window *w, Lisp_Object val)
   w->horizontal_scroll_bar_type = val;
 }
 
+INLINE void
+wset_cursor_type (struct window *w, Lisp_Object val)
+{
+  w->cursor_type = val;
+}
+
 INLINE void
 wset_prev_buffers (struct window *w, Lisp_Object val)
 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 85802ec5083..24d0c090326 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33617,7 +33617,9 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
 	{
-	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
+	  if (!EQ (Qt, w->cursor_type))
+	      return get_specified_cursor_type (w->cursor_type, width);
+	  else if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
 	    {
 	      *width = FRAME_CURSOR_WIDTH (f);
 	      return FRAME_DESIRED_CURSOR (f);
@@ -33644,18 +33646,23 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  if (!EQ (Qt, w->cursor_type))
+      cursor_type = get_specified_cursor_type (w->cursor_type, width);
+  else
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
     }
-  else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-- 
2.45.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-09 10:56                         ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-09 11:25                           ` Eli Zaretskii
  2024-05-09 14:19                             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-09 11:25 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: rudalics, 70622

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: rudalics@gmx.at,  70622@debbugs.gnu.org
> Date: Thu, 09 May 2024 12:56:54 +0200
> 
> > Eshel, could you please update your patch along these lines?
> 
> Yes, how does the attached patch look?

Looks good, with a few nits:

>  @vindex cursor-type
> -The @code{cursor-type} frame parameter may be overridden by the
> -variables @code{cursor-type} and
> -@code{cursor-in-non-selected-windows}:
> +The @code{cursor-type} frame parameter may be overridden by
> +@code{set-window-cursor-type}, and by the variables @code{cursor-type}
> +and @code{cursor-in-non-selected-windows}:

Please add here a cross-reference to where set-window-cursor-type is
described.

> --- a/doc/lispref/windows.texi
> +++ b/doc/lispref/windows.texi
> @@ -5142,6 +5142,18 @@ Window Point
>  so @code{window-point} will stay behind text inserted there.
>  @end defvar
>  
> +@defun set-window-cursor-type window type
> +This function sets the cursor shape for @var{window}.  This setting
> +takes precedence over the @code{cursor-type} variable, and @var{type}
> +has the same format as the value of that variable.

And here, please add a cross-reference to where the values accepted by
cursor-type are described.

> ++++
> +*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
> +'set-window-cursor-type' sets a per-window cursor type, and
> +'window-cursor-type' queries this setting for a given window.

Here, we should tell what is the default value and its meaning.

> +DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
> +       Sset_window_cursor_type, 2, 2, 0,
> +       doc: /* Set the `cursor-type' of WINDOW to TYPE.
> +
> +This setting takes precedence over the variable `cursor-type', and TYPE
> +has the same format as the value of that variable.  WINDOW nil means use
> +the selected window.  */)
> +  (Lisp_Object window, Lisp_Object type)
> +{
> +  struct window *w = decode_live_window (window);
> +
> +  wset_cursor_type (w, type);

Shouldn't we validate the value of TYPE before plugging it into the
window?  I know we will validate it at display time, but maybe it's a
good idea to do that here as well, and signal an error up front?
Martin, WDYT?

> +DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
> +       0, 1, 0,
> +       doc: /* Return the `cursor-type' of WINDOW.
> +WINDOW must be a live window and defaults to the selected one.  */)
> +  (Lisp_Object window)
> +{
> +  return decode_live_window (window)->cursor_type;
> +}

This will AFAIU return t if the value is Qt.  Should we return the
value actually in effect in that case?

> --- a/src/window.h
> +++ b/src/window.h
> @@ -323,6 +323,9 @@ #define WINDOW_H_INCLUDED
>         as the normal may yield a matrix which is too small.  */
>      int nrows_scale_factor, ncols_scale_factor;
>  
> +    /* `cursor-type' to use in this window.  */
> +    Lisp_Object cursor_type;
> +

The comment after the mode_line_help_echo member of 'struct window'
says:

    /* No Lisp data may follow this point; mode_line_help_echo must be
       the last Lisp member.  */

So you must move this new Lisp_Object member to before
mode_line_help_echo (or move it just after it, and update the comment
and allocate_window accordingly).  This is because GC needs to know
where the Lisp part of a window object ends.

Thanks.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-09 11:25                           ` Eli Zaretskii
@ 2024-05-09 14:19                             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-10  8:58                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-10 16:19                               ` Eli Zaretskii
  0 siblings, 2 replies; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-09 14:19 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, 70622

[-- Attachment #1: Type: text/plain, Size: 4155 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: rudalics@gmx.at,  70622@debbugs.gnu.org
>> Date: Thu, 09 May 2024 12:56:54 +0200
>>
>> > Eshel, could you please update your patch along these lines?
>>
>> Yes, how does the attached patch look?
>
> Looks good, with a few nits:

Thanks, I'm attaching another iteration of this patch below.

>>  @vindex cursor-type
>> -The @code{cursor-type} frame parameter may be overridden by the
>> -variables @code{cursor-type} and
>> -@code{cursor-in-non-selected-windows}:
>> +The @code{cursor-type} frame parameter may be overridden by
>> +@code{set-window-cursor-type}, and by the variables @code{cursor-type}
>> +and @code{cursor-in-non-selected-windows}:
>
> Please add here a cross-reference to where set-window-cursor-type is
> described.

Done.

>> --- a/doc/lispref/windows.texi
>> +++ b/doc/lispref/windows.texi
>> @@ -5142,6 +5142,18 @@ Window Point
>>  so @code{window-point} will stay behind text inserted there.
>>  @end defvar
>>
>> +@defun set-window-cursor-type window type
>> +This function sets the cursor shape for @var{window}.  This setting
>> +takes precedence over the @code{cursor-type} variable, and @var{type}
>> +has the same format as the value of that variable.
>
> And here, please add a cross-reference to where the values accepted by
> cursor-type are described.

Done.

>> ++++
>> +*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
>> +'set-window-cursor-type' sets a per-window cursor type, and
>> +'window-cursor-type' queries this setting for a given window.
>
> Here, we should tell what is the default value and its meaning.

And done.

>> +DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
>> +       Sset_window_cursor_type, 2, 2, 0,
>> +       doc: /* Set the `cursor-type' of WINDOW to TYPE.
>> +
>> +This setting takes precedence over the variable `cursor-type', and TYPE
>> +has the same format as the value of that variable.  WINDOW nil means use
>> +the selected window.  */)
>> +  (Lisp_Object window, Lisp_Object type)
>> +{
>> +  struct window *w = decode_live_window (window);
>> +
>> +  wset_cursor_type (w, type);
>
> Shouldn't we validate the value of TYPE before plugging it into the
> window?  I know we will validate it at display time, but maybe it's a
> good idea to do that here as well, and signal an error up front?

AFAICT there are no invalid values, since we take "any other value" to
mean the same as 'hollow' (see C-h v cursor-type), so I think not
validating anything should be perfectly valid :)

> Martin, WDYT?
>
>> +DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
>> +       0, 1, 0,
>> +       doc: /* Return the `cursor-type' of WINDOW.
>> +WINDOW must be a live window and defaults to the selected one.  */)
>> +  (Lisp_Object window)
>> +{
>> +  return decode_live_window (window)->cursor_type;
>> +}
>
> This will AFAIU return t if the value is Qt.  Should we return the
> value actually in effect in that case?

Maybe, but that's a bit tricky because we need to consider whether or
not the window is selected and what cursor-in-non-selected-windows has
to say to figure out what the cursor will actually look like.  Currently
this function just provides Lisp with access to the window slot, so we
have all the needed information available in Lisp.  I suggest keeping
'window-cursor-type' simple and, if the need arises, providing a Lisp
function that calculates the effective cursor type for a given window.
WDYT?

>> --- a/src/window.h
>> +++ b/src/window.h
>> @@ -323,6 +323,9 @@ #define WINDOW_H_INCLUDED
>>         as the normal may yield a matrix which is too small.  */
>>      int nrows_scale_factor, ncols_scale_factor;
>>
>> +    /* `cursor-type' to use in this window.  */
>> +    Lisp_Object cursor_type;
>> +
>
> The comment after the mode_line_help_echo member of 'struct window'
> says:
>
>     /* No Lisp data may follow this point; mode_line_help_echo must be
>        the last Lisp member.  */

Oh I missed that, thanks!

> So you must move this new Lisp_Object member to before
> mode_line_help_echo

Done, here's the updated patch:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v4-0001-New-functions-set-window-cursor-type.patch --]
[-- Type: text/x-patch, Size: 7548 bytes --]

From c685d968962be8e16205bffb4cc1a953218d8e4f Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH v4] New functions '(set-)window-cursor-type'

* src/window.h (struct window): Add 'cursor_type' slot.
(wset_cursor_type): New inline function.
* src/xdisp.c (get_window_cursor_type): Consult 'cursor_type'.
* src/window.c (make_window): Initialize 'cursor_type' to t.
(Fset_window_cursor_type, Fwindow_cursor_type): New functions.
(syms_of_window): List their symbols.
* doc/lispref/windows.texi (Window Point): Document them.
* doc/lispref/frames.texi (Cursor Parameters): Mention
new 'set-window-cursor-type'.
* etc/NEWS: Announce new functions.  (Bug#70622)
---
 doc/lispref/frames.texi  |  6 +++---
 doc/lispref/windows.texi | 13 +++++++++++++
 etc/NEWS                 |  7 +++++++
 src/window.c             | 30 ++++++++++++++++++++++++++++++
 src/window.h             |  9 +++++++++
 src/xdisp.c              | 29 ++++++++++++++++++-----------
 6 files changed, 80 insertions(+), 14 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index cae93acae9f..974def3de10 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2341,9 +2341,9 @@ Cursor Parameters
 @end table
 
 @vindex cursor-type
-The @code{cursor-type} frame parameter may be overridden by the
-variables @code{cursor-type} and
-@code{cursor-in-non-selected-windows}:
+The @code{cursor-type} frame parameter may be overridden by
+@code{set-window-cursor-type} (@pxref{Window Point}), and by the
+variables @code{cursor-type} and @code{cursor-in-non-selected-windows}:
 
 @defopt cursor-type
 This buffer-local variable controls how the cursor looks in a selected
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..eb9a5b4efb1 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -5142,6 +5142,19 @@ Window Point
 so @code{window-point} will stay behind text inserted there.
 @end defvar
 
+@defun set-window-cursor-type window type
+This function sets the cursor shape for @var{window}.  This setting
+takes precedence over the @code{cursor-type} variable, and @var{type}
+has the same format as the value of that variable.  @xref{Cursor
+Parameters}.  If @var{window} is @code{nil}, it means to set the cursor
+type for the selected window.
+@end defun
+
+@defun window-cursor-type &optional window
+This function returns the cursor type of @var{window}, defaulting to the
+selected window.
+@end defun
+
 @node Window Start and End
 @section The Window Start and End Positions
 @cindex window start position
diff --git a/etc/NEWS b/etc/NEWS
index 9c356e64bde..700c7d060b8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,13 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
+'set-window-cursor-type' sets a per-window cursor type, and
+'window-cursor-type' queries this setting for a given window.  Windows
+are always created with a 'window-cursor-type' of t, which means to
+consult the variable 'cursor-type' as before.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/window.c b/src/window.c
index cf12841bd51..e71f1b152a6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4425,6 +4425,7 @@ make_window (void)
   wset_old_pointm (w, Fmake_marker ());
   wset_vertical_scroll_bar_type (w, Qt);
   wset_horizontal_scroll_bar_type (w, Qt);
+  wset_cursor_type (w, Qt);
   /* These Lisp fields are marked specially so they're not set to nil by
      allocate_window.  */
   wset_prev_buffers (w, Qnil);
@@ -8050,6 +8051,33 @@ DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
 		w->fringes_persistent ? Qt : Qnil);
 }
 
+DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
+       Sset_window_cursor_type, 2, 2, 0,
+       doc: /* Set the `cursor-type' of WINDOW to TYPE.
+
+This setting takes precedence over the variable `cursor-type', and TYPE
+has the same format as the value of that variable.  WINDOW nil means use
+the selected window.  */)
+  (Lisp_Object window, Lisp_Object type)
+{
+  struct window *w = decode_live_window (window);
+
+  wset_cursor_type (w, type);
+
+  /* Redisplay with updated cursor type.  */
+  wset_redisplay (w);
+
+  return type;
+}
+
+DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
+       0, 1, 0,
+       doc: /* Return the `cursor-type' of WINDOW.
+WINDOW must be a live window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_live_window (window)->cursor_type;
+}
 
 \f
 /***********************************************************************
@@ -8976,4 +9004,6 @@ syms_of_window (void)
   defsubr (&Swindow_parameters);
   defsubr (&Swindow_parameter);
   defsubr (&Sset_window_parameter);
+  defsubr (&Swindow_cursor_type);
+  defsubr (&Sset_window_cursor_type);
 }
diff --git a/src/window.h b/src/window.h
index 19283725931..86932181252 100644
--- a/src/window.h
+++ b/src/window.h
@@ -205,6 +205,9 @@ #define WINDOW_H_INCLUDED
     /* An alist with parameters.  */
     Lisp_Object window_parameters;
 
+    /* `cursor-type' to use in this window.  */
+    Lisp_Object cursor_type;
+
     /* The help echo text for this window.  Qnil if there's none.  */
     Lisp_Object mode_line_help_echo;
 
@@ -542,6 +545,12 @@ wset_horizontal_scroll_bar_type (struct window *w, Lisp_Object val)
   w->horizontal_scroll_bar_type = val;
 }
 
+INLINE void
+wset_cursor_type (struct window *w, Lisp_Object val)
+{
+  w->cursor_type = val;
+}
+
 INLINE void
 wset_prev_buffers (struct window *w, Lisp_Object val)
 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 85802ec5083..24d0c090326 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33617,7 +33617,9 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
 	{
-	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
+	  if (!EQ (Qt, w->cursor_type))
+	      return get_specified_cursor_type (w->cursor_type, width);
+	  else if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
 	    {
 	      *width = FRAME_CURSOR_WIDTH (f);
 	      return FRAME_DESIRED_CURSOR (f);
@@ -33644,18 +33646,23 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  if (!EQ (Qt, w->cursor_type))
+      cursor_type = get_specified_cursor_type (w->cursor_type, width);
+  else
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
     }
-  else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-- 
2.45.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-09 14:19                             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-10  8:58                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-10 16:20                                 ` Eli Zaretskii
  2024-05-10 16:19                               ` Eli Zaretskii
  1 sibling, 1 reply; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-10  8:58 UTC (permalink / raw)
  To: Eshel Yaron, Eli Zaretskii; +Cc: 70622

 >>> +DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
 >>> +       Sset_window_cursor_type, 2, 2, 0,
 >>> +       doc: /* Set the `cursor-type' of WINDOW to TYPE.
 >>> +
 >>> +This setting takes precedence over the variable `cursor-type', and TYPE
 >>> +has the same format as the value of that variable.  WINDOW nil means use
 >>> +the selected window.  */)
 >>> +  (Lisp_Object window, Lisp_Object type)
 >>> +{
 >>> +  struct window *w = decode_live_window (window);
 >>> +
 >>> +  wset_cursor_type (w, type);
 >>
 >> Shouldn't we validate the value of TYPE before plugging it into the
 >> window?  I know we will validate it at display time, but maybe it's a
 >> good idea to do that here as well, and signal an error up front?
 >
 > AFAICT there are no invalid values, since we take "any other value" to
 > mean the same as 'hollow' (see C-h v cursor-type), so I think not
 > validating anything should be perfectly valid :)
 >
 >> Martin, WDYT?

I think Eshel is right.

 >>> +DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
 >>> +       0, 1, 0,
 >>> +       doc: /* Return the `cursor-type' of WINDOW.
 >>> +WINDOW must be a live window and defaults to the selected one.  */)
 >>> +  (Lisp_Object window)
 >>> +{
 >>> +  return decode_live_window (window)->cursor_type;
 >>> +}
 >>
 >> This will AFAIU return t if the value is Qt.  Should we return the
 >> value actually in effect in that case?
 >
 > Maybe, but that's a bit tricky because we need to consider whether or
 > not the window is selected and what cursor-in-non-selected-windows has
 > to say to figure out what the cursor will actually look like.  Currently
 > this function just provides Lisp with access to the window slot, so we
 > have all the needed information available in Lisp.  I suggest keeping
 > 'window-cursor-type' simple and, if the need arises, providing a Lisp
 > function that calculates the effective cursor type for a given window.
 > WDYT?

If needed, the function can be given a second argument that allows to
retrieve either the value specified for this window or the effective
value used.

'set-window-cursor-type' like all other functions and parameters in this
context suffers from the problem that there's no common concept wrt
setting window/buffer/frame-local values.  This matters when a
buffer-local value changes or another buffer is shown in a window.  For
margins or fringes the PERSISTENT argument can be used to tell whether a
window-specified value shall survive subsequent 'set-window-buffer'
calls.  Setting the buffer variable for these doesn't take effect
immediately.

For 'set-window-cursor-type' we probably should say that any value it
sets is "persistent" (survives subsequent 'set-window-buffer' calls)
unless the value delegates the choice to the 'cursor-type' variable or
frame parameter and that it takes effect immediately.

And we _could_ tell that setting the 'cursor-type' variable takes effect
"pretty soon", that is when an associated window is redisplayed so it
does not have to wait until the next 'set-window-buffer' call, that it
can be overridden by 'set-window-cursor-type' in quite some ways, and
that 'set-window-buffer' won't use the buffer value when another way has
been specified via 'set-window-cursor-type'.  If I'm right, obviously.

martin





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-09 14:19                             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-10  8:58                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-10 16:19                               ` Eli Zaretskii
  1 sibling, 0 replies; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-10 16:19 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: rudalics, 70622

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: rudalics@gmx.at,  70622@debbugs.gnu.org
> Date: Thu, 09 May 2024 16:19:31 +0200
> 
> >> +DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
> >> +       Sset_window_cursor_type, 2, 2, 0,
> >> +       doc: /* Set the `cursor-type' of WINDOW to TYPE.
> >> +
> >> +This setting takes precedence over the variable `cursor-type', and TYPE
> >> +has the same format as the value of that variable.  WINDOW nil means use
> >> +the selected window.  */)
> >> +  (Lisp_Object window, Lisp_Object type)
> >> +{
> >> +  struct window *w = decode_live_window (window);
> >> +
> >> +  wset_cursor_type (w, type);
> >
> > Shouldn't we validate the value of TYPE before plugging it into the
> > window?  I know we will validate it at display time, but maybe it's a
> > good idea to do that here as well, and signal an error up front?
> 
> AFAICT there are no invalid values, since we take "any other value" to
> mean the same as 'hollow' (see C-h v cursor-type), so I think not
> validating anything should be perfectly valid :)

I know, but that's because there's no useful way of signaling an error
in the middle of redisplay.  Here we have an opportunity to help the
caller to catch any mistakes before the value is applied, so why not?

> Maybe, but that's a bit tricky because we need to consider whether or
> not the window is selected and what cursor-in-non-selected-windows has
> to say to figure out what the cursor will actually look like.  Currently
> this function just provides Lisp with access to the window slot, so we
> have all the needed information available in Lisp.  I suggest keeping
> 'window-cursor-type' simple and, if the need arises, providing a Lisp
> function that calculates the effective cursor type for a given window.
> WDYT?

Martin suggested a way to have both, so I think we should take it.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-10  8:58                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-10 16:20                                 ` Eli Zaretskii
  2024-05-11  7:35                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-10 16:20 UTC (permalink / raw)
  To: martin rudalics; +Cc: me, 70622

> Date: Fri, 10 May 2024 10:58:58 +0200
> Cc: 70622@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  >>> +DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
>  >>> +       Sset_window_cursor_type, 2, 2, 0,
>  >>> +       doc: /* Set the `cursor-type' of WINDOW to TYPE.
>  >>> +
>  >>> +This setting takes precedence over the variable `cursor-type', and TYPE
>  >>> +has the same format as the value of that variable.  WINDOW nil means use
>  >>> +the selected window.  */)
>  >>> +  (Lisp_Object window, Lisp_Object type)
>  >>> +{
>  >>> +  struct window *w = decode_live_window (window);
>  >>> +
>  >>> +  wset_cursor_type (w, type);
>  >>
>  >> Shouldn't we validate the value of TYPE before plugging it into the
>  >> window?  I know we will validate it at display time, but maybe it's a
>  >> good idea to do that here as well, and signal an error up front?
>  >
>  > AFAICT there are no invalid values, since we take "any other value" to
>  > mean the same as 'hollow' (see C-h v cursor-type), so I think not
>  > validating anything should be perfectly valid :)
>  >
>  >> Martin, WDYT?
> 
> I think Eshel is right.

Any reasons?

>  > Maybe, but that's a bit tricky because we need to consider whether or
>  > not the window is selected and what cursor-in-non-selected-windows has
>  > to say to figure out what the cursor will actually look like.  Currently
>  > this function just provides Lisp with access to the window slot, so we
>  > have all the needed information available in Lisp.  I suggest keeping
>  > 'window-cursor-type' simple and, if the need arises, providing a Lisp
>  > function that calculates the effective cursor type for a given window.
>  > WDYT?
> 
> If needed, the function can be given a second argument that allows to
> retrieve either the value specified for this window or the effective
> value used.

SGTM, thanks.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-10 16:20                                 ` Eli Zaretskii
@ 2024-05-11  7:35                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-11  8:34                                     ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-11  7:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: me, 70622

 >>   >> Shouldn't we validate the value of TYPE before plugging it into the
 >>   >> window?  I know we will validate it at display time, but maybe it's a
 >>   >> good idea to do that here as well, and signal an error up front?
 >>   >
 >>   > AFAICT there are no invalid values, since we take "any other value" to
 >>   > mean the same as 'hollow' (see C-h v cursor-type), so I think not
 >>   > validating anything should be perfectly valid :)
 >>   >
 >>   >> Martin, WDYT?
 >>
 >> I think Eshel is right.
 >
 > Any reasons?

The doc-string of the variable 'cursor-type' states that

     cursor-type is a variable defined in ‘C source code’.

     Its value is t

     Cursor to use when this buffer is in the selected window.
     Values are interpreted as follows:

       t               use the cursor specified for the frame
       [...]
       ANYTHING ELSE   display a hollow box cursor

Suppose the buffer value is ANYTHING ELSE, someone wants to temporarily
change it for a specific window and later wants to reset it back to its
buffer value via 'set-window-cursor-type'.  Should Emacs signal an error
up front in that case?

martin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-11  7:35                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-11  8:34                                     ` Eli Zaretskii
  2024-05-12  8:29                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-11  8:34 UTC (permalink / raw)
  To: martin rudalics; +Cc: me, 70622

> Date: Sat, 11 May 2024 09:35:37 +0200
> Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  >>   >> Shouldn't we validate the value of TYPE before plugging it into the
>  >>   >> window?  I know we will validate it at display time, but maybe it's a
>  >>   >> good idea to do that here as well, and signal an error up front?
>  >>   >
>  >>   > AFAICT there are no invalid values, since we take "any other value" to
>  >>   > mean the same as 'hollow' (see C-h v cursor-type), so I think not
>  >>   > validating anything should be perfectly valid :)
>  >>   >
>  >>   >> Martin, WDYT?
>  >>
>  >> I think Eshel is right.
>  >
>  > Any reasons?
> 
> The doc-string of the variable 'cursor-type' states that
> 
>      cursor-type is a variable defined in ‘C source code’.
> 
>      Its value is t
> 
>      Cursor to use when this buffer is in the selected window.
>      Values are interpreted as follows:
> 
>        t               use the cursor specified for the frame
>        [...]
>        ANYTHING ELSE   display a hollow box cursor
> 
> Suppose the buffer value is ANYTHING ELSE, someone wants to temporarily
> change it for a specific window and later wants to reset it back to its
> buffer value via 'set-window-cursor-type'.  Should Emacs signal an error
> up front in that case?

I don't see why not.

The ANYTHING ELSE clause is simply defensive programming, something we
do in many other places.  It can easily hide mistakes, and I see no
reason not to help users find those mistakes.

But if you are still unconvinced, I won't argue, although I still
don't understand your and Eshel's objections.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-11  8:34                                     ` Eli Zaretskii
@ 2024-05-12  8:29                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-12  9:39                                         ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-12  8:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: me, 70622

 > The ANYTHING ELSE clause is simply defensive programming, something we
 > do in many other places.  It can easily hide mistakes, and I see no
 > reason not to help users find those mistakes.

I'm not a fan of strong typing but I agree with you.  The problem I see
is that we don't care about catching mistakes when setting the variable
or the corresponding frame parameter.  If we want to help users finding
mistakes, we should care everywhere in a consistent fashion.

 > But if you are still unconvinced, I won't argue, although I still
 > don't understand your and Eshel's objections.

I only stated my personal view and will leave it to Eshel and you how
serve users best.

martin





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-12  8:29                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-12  9:39                                         ` Eli Zaretskii
  2024-05-12 12:33                                           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-12  9:39 UTC (permalink / raw)
  To: martin rudalics; +Cc: me, 70622

> Date: Sun, 12 May 2024 10:29:24 +0200
> Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > The ANYTHING ELSE clause is simply defensive programming, something we
>  > do in many other places.  It can easily hide mistakes, and I see no
>  > reason not to help users find those mistakes.
> 
> I'm not a fan of strong typing but I agree with you.  The problem I see
> is that we don't care about catching mistakes when setting the variable
> or the corresponding frame parameter.  If we want to help users finding
> mistakes, we should care everywhere in a consistent fashion.
> 
>  > But if you are still unconvinced, I won't argue, although I still
>  > don't understand your and Eshel's objections.
> 
> I only stated my personal view and will leave it to Eshel and you how
> serve users best.

Thanks.  Let's see what Eshel takes from this.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-12  9:39                                         ` Eli Zaretskii
@ 2024-05-12 12:33                                           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-13  8:05                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-12 12:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: martin rudalics, 70622

[-- Attachment #1: Type: text/plain, Size: 1971 bytes --]

Hi,

Eli Zaretskii <eliz@gnu.org> writes:

>> Date: Sun, 12 May 2024 10:29:24 +0200
>> Cc: me@eshelyaron.com, 70622@debbugs.gnu.org
>> From: martin rudalics <rudalics@gmx.at>
>>
>>  > The ANYTHING ELSE clause is simply defensive programming, something we
>>  > do in many other places.  It can easily hide mistakes, and I see no
>>  > reason not to help users find those mistakes.
>>
>> I'm not a fan of strong typing but I agree with you.  The problem I see
>> is that we don't care about catching mistakes when setting the variable
>> or the corresponding frame parameter.  If we want to help users finding
>> mistakes, we should care everywhere in a consistent fashion.
>>
>>  > But if you are still unconvinced, I won't argue, although I still
>>  > don't understand your and Eshel's objections.
>>
>> I only stated my personal view and will leave it to Eshel and you how
>> serve users best.
>
> Thanks.  Let's see what Eshel takes from this.

I think that given there are no strictly invalid cursor-type values,
designating some (most) values as invalid for set-window-cursor-type
reduces consistency for little practical gain.  OTOH, I don't think
there's any real harm to it either, so I added such a check in the
update patch below.

I've also extended the documentation of set-window-cursor-type to note
that this setting persists when you change the buffer of the window, as
Martin suggested.

I've added a FIXME comment about extending window-cursor-type with an
optional argument that asks for the effective cursor type, but I did not
implement it at this point.  I looked into it, but the implementation is
quite involved, it basically requires duplicating many of the careful
considerations of get_window_cursor_type, or refactoring it for reuse.
Since we do provide all the needed information for computing the
effective cursor in Lisp, and there's no concrete use case for doing
that ATM, I think we can leave it at for now.


Here's the updated patch:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v5-0001-New-functions-set-window-cursor-type.patch --]
[-- Type: text/x-patch, Size: 8468 bytes --]

From 5f257d8b0ed85be9ac638b36b6669cd96c70cada Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH v5] New functions '(set-)window-cursor-type'

* src/window.h (struct window): Add 'cursor_type' slot.
(wset_cursor_type): New inline function.
* src/xdisp.c (get_window_cursor_type): Consult 'cursor_type'.
* src/window.c (make_window): Initialize 'cursor_type' to t.
(Fset_window_cursor_type, Fwindow_cursor_type): New functions.
(syms_of_window): List their symbols.
* doc/lispref/windows.texi (Window Point): Document them.
* doc/lispref/frames.texi (Cursor Parameters): Mention
new 'set-window-cursor-type'.
* etc/NEWS: Announce new functions.  (Bug#70622)
---
 doc/lispref/frames.texi  |  6 ++---
 doc/lispref/windows.texi | 18 +++++++++++++++
 etc/NEWS                 |  7 ++++++
 src/window.c             | 49 ++++++++++++++++++++++++++++++++++++++++
 src/window.h             |  9 ++++++++
 src/xdisp.c              | 29 +++++++++++++++---------
 6 files changed, 104 insertions(+), 14 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index cae93acae9f..974def3de10 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2341,9 +2341,9 @@ Cursor Parameters
 @end table
 
 @vindex cursor-type
-The @code{cursor-type} frame parameter may be overridden by the
-variables @code{cursor-type} and
-@code{cursor-in-non-selected-windows}:
+The @code{cursor-type} frame parameter may be overridden by
+@code{set-window-cursor-type} (@pxref{Window Point}), and by the
+variables @code{cursor-type} and @code{cursor-in-non-selected-windows}:
 
 @defopt cursor-type
 This buffer-local variable controls how the cursor looks in a selected
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..eac7e01946d 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -5142,6 +5142,24 @@ Window Point
 so @code{window-point} will stay behind text inserted there.
 @end defvar
 
+@defun set-window-cursor-type window type
+This function sets the cursor shape for @var{window}.  This setting
+takes precedence over the @code{cursor-type} variable, and @var{type}
+has the same format as the value of that variable.  @xref{Cursor
+Parameters}.  If @var{window} is @code{nil}, it means to set the cursor
+type for the selected window.
+
+The initial value for new windows is @code{t}, which says to respect the
+buffer-local value of @code{cursor-type}.  This setting persists across
+buffers shown in @var{window}, so @code{set-window-buffer} does not
+reset it.  @xref{Buffers and Windows}.
+@end defun
+
+@defun window-cursor-type &optional window
+This function returns the cursor type of @var{window}, defaulting to the
+selected window.
+@end defun
+
 @node Window Start and End
 @section The Window Start and End Positions
 @cindex window start position
diff --git a/etc/NEWS b/etc/NEWS
index 846bf759995..c93b04bae2d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,13 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
+'set-window-cursor-type' sets a per-window cursor type, and
+'window-cursor-type' queries this setting for a given window.  Windows
+are always created with a 'window-cursor-type' of t, which means to
+consult the variable 'cursor-type' as before.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/window.c b/src/window.c
index cf12841bd51..03f359b932b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4425,6 +4425,7 @@ make_window (void)
   wset_old_pointm (w, Fmake_marker ());
   wset_vertical_scroll_bar_type (w, Qt);
   wset_horizontal_scroll_bar_type (w, Qt);
+  wset_cursor_type (w, Qt);
   /* These Lisp fields are marked specially so they're not set to nil by
      allocate_window.  */
   wset_prev_buffers (w, Qnil);
@@ -8050,6 +8051,52 @@ DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
 		w->fringes_persistent ? Qt : Qnil);
 }
 
+DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
+       Sset_window_cursor_type, 2, 2, 0,
+       doc: /* Set the `cursor-type' of WINDOW to TYPE.
+
+This setting takes precedence over the variable `cursor-type', and TYPE
+has the same format as the value of that variable.  The initial value
+for new windows is t, which says to respect the buffer-local value of
+`cursor-type'.
+
+WINDOW nil means use the selected window.  This setting persists across
+buffers shown in WINDOW, so `set-window-buffer' does not reset it.  */)
+  (Lisp_Object window, Lisp_Object type)
+{
+  struct window *w = decode_live_window (window);
+
+  if (!(NILP (type)
+	|| EQ (type, Qt)
+	|| EQ (type, Qbox)
+	|| EQ (type, Qhollow)
+	|| EQ (type, Qbar)
+	|| EQ (type, Qhbar)
+	|| (CONSP (type)
+	    && (EQ (XCAR (type), Qbox)
+		|| EQ (XCAR (type), Qbar)
+		|| EQ (XCAR (type), Qhbar))
+	    && INTEGERP (XCDR (type)))))
+    error ("Invalid cursor type");
+
+  wset_cursor_type (w, type);
+
+  /* Redisplay with updated cursor type.  */
+  wset_redisplay (w);
+
+  return type;
+}
+
+/* FIXME: Add a way to get the _effective_ cursor type, possibly by
+   extending this function with an additional optional argument.  */
+DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
+       0, 1, 0,
+       doc: /* Return the `cursor-type' of WINDOW.
+WINDOW must be a live window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_live_window (window)->cursor_type;
+}
 
 \f
 /***********************************************************************
@@ -8976,4 +9023,6 @@ syms_of_window (void)
   defsubr (&Swindow_parameters);
   defsubr (&Swindow_parameter);
   defsubr (&Sset_window_parameter);
+  defsubr (&Swindow_cursor_type);
+  defsubr (&Sset_window_cursor_type);
 }
diff --git a/src/window.h b/src/window.h
index 19283725931..86932181252 100644
--- a/src/window.h
+++ b/src/window.h
@@ -205,6 +205,9 @@ #define WINDOW_H_INCLUDED
     /* An alist with parameters.  */
     Lisp_Object window_parameters;
 
+    /* `cursor-type' to use in this window.  */
+    Lisp_Object cursor_type;
+
     /* The help echo text for this window.  Qnil if there's none.  */
     Lisp_Object mode_line_help_echo;
 
@@ -542,6 +545,12 @@ wset_horizontal_scroll_bar_type (struct window *w, Lisp_Object val)
   w->horizontal_scroll_bar_type = val;
 }
 
+INLINE void
+wset_cursor_type (struct window *w, Lisp_Object val)
+{
+  w->cursor_type = val;
+}
+
 INLINE void
 wset_prev_buffers (struct window *w, Lisp_Object val)
 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 4b7d7e02c68..c74247e43aa 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33616,7 +33616,9 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
 	{
-	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
+	  if (!EQ (Qt, w->cursor_type))
+	      return get_specified_cursor_type (w->cursor_type, width);
+	  else if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
 	    {
 	      *width = FRAME_CURSOR_WIDTH (f);
 	      return FRAME_DESIRED_CURSOR (f);
@@ -33643,18 +33645,23 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  if (!EQ (Qt, w->cursor_type))
+      cursor_type = get_specified_cursor_type (w->cursor_type, width);
+  else
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
     }
-  else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-- 
2.45.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-12 12:33                                           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-13  8:05                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-13 12:13                                               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-13  8:05 UTC (permalink / raw)
  To: Eshel Yaron, Eli Zaretskii; +Cc: 70622

 > Here's the updated patch:

One ambiguity:

 > The initial value for new windows is @code{t}, which says to respect the
 > buffer-local value of @code{cursor-type}.  This setting persists across
                                              ^^^^^^^^^^^^
 > buffers shown in @var{window}, so @code{set-window-buffer} does not
 > reset it.  @xref{Buffers and Windows}.

"This setting" may refer to the "initial value".  I'd write "The value
set by this function".

martin





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-13  8:05                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-13 12:13                                               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-05-18  9:43                                                 ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-13 12:13 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, 70622

[-- Attachment #1: Type: text/plain, Size: 593 bytes --]

Hi Martin,

martin rudalics <rudalics@gmx.at> writes:

>> Here's the updated patch:
>
> One ambiguity:
>
>> The initial value for new windows is @code{t}, which says to respect the
>> buffer-local value of @code{cursor-type}.  This setting persists across
>                                              ^^^^^^^^^^^^
>> buffers shown in @var{window}, so @code{set-window-buffer} does not
>> reset it.  @xref{Buffers and Windows}.
>
> "This setting" may refer to the "initial value".  I'd write "The value
> set by this function".

Thanks, I've adopted your wording in the updated patch below.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v6-0001-New-functions-set-window-cursor-type.patch --]
[-- Type: text/x-patch, Size: 8486 bytes --]

From 2a9d88d38278957c4703bbbaaca543da0edb4d3e Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH v6] New functions '(set-)window-cursor-type'

* src/window.h (struct window): Add 'cursor_type' slot.
(wset_cursor_type): New inline function.
* src/xdisp.c (get_window_cursor_type): Consult 'cursor_type'.
* src/window.c (make_window): Initialize 'cursor_type' to t.
(Fset_window_cursor_type, Fwindow_cursor_type): New functions.
(syms_of_window): List their symbols.
* doc/lispref/windows.texi (Window Point): Document them.
* doc/lispref/frames.texi (Cursor Parameters): Mention
new 'set-window-cursor-type'.
* etc/NEWS: Announce new functions.  (Bug#70622)
---
 doc/lispref/frames.texi  |  6 ++---
 doc/lispref/windows.texi | 18 +++++++++++++++
 etc/NEWS                 |  7 ++++++
 src/window.c             | 49 ++++++++++++++++++++++++++++++++++++++++
 src/window.h             |  9 ++++++++
 src/xdisp.c              | 29 +++++++++++++++---------
 6 files changed, 104 insertions(+), 14 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index cae93acae9f..974def3de10 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2341,9 +2341,9 @@ Cursor Parameters
 @end table
 
 @vindex cursor-type
-The @code{cursor-type} frame parameter may be overridden by the
-variables @code{cursor-type} and
-@code{cursor-in-non-selected-windows}:
+The @code{cursor-type} frame parameter may be overridden by
+@code{set-window-cursor-type} (@pxref{Window Point}), and by the
+variables @code{cursor-type} and @code{cursor-in-non-selected-windows}:
 
 @defopt cursor-type
 This buffer-local variable controls how the cursor looks in a selected
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..d34a127a969 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -5142,6 +5142,24 @@ Window Point
 so @code{window-point} will stay behind text inserted there.
 @end defvar
 
+@defun set-window-cursor-type window type
+This function sets the cursor shape for @var{window}.  This setting
+takes precedence over the @code{cursor-type} variable, and @var{type}
+has the same format as the value of that variable.  @xref{Cursor
+Parameters}.  If @var{window} is @code{nil}, it means to set the cursor
+type for the selected window.
+
+The initial value for new windows is @code{t}, which says to respect the
+buffer-local value of @code{cursor-type}.  The value set by this
+function persists across buffers shown in @var{window}, so
+@code{set-window-buffer} does not reset it.  @xref{Buffers and Windows}.
+@end defun
+
+@defun window-cursor-type &optional window
+This function returns the cursor type of @var{window}, defaulting to the
+selected window.
+@end defun
+
 @node Window Start and End
 @section The Window Start and End Positions
 @cindex window start position
diff --git a/etc/NEWS b/etc/NEWS
index 846bf759995..c93b04bae2d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,13 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
+'set-window-cursor-type' sets a per-window cursor type, and
+'window-cursor-type' queries this setting for a given window.  Windows
+are always created with a 'window-cursor-type' of t, which means to
+consult the variable 'cursor-type' as before.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/window.c b/src/window.c
index cf12841bd51..03f359b932b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4425,6 +4425,7 @@ make_window (void)
   wset_old_pointm (w, Fmake_marker ());
   wset_vertical_scroll_bar_type (w, Qt);
   wset_horizontal_scroll_bar_type (w, Qt);
+  wset_cursor_type (w, Qt);
   /* These Lisp fields are marked specially so they're not set to nil by
      allocate_window.  */
   wset_prev_buffers (w, Qnil);
@@ -8050,6 +8051,52 @@ DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
 		w->fringes_persistent ? Qt : Qnil);
 }
 
+DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
+       Sset_window_cursor_type, 2, 2, 0,
+       doc: /* Set the `cursor-type' of WINDOW to TYPE.
+
+This setting takes precedence over the variable `cursor-type', and TYPE
+has the same format as the value of that variable.  The initial value
+for new windows is t, which says to respect the buffer-local value of
+`cursor-type'.
+
+WINDOW nil means use the selected window.  This setting persists across
+buffers shown in WINDOW, so `set-window-buffer' does not reset it.  */)
+  (Lisp_Object window, Lisp_Object type)
+{
+  struct window *w = decode_live_window (window);
+
+  if (!(NILP (type)
+	|| EQ (type, Qt)
+	|| EQ (type, Qbox)
+	|| EQ (type, Qhollow)
+	|| EQ (type, Qbar)
+	|| EQ (type, Qhbar)
+	|| (CONSP (type)
+	    && (EQ (XCAR (type), Qbox)
+		|| EQ (XCAR (type), Qbar)
+		|| EQ (XCAR (type), Qhbar))
+	    && INTEGERP (XCDR (type)))))
+    error ("Invalid cursor type");
+
+  wset_cursor_type (w, type);
+
+  /* Redisplay with updated cursor type.  */
+  wset_redisplay (w);
+
+  return type;
+}
+
+/* FIXME: Add a way to get the _effective_ cursor type, possibly by
+   extending this function with an additional optional argument.  */
+DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
+       0, 1, 0,
+       doc: /* Return the `cursor-type' of WINDOW.
+WINDOW must be a live window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_live_window (window)->cursor_type;
+}
 
 \f
 /***********************************************************************
@@ -8976,4 +9023,6 @@ syms_of_window (void)
   defsubr (&Swindow_parameters);
   defsubr (&Swindow_parameter);
   defsubr (&Sset_window_parameter);
+  defsubr (&Swindow_cursor_type);
+  defsubr (&Sset_window_cursor_type);
 }
diff --git a/src/window.h b/src/window.h
index 19283725931..86932181252 100644
--- a/src/window.h
+++ b/src/window.h
@@ -205,6 +205,9 @@ #define WINDOW_H_INCLUDED
     /* An alist with parameters.  */
     Lisp_Object window_parameters;
 
+    /* `cursor-type' to use in this window.  */
+    Lisp_Object cursor_type;
+
     /* The help echo text for this window.  Qnil if there's none.  */
     Lisp_Object mode_line_help_echo;
 
@@ -542,6 +545,12 @@ wset_horizontal_scroll_bar_type (struct window *w, Lisp_Object val)
   w->horizontal_scroll_bar_type = val;
 }
 
+INLINE void
+wset_cursor_type (struct window *w, Lisp_Object val)
+{
+  w->cursor_type = val;
+}
+
 INLINE void
 wset_prev_buffers (struct window *w, Lisp_Object val)
 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 4b7d7e02c68..c74247e43aa 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33616,7 +33616,9 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
 	{
-	  if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
+	  if (!EQ (Qt, w->cursor_type))
+	      return get_specified_cursor_type (w->cursor_type, width);
+	  else if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
 	    {
 	      *width = FRAME_CURSOR_WIDTH (f);
 	      return FRAME_DESIRED_CURSOR (f);
@@ -33643,18 +33645,23 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  if (!EQ (Qt, w->cursor_type))
+      cursor_type = get_specified_cursor_type (w->cursor_type, width);
+  else
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
     }
-  else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-- 
2.45.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-13 12:13                                               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-05-18  9:43                                                 ` Eli Zaretskii
  2024-05-18 13:45                                                   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2024-05-18  9:43 UTC (permalink / raw)
  To: Eshel Yaron; +Cc: rudalics, 70622

> From: Eshel Yaron <me@eshelyaron.com>
> Cc: Eli Zaretskii <eliz@gnu.org>,  70622@debbugs.gnu.org
> Date: Mon, 13 May 2024 14:13:53 +0200
> 
> Hi Martin,
> 
> martin rudalics <rudalics@gmx.at> writes:
> 
> >> Here's the updated patch:
> >
> > One ambiguity:
> >
> >> The initial value for new windows is @code{t}, which says to respect the
> >> buffer-local value of @code{cursor-type}.  This setting persists across
> >                                              ^^^^^^^^^^^^
> >> buffers shown in @var{window}, so @code{set-window-buffer} does not
> >> reset it.  @xref{Buffers and Windows}.
> >
> > "This setting" may refer to the "initial value".  I'd write "The value
> > set by this function".
> 
> Thanks, I've adopted your wording in the updated patch below.

Feel free to install, and thanks.





^ permalink raw reply	[flat|nested] 29+ messages in thread

* bug#70622: [PATCH] New window parameter 'cursor-type'
  2024-05-18  9:43                                                 ` Eli Zaretskii
@ 2024-05-18 13:45                                                   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 29+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-05-18 13:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, 70622

close 70622 30.1
quit

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Eshel Yaron <me@eshelyaron.com>
>> Cc: Eli Zaretskii <eliz@gnu.org>,  70622@debbugs.gnu.org
>> Date: Mon, 13 May 2024 14:13:53 +0200
>> 
>> Hi Martin,
>> 
>> martin rudalics <rudalics@gmx.at> writes:
>> 
>> >> Here's the updated patch:
>> >
>> > One ambiguity:
>> >
>> >> The initial value for new windows is @code{t}, which says to respect the
>> >> buffer-local value of @code{cursor-type}.  This setting persists across
>> >                                              ^^^^^^^^^^^^
>> >> buffers shown in @var{window}, so @code{set-window-buffer} does not
>> >> reset it.  @xref{Buffers and Windows}.
>> >
>> > "This setting" may refer to the "initial value".  I'd write "The value
>> > set by this function".
>> 
>> Thanks, I've adopted your wording in the updated patch below.
>
> Feel free to install, and thanks.

Thanks, pushed to master (commit 3b890bf2bd2), and closing the bug.


Eshel





^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2024-05-18 13:45 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-28  6:27 bug#70622: [PATCH] New window parameter 'cursor-type' Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-28  7:22 ` Eli Zaretskii
2024-04-28 15:00   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-28 15:29     ` Eli Zaretskii
2024-04-28 19:05       ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-29  6:31         ` Eli Zaretskii
2024-04-29  8:18           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-29  9:08             ` Eli Zaretskii
2024-04-29  9:48               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-29 11:10                 ` Eli Zaretskii
2024-04-30  9:03                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-30 12:12                     ` Eli Zaretskii
2024-05-09  7:44                       ` Eli Zaretskii
2024-05-09 10:56                         ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-09 11:25                           ` Eli Zaretskii
2024-05-09 14:19                             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-10  8:58                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-10 16:20                                 ` Eli Zaretskii
2024-05-11  7:35                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-11  8:34                                     ` Eli Zaretskii
2024-05-12  8:29                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-12  9:39                                         ` Eli Zaretskii
2024-05-12 12:33                                           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-13  8:05                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-13 12:13                                               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-18  9:43                                                 ` Eli Zaretskii
2024-05-18 13:45                                                   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-05-10 16:19                               ` Eli Zaretskii
2024-04-29  9:48       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.