all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: JD Smith <jdtsmith@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: xterm-mouse-mode gives incorrect posn-object-x-y with display space
Date: Fri, 25 Nov 2022 10:15:37 -0500	[thread overview]
Message-ID: <A697A69B-EC03-404E-8BDE-7C22BC06C88D@gmail.com> (raw)
In-Reply-To: <83tu2nv6rs.fsf@gnu.org>



> On Nov 25, 2022, at 2:21 AM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: JD Smith <jdtsmith@gmail.com>
>> Date: Thu, 24 Nov 2022 16:42:29 -0500
>> Cc: emacs-devel@gnu.org
>> 
>> Thanks.  The documentation on posn-object-* provides no guidance that a “string object” would not include a
>> stretched string with specified space.  So it was not at all surprising to me that it worked "as expected" in the
>> GUI.  In further support of this impression (leaving aside specified space), posn-object-x-y works perfectly
>> well on normal width characters in the buffer, providing pixel level information on where *within the
>> character* you clicked.  In fact I cannot think what "pixel-based x and y coordinates relative to the upper left
>> corner” would mean other than this for a "string object".  Surely that is not an accident of the
>> implementation!
> 
> Yes, but on TTY frames the DX/DY _within_ the character glyph are always
> zero, because each character is considered to be exactly one "pixel".  And
> if I tell you that stretches of whitespace produced by 'space' display specs
> are implemented on TTY as sequences of SPC characters (of course, what
> else?), then I think you will understand why the DX/DY values, defined in
> the ELisp manual as "the coordinates relative to the top left corner of the
> character glyph clicked on", on a TTY are always zero: wherever the click
> is, it is always on a glyph of some SPC character from those that represent
> the stretch of whitespace.

Thanks for these details.  This I had indeed understood; with char units, you can’t and won't get any pixel offsets within a single char glyph.  Since for the TTY, Emacs implements a specified space under the hood as a “series of spaces”, the natural thing for consistency with the GUI would be for posn-object-x-y to report click position offsets (in integer character units, naturally) within that stretched space.  It sounds like this may be challenging to implement internally, but it would be the most consistent.  It must be possible, since Emacs 1) knows it drew a specified space as a series of space chars in the TTY, and 2) knows (or could know) where the click occurred within that group of space chars it drew.

To summarize, the fact that in the TTY a stretched space is implemented as a collection of space chars, and on GUI, some other type of pixel-precise graphical element is IMO just an implementation detail.  What if TTY’s of the future allow drawing small graphical elements at pixel precision? How is the user of posn-object-* to know which of the two different and incompatible result flavors they will get?

>> Is there a reliable way to determine where (in pixels [1]) the mouse was clicked relative to a string displayed
>> with specified space, which works equally in the GUI and TTYs?   Keep in mind that the string may not be at
>> a fixed column, but at an arbitrary pixel offset from the window (due to prior specified space, variable width
>> fonts, etc.).  
> 
> Please tell more about your use case.  I don't think I understand what you
> mean by "string displayed with specified space”;

This is how I implement mlscroll, a mode line scroll bar we’ve discussed here before.  The basic design is 3 specified spaces in a row , usually right-aligned in the mode line. Together these 3 (varying width) spaces indicate the number of lines: i) above ii) showing, and iii) after the window.  Just like a “real” scrollbar, the user can interact with it by clicking/dragging/etc.  When clicking on the bar, the precise relative click position determines what lines are scrolled into view (again, just like a real scrollbar).  Surprisingly it looks pretty good on TTY without any special casing, though obviously with char- instead of pixel-granularity.  But this happy consistency breaks down with xterm-mouse-mode, since clicks on the modeline scrollbar are not reportable as positions w.r.t. the clicked element, i.e. since posn-object-x-y always reports 0 on TTY.  

> If I have to guess what you want, then my suggestion would be to use
> something like this:
> 
>  (let* ((event-posn (posn-point (event-start ev)))
>         (click-x-y (posn-x-y (event-start ev)))
>         (obj-x-y (posn-x-y (posn-at-point event-posn))))
>    (cons (- (car click-x-y) (car obj-x-y))
>          (- (cdr click-x-y) (cdr obj-x-y))))
> 
> IOW, don't trust DX/DY, but calculate the offsets "by hand".


Thanks for your good suggestion; this would indeed work as desired in the buffer, since posn-at-point does seem to “know” it’s in a specified space in both GUI and TTY (which makes me think posn-object-x-y should also be able to know this).

Unfortunately posn-point returns nil for posn-area = mode-line, so this does not solve the problem.  Is there any other way you know to determine the starting char position of the _group of spaces_ that TTY Emacs translates a specified space into, in the mode line?  Calculating the char-start of the scrollbar myself will be challenging given dynamic modeline elements and the possibility for the user to place the scrollbar anywhere they want (i.e. not just right-aligned).


  reply	other threads:[~2022-11-25 15:15 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-24 17:22 xterm-mouse-mode gives incorrect posn-object-x-y with display space JD Smith
2022-11-24 18:09 ` Stefan Monnier
2022-11-24 18:34 ` Eli Zaretskii
2022-11-24 21:42   ` JD Smith
2022-11-25  7:21     ` Eli Zaretskii
2022-11-25 15:15       ` JD Smith [this message]
2022-11-26 12:07     ` Eli Zaretskii
2022-11-26 18:56       ` Akib Azmain Turja
2022-11-26 19:14         ` Eli Zaretskii
2022-11-27  1:14       ` JD Smith

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=A697A69B-EC03-404E-8BDE-7C22BC06C88D@gmail.com \
    --to=jdtsmith@gmail.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.