GNU bug report logs - #28620
Mouse drag event records wrong window for release when crossing frames

Previous Next

Package: emacs;

Reported by: rswgnu <at> gmail.com

Date: Wed, 27 Sep 2017 15:45:01 UTC

Severity: normal

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 28620 in the body.
You can then email your comments to 28620 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 27 Sep 2017 15:45:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to rswgnu <at> gmail.com:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 27 Sep 2017 15:45:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: bug-gnu-emacs <at> gnu.org
Subject: Mouse drag event records wrong window for release when crossing frames
Date: Wed, 27 Sep 2017 11:44:06 -0400
[Message part 1 (text/plain, inline)]
With Emacs 25.3 under MacOS 10.12, a drag with mouse-1 depressed from
the text area of frame F1 to the text area of frame F2 improperly
generates a drag event whose (posn-window (event-end <event>)) shows
F1 rather than F2.

Note that for a drag between frames, posn-window should return a frame
(according to the Elisp manual but not its own doc string).  The bug is
that the event itself records the wrong frame (the depress frame rather
than the release frame).

I have confirmed this with Emacs 25.2 under Windows 7 as well.

Bob


In GNU Emacs 25.3.1 (x86_64-apple-darwin13.4.0, NS appkit-1265.21 Version
10.9.5 (Build 13F1911))
 of 2017-09-12 built on builder10-9.local
Windowing system distributor 'Apple', version 10.3.1504
Configured using:
 'configure --with-ns '--enable-locallisppath=/Library/Application
 Support/Emacs/${version}/site-lisp:/Library/Application
 Support/Emacs/site-lisp' --with-modules'

Configured features:
NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Emacs-Lisp

Minor modes in effect:
  recentf-mode: t
  shell-dirtrack-mode: t
  diff-auto-refine-mode: t
  desktop-save-mode: t
  winner-mode: t
  which-key-mode: t
  show-paren-mode: t
  which-function-mode: t
  persistent-scratch-autosave-mode: t
  paredit-everywhere-mode: t
  dynamic-completion-mode: t
  global-edit-server-edit-mode: t
  delete-selection-mode: t
  auto-compile-on-load-mode: t
  auto-compile-on-save-mode: t
  auto-compile-mode: t
  outline-minor-mode: t
  minibuffer-depth-indicate-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  auto-fill-function: do-auto-fill
  transient-mark-mode: t

Features:
(shadow mail-extr emacsbug tabify man magit-utils crm pulse glasses
cus-start cus-load mule-diag ispell filecache two-column iso-transl
debug recentf tree-widget helm-x-files helm-for-files helm-bookmark
helm-adaptive helm-info bookmark helm-external helm-net helm-files
image-dired ffap helm-tags helm-locate tramp tramp-compat tramp-loaddefs
trampver eieio-opt speedbar sb-image ezimage dframe helm-buffers
helm-grep helm-regexp helm-utils helm-help helm-types thai-util
thai-word misearch multi-isearch pcmpl-unix pcmpl-gnu shell dired-aux
grep hywconfig network-stream nsm starttls web-beautify org-element
org-rmail org-mhe org-irc org-info org-gnus org-docview org-bibtex
bibtex org-bbdb org-w3m doc-view arc-mode archive-mode eww mm-url gnus
gnus-ems nnheader wid-edit url-queue shr dom texinfo make-mode
skewer-html markdown-mode color sh-script smie executable rst conf-mode
tern-auto-complete tern jsdock helm-dash cursor-sensor image-mode
flycheck rx flymake jedi auto-complete popup jedi-core
python-environment epc ctable concurrent deferred pydock pydoc goto-addr
autorevert filenotify vc-git diff-mode .emacs desktop frameset
window-jump winner which-key supercite regi sort skewer-setup
skewer-mode cache-table js2-mode js cc-mode cc-fonts cc-guess cc-menus
cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs simple-httpd pp
json map python-mode compile thingatpt aggressive-indent paren
which-func imenu persistent-scratch js-lookup paredit-everywhere
paredit-menu paredit par-align rep-region id-edit wrect rect id-linecol
bw-tags apropos file-hdr lib site-key site-func id-keys id-vers
chrome-macos emmet-mode dired-x completion ido server edit-server delsel
jka-compr auto-compile packed dash hmouse-tag etags xref project
rsw-helm helm-easymenu helm edmacro kmacro helm-source eieio-compat
helm-multi-match helm-lib wdired async hyperbole hinit hibtypes
hib-doc-id hsys-www klink subr-x hib-kbd hib-social hib-debbugs
debbugs-gnu debbugs soap-client url-http tls gnutls url-auth url-gw
warnings rng-xsd rng-dt rng-util xsd-regexp hsys-org org org-macro
org-footnote org-pcomplete pcomplete org-list org-faces org-entities
org-version ob-emacs-lisp ob ob-tangle ob-ref ob-lob ob-table ob-exp
org-src ob-keys ob-comint ob-core ob-eval org-compat org-macs
org-loaddefs find-func hactypes comint ansi-color hui-mini hui hui-mouse
hui-window hargs hui-menu hyrolo-menu hyrolo google-contacts xml
url-cache url url-proxy url-privacy url-expand url-methods url-history
url-cookie url-domsuf mailcap url-util url-parse auth-source cl-seq
eieio url-vars google-oauth hmail hui-jmenu noutline outline easy-mmode
hmouse-key hmouse-sh hmouse-drv hypb locate hsettings hui-em-but hbut
hact hpath hhist hbdata htz cal-julian cal-menu calendar cal-loaddefs
hbmap hmoccur derived browse-url hui-select web-mode disp-table
sgml-mode hvar set hversion hload-path package-x mail-hist sendmail ring
message dired format-spec rfc822 mml mml-sec password-cache epg
gnus-util mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047
rfc2045 ietf-drums mm-util help-fns mail-prsvr mailabbrev mail-utils
gmm-utils mailheader rsw-evernote epic htmlize cl add-log
exec-path-from-shell finder-inf eieio-core cl-macs kotl-loaddefs
pydoc-info advice info-look info package epg-config seq byte-opt gv
bytecomp byte-compile cl-extra help-mode cconv mb-depth edebug easymenu
cl-loaddefs pcase cl-lib time-date mule-util tooltip eldoc electric
uniquify ediff-hook vc-hooks lisp-float-type mwheel ns-win ucs-normalize
term/common-win tool-bar dnd fontset image regexp-opt fringe
tabulated-list newcomment elisp-mode lisp-mode prog-mode register page
menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock font-lock
syntax facemenu font-core frame cl-generic cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese charscript case-table epa-hook jka-cmpr-hook help
simple abbrev minibuffer cl-preloaded nadvice loaddefs button faces
cus-face macroexp files text-properties overlay sha1 md5 base64 format
env code-pages mule custom widget hashtable-print-readable backquote
kqueue cocoa ns multi-tty make-network-process emacs)

Memory information:
((conses 16 1208296 206512)
 (symbols 48 87755 1)
 (miscs 40 9963 6750)
 (strings 32 234897 19520)
 (string-bytes 1 7230712)
 (vectors 16 99432)
 (vector-slots 8 2323157 242912)
 (floats 8 1648 1850)
 (intervals 56 53652 6347)
 (buffers 976 433))
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 30 Sep 2017 21:58:02 GMT) Full text and rfc822 format available.

Message #8 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 28620 <at> debbugs.gnu.org
Subject: Re: bug#28621: Proposed patch for doc of posn-window and code of
 posn-set-point to handle frame arguments
Date: Sat, 30 Sep 2017 17:56:47 -0400
[Message part 1 (text/plain, inline)]
On Sat, Sep 30, 2017 at 1:12 PM, martin rudalics <rudalics <at> gmx.at> wrote:

> > This speaks to my point in my most recent prior message, "If we just had
> a
> > way to get a window from a set of coordinates within a frame, then I
> think
> > this would help solve a lot of this."  If the event-end of Emacs mouse
> drag
> > events included a window, rather than a frame, when the endpoint of the
> > drag is at a position unique to a window (considering Z-frame order), I
> > think that would solve all these issues and simplify parts of the posn
> code.
>

​The issue, to recap, is that I can't find a function that
will report the window that a mouse release button event
occurs in if the depress and release are in different frames
(for Emacs 25).

In fact, the release event (drag event) contains the wrong
frame (that of the depress rather than the release).  The wrong
frame is also reported by mouse-position and mouse-pixel-position,
so window-at can't be used either.

The problem seems to be documented in the Emacs event design.
Frame selection events are deferred when they occur while a button
is depressed to prevent some kind of state inconsistency.  But as
a result, the drag release event records the wrong frame and there
is no way for the release binding to determine and record the right
one.


> Take the position of the event-end (if it's a frame) and translate it
> into absolute screen coordinates (the Elisp manual should give you
> enough clues to do that).  Or, try ‘mouse-absolute-pixel-position’ - it
> should give you the screen position of the mouse at that time so you can
> ignore the event completely.
>
> Then walk all your windows and compare that position with whatever
> ‘window-absolute-pixel-edges’ returns for that window.  If you have two
> or more positives, run ‘frame-list-z-order’ and compare the result
> against those windows' frames.  No hands, IMHO.


​frame-list-z-order is Emacs 26 only; I need something that works with
older versions.​

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 30 Sep 2017 23:36:02 GMT) Full text and rfc822 format available.

Message #11 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 28620 <at> debbugs.gnu.org
Subject: Re: bug#28621: Proposed patch for doc of posn-window and code of
 posn-set-point to handle frame arguments
Date: Sat, 30 Sep 2017 19:34:52 -0400
[Message part 1 (text/plain, inline)]
On Sat, Sep 30, 2017 at 5:56 PM, Robert Weiner <rsw <at> gnu.org> wrote:

> In fact, the release event (drag event) contains the wrong
> frame (that of the depress rather than the release).
>

​In looking at how mouse-1 is able to select the proper window of a mouse
click,
I found that the release binding of mouse-1 changes when a click is in a
frame
other than the selected one.  In that case, it shifts from mouse-set-point
to
handle-switch-frame which selects the new frame.  Is this shift due to the
transient-map
map setting in mouse-drag-track?

Eli, if you could point me to where the switch-frame event is generated
when the click
is in another frame, with that I might be able to produce a temporary fix
for this problem.

It would also help if in handle-switch-frame, the handle-focus-in hook
invocation occurred
after the call to do_switch_frame rather than before; then we could grab
the value of the
newly selected frame rather than the old one.

Bob


tBut I can't find anywhere in
the Emacs 25 code where mouse-1 is bound to handle-switch-frame.

Can you point me to where this is coded?  Is the keymap in use changing?
Is there any way to capture a switch-frame event and attach my own handler
to
it?  (I guess I could redefine the primitive handle-switch-fraem
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 03 Oct 2017 18:23:02 GMT) Full text and rfc822 format available.

Message #14 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: 28620 <at> debbugs.gnu.org
Cc: Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Tue, 3 Oct 2017 14:21:43 -0400
[Message part 1 (text/plain, inline)]
Using the latest Emacs26 built from master on MacOS Sierra using the macOS
window system, I see the following if I have two frames: f1 and f2.

I start with the mouse within a window of f1 and selected frame of f1;
(mouse-position) also reports f1.

I click mouse-1 in an Emacs window of f2 and leave it there.
  (selected-frame) is now f2
  macOS window manager highlights f2 as active window
  (frame-focus) returns nil
  (mouse-position) reports a frame of f1       <<< WRONG


I click mouse-1 again in the same Emacs window of f2.
  (selected-frame) is still f2
  macOS window manager highlights f2 as active window
  (frame-focus) returns nil
  (mouse-position) now reports a frame of f2

This happens consistently in testing.  This must be a bug in mouse-position
for macOS, right?  Why would (mouse-position) still report f1 when f2 is
the selected frame?  Maybe this is why I am seeing the wrong frame on drag
releases too.

If anyone else could confirm this and whether it happens on other window
systems that use a mouse click to select windows, that would be helpful.

Bob

​​
​​
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 03 Oct 2017 18:44:01 GMT) Full text and rfc822 format available.

Message #17 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: rswgnu <at> gmail.com
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Tue, 03 Oct 2017 21:42:53 +0300
> From: Robert Weiner <rsw <at> gnu.org>
> Date: Tue, 3 Oct 2017 14:21:43 -0400
> Cc: Eli Zaretskii <eliz <at> gnu.org>
> 
> I start with the mouse within a window of f1 and selected frame of f1; (mouse-position) also reports f1.
> 
> I click mouse-1 in an Emacs window of f2 and leave it there.
> (selected-frame) is now f2
> macOS window manager highlights f2 as active window
> (frame-focus) returns nil
> (mouse-position) reports a frame of f1 <<< WRONG

Sounds like something that's macOS specific.  At least on MS-Windows I
cannot reproduce this: mouse-position returns the correct frame.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 03 Oct 2017 18:54:01 GMT) Full text and rfc822 format available.

Message #20 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Tue, 3 Oct 2017 14:53:07 -0400
[Message part 1 (text/plain, inline)]
On Tue, Oct 3, 2017 at 2:42 PM, Eli Zaretskii <eliz <at> gnu.org> wrote:

> > From: Robert Weiner <rsw <at> gnu.org>
> > Date: Tue, 3 Oct 2017 14:21:43 -0400
> > Cc: Eli Zaretskii <eliz <at> gnu.org>
> >
> > I start with the mouse within a window of f1 and selected frame of f1;
> (mouse-position) also reports f1.
> >
> > I click mouse-1 in an Emacs window of f2 and leave it there.
> > (selected-frame) is now f2
> > macOS window manager highlights f2 as active window
> > (frame-focus) returns nil
> > (mouse-position) reports a frame of f1 <<< WRONG
>
> Sounds like something that's macOS specific.  At least on MS-Windows I
> cannot reproduce this: mouse-position returns the correct frame.
>

​Ok, that is good to know.  Is there a go to person for the Mac-specific
windowing code to check on this with?

Could someone check when running X with a click-for-focus window manager
setting and see what happens there?

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 03 Oct 2017 20:56:02 GMT) Full text and rfc822 format available.

Message #23 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: 28620 <at> debbugs.gnu.org
Cc: Eli Zaretskii <eliz <at> gnu.org>
Subject: (mouse-position_ wrong on macOS after mouse-1 click (Was: Interact
 directly on Emacs bug#28620: mouse drag event records wrong release window)
Date: Tue, 3 Oct 2017 16:54:22 -0400
[Message part 1 (text/plain, inline)]
Interestingly, mouse wheel scroll events work properly.  Such events always
include the window the mouse is over (when mouse-wheel-follow-mouse is t,
which it is by default).  They select this window and then scroll that
window, so I can move the mouse across frames and scroll arbitrary windows,
which suggests that drag events should operate similarly and include the
window of the drag release.

Now to find out how the position of the mouse is used differently in mouse
drags compared to mouse wheel events.

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 03 Oct 2017 22:41:02 GMT) Full text and rfc822 format available.

Message #26 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: rswgnu <at> gmail.com
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag
 event records wrong release window
Date: Tue, 3 Oct 2017 23:40:17 +0100
On Tue, Oct 03, 2017 at 02:21:43PM -0400, Robert Weiner wrote:
> This happens consistently in testing.  This must be a bug in mouse-position
> for macOS, right?  Why would (mouse-position) still report f1 when f2 is
> the selected frame?  Maybe this is why I am seeing the wrong frame on drag
> releases too.

As far as I can tell ns_mouse_position returns the frame stored in
dpyinfo->last_mouse_frame, which is set by EmacsView::mouseDown, however:

    If the user clicks a view that isn’t in the key window, by default
    the window is brought forward and made key, but the mouse event is
    not dispatched.

        https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html

My guess is that ns_mouse_position needs to get a list of NSWindows,
iterate over them to find out which one the mouse pointer is over,
convert that NSWindow back to an Emacs frame, and set *fp to it before
returning.

That way it should return the frame the mouse is over, rather than the
last one that received a click event.

I’m not sure what happens if the mouse isn’t over an emacs frame...
Does it just return *fp unchanged?
-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 00:17:01 GMT) Full text and rfc822 format available.

Message #29 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Alan Third <alan <at> idiocy.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Tue, 3 Oct 2017 20:15:53 -0400
[Message part 1 (text/plain, inline)]
On Tue, Oct 3, 2017 at 6:40 PM, Alan Third <alan <at> idiocy.org> wrote:

> On Tue, Oct 03, 2017 at 02:21:43PM -0400, Robert Weiner wrote:
> > This happens consistently in testing.  This must be a bug in
> mouse-position
> > for macOS, right?  Why would (mouse-position) still report f1 when f2 is
> > the selected frame?  Maybe this is why I am seeing the wrong frame on
> drag
> > releases too.
>
> As far as I can tell ns_mouse_position returns the frame stored in
> dpyinfo->last_mouse_frame, which is set by EmacsView::mouseDown, however:
>
>     If the user clicks a view that isn’t in the key window, by default
>     the window is brought forward and made key, but the mouse event is
>     not dispatched.
>

​What does "the mouse event is not dispatched mean"?  Does it mean Emacs
never sees the event?  Maybe Emacs sees only that the window has been
selected by the window manager and based on that switches to the selected
window of the frame?

> ​​
>
> ​​
>         https://developer.apple.com/library/content/documentation/
> Cocoa/Conceptual/EventOverview/HandlingMouseEvents/
> HandlingMouseEvents.html
> ​​
>
> ​​
> My guess is that ns_mouse_position needs to get a list of NSWindows,
> ​​
> iterate over them to find out which one the mouse pointer is over,
> ​​
> convert that NSWindow back to an Emacs frame, and set *fp to it before
> ​​
> returning.
>

​The mouse wheel code manages to scroll the proper window that the mouse is
over, even across overlapping frames where the window the mouse is over is
in a frame that is partially behind another frame.  And this happens
without without any click events.  This could be utilized in the click
event code to get this right somehow.

It looks like the EV_TRAILER macro call at the end of the nsterm.c
mouseDown function (which is also called by mouseUp) sets the frame used
for mouse button down, up and scroll wheel events from the variable
emacsframe.  Somehow the value of emacsframe must be set differently for
mouse up events than it is for mouse wheel events since they end up with
different frames for the same mouse positions.

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 16:31:02 GMT) Full text and rfc822 format available.

Message #32 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: rswgnu <at> gmail.com
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag
 event records wrong release window
Date: Wed, 4 Oct 2017 17:30:48 +0100
On Tue, Oct 03, 2017 at 08:15:53PM -0400, Robert Weiner wrote:
> On Tue, Oct 3, 2017 at 6:40 PM, Alan Third <alan <at> idiocy.org> wrote:
> > As far as I can tell ns_mouse_position returns the frame stored in
> > dpyinfo->last_mouse_frame, which is set by EmacsView::mouseDown, however:
> >
> >     If the user clicks a view that isn’t in the key window, by default
> >     the window is brought forward and made key, but the mouse event is
> >     not dispatched.
> >
> 
> ​What does "the mouse event is not dispatched mean"?  Does it mean Emacs
> never sees the event?  Maybe Emacs sees only that the window has been
> selected by the window manager and based on that switches to the selected
> window of the frame?

Precisely that.

> ​The mouse wheel code manages to scroll the proper window that the mouse is
> over, even across overlapping frames where the window the mouse is over is
> in a frame that is partially behind another frame.  And this happens
> without without any click events.  This could be utilized in the click
> event code to get this right somehow.

The mouse wheel code is also handled in mouseDown, the difference is
that macOS always sends the mouse wheel event to the emacs frame under
the mouse pointer, whereas the mouse click event is not sent when the
frame is not already key (i.e. selected).

AFAICT Emacs does the right thing here, exactly the same thing as
every other macOS app.

> It looks like the EV_TRAILER macro call at the end of the nsterm.c
> mouseDown function (which is also called by mouseUp) sets the frame used
> for mouse button down, up and scroll wheel events from the variable
> emacsframe.  Somehow the value of emacsframe must be set differently for
> mouse up events than it is for mouse wheel events since they end up with
> different frames for the same mouse positions.

There’s nothing fancy here, emacsframe is an instance variable
associated with the EmacsView that macOS sends the mouse event to.

-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 17:27:02 GMT) Full text and rfc822 format available.

Message #35 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Alan Third <alan <at> idiocy.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Wed, 4 Oct 2017 13:26:18 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 4, 2017 at 12:30 PM, Alan Third <alan <at> idiocy.org> wrote:

> On Tue, Oct 03, 2017 at 08:15:53PM -0400, Robert Weiner wrote:
> > On Tue, Oct 3, 2017 at 6:40 PM, Alan Third <alan <at> idiocy.org> wrote:
> > > As far as I can tell ns_mouse_position returns the frame stored in
> > > dpyinfo->last_mouse_frame, which is set by EmacsView::mouseDown,
> however:
> > >
> > >     If the user clicks a view that isn’t in the key window, by default
> > >     the window is brought forward and made key, but the mouse event is
> > >     not dispatched.
> > >
> >
> > ​What does "the mouse event is not dispatched mean"?  Does it mean Emacs
> > never sees the event?  Maybe Emacs sees only that the window has been
> > selected by the window manager and based on that switches to the selected
> > window of the frame?
>
> Precisely that.
>

​So how is it that Emacs processes a drag event when the mouse button is
released in the new frame if it never sees the mouseUp (drag release)
event?​  If I drag across frames, on mouseUp, the key binding associated
with mouseUp (mouse-1 as opposed to down-mouse-1 is run).

​​
>
> > ​The mouse wheel code manages to scroll the proper window that the mouse
> is
> > over, even across overlapping frames where the window the mouse is over
> is
> > in a frame that is partially behind another frame.  And this happens
> > without without any click events.  This could be utilized in the click
> > event code to get this right somehow.
>
> The mouse wheel code is also handled in mouseDown, the difference is
> that macOS always sends the mouse wheel event to the emacs frame under
> the mouse pointer, whereas the mouse click event is not sent when the
> frame is not already key (i.e. selected).
>

​Can you show some sample code that would make macOS send the mouse drag
release event to the frame under the mouse pointer just as the scroll wheel
code does.  I have looked at this mouseUp code in nsterm.m but cannot get
it to do this.  I have managed to inject a focus in event to the mouseUp​
function and make its event frame the key frame (selected frame) but its
event frame is the wrong one (it always has the frame of the mouseDown
event).

​​
>
> ​​
> AFAICT Emacs does the right thing here, exactly the same thing as
> ​​
> every other macOS app.
> ​​
>
> ​​
​As Eli noted, this does not happen under MS Windows.  I want to have
behavior that allows for drags across frames.  The present code does not,
so whether it is consistent with Mac UI guidelines, it is not useful for
that purpose.  I would like your help in figuring out how to enable such
behavior as you seem to understand the macOS event flow well.
​​​

> ​​
>
> ​​
> > It looks like the EV_TRAILER macro call at the end of the nsterm.c
> ​​
> > mouseDown function (which is also called by mouseUp) sets the frame used
> ​​
> > for mouse button down, up and scroll wheel events from the variable
> ​​
> > emacsframe.  Somehow the value of emacsframe must be set differently for
> ​​
> > mouse up events than it is for mouse wheel events since they end up with
> ​​
> > different frames for the same mouse positions.
>
​​


> ​​
> There’s nothing fancy here, emacsframe is an instance variable
> ​​
> associated with the EmacsView that macOS sends the mouse event to.


​So show me how and where I could set that variable to the frame of the
mouse position at the point of mouseUp​ and I will test it and let people
know if it works.

Thanks,

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 19:00:02 GMT) Full text and rfc822 format available.

Message #38 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: rswgnu <at> gmail.com
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag
 event records wrong release window
Date: Wed, 4 Oct 2017 19:59:00 +0100
On Wed, Oct 04, 2017 at 01:26:18PM -0400, Robert Weiner wrote:
> On Wed, Oct 4, 2017 at 12:30 PM, Alan Third <alan <at> idiocy.org> wrote:
> 
> > On Tue, Oct 03, 2017 at 08:15:53PM -0400, Robert Weiner wrote:
> > > On Tue, Oct 3, 2017 at 6:40 PM, Alan Third <alan <at> idiocy.org> wrote:
> > > > As far as I can tell ns_mouse_position returns the frame stored in
> > > > dpyinfo->last_mouse_frame, which is set by EmacsView::mouseDown,
> > however:
> > > >
> > > >     If the user clicks a view that isn’t in the key window, by default
> > > >     the window is brought forward and made key, but the mouse event is
> > > >     not dispatched.
> > > >
> > >
> > > ​What does "the mouse event is not dispatched mean"?  Does it mean Emacs
> > > never sees the event?  Maybe Emacs sees only that the window has been
> > > selected by the window manager and based on that switches to the selected
> > > window of the frame?
> >
> > Precisely that.
> >
> 
> ​So how is it that Emacs processes a drag event when the mouse button is
> released in the new frame if it never sees the mouseUp (drag release)
> event?​  If I drag across frames, on mouseUp, the key binding associated
> with mouseUp (mouse-1 as opposed to down-mouse-1 is run).

The NSEvent is delivered to the EmacsView belonging to the frame where
the drag was initiated. I don’t think there’s anything we can do to
change that.

> > The mouse wheel code is also handled in mouseDown, the difference is
> > that macOS always sends the mouse wheel event to the emacs frame under
> > the mouse pointer, whereas the mouse click event is not sent when the
> > frame is not already key (i.e. selected).
> >
> 
> ​Can you show some sample code that would make macOS send the mouse drag
> release event to the frame under the mouse pointer just as the scroll wheel
> code does.  I have looked at this mouseUp code in nsterm.m but cannot get
> it to do this.  I have managed to inject a focus in event to the mouseUp​
> function and make its event frame the key frame (selected frame) but its
> event frame is the wrong one (it always has the frame of the mouseDown
> event).

I don’t believe it’s possible. As I described before we’d have to do
something like:

    [...] get a list of NSWindows, iterate over them to find out which
    one the mouse pointer is over, convert that NSWindow back to an Emacs
    frame, and [return it].

> > AFAICT Emacs does the right thing here, exactly the same thing as
> > every other macOS app.
> >
> ​As Eli noted, this does not happen under MS Windows.  I want to have
> behavior that allows for drags across frames.  The present code does not,
> so whether it is consistent with Mac UI guidelines, it is not useful for
> that purpose.  I would like your help in figuring out how to enable such
> behavior as you seem to understand the macOS event flow well.

But which behaviour? I can’t work out exactly what we’re talking about
here. Are you trying to get cross‐frame dragging working or are you
genuinely concerned that Emacs doesn’t receive a click event when the
frame is selected using the mouse? These seem like two different
things to me.

> > There’s nothing fancy here, emacsframe is an instance variable
> > associated with the EmacsView that macOS sends the mouse event to.
> 
> 
> ​So show me how and where I could set that variable to the frame of the
> mouse position at the point of mouseUp​ and I will test it and let people
> know if it works.

Fns_frame_list_z_order in nsfns.m does some of what’s described
above... But...

It looks like there’s maybe a neater way to get the current frame
under the mouse...

    Lisp_Object frame = Qnil;
    NSWindow *w = [NSApp windowWithWindowNumber:
                         [NSWindow windowNumberAtPoint:[NSEvent mouseLocation]
                           belowWindowWithWindowNumber:0]];
    if (w != nil)
      XSETFRAME (frame, ((EmacsView *)[w delegate])->emacsframe);

I’ve not tested this, so it may not work at all. Note that [NSEvent
mouseLocation] returns an NSPoint indicating where the mouse is *right
now*. It would probably be more sensible to use any co‐ordinates
provided by the event itself.
-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 19:32:01 GMT) Full text and rfc822 format available.

Message #41 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Alan Third <alan <at> idiocy.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Wed, 4 Oct 2017 15:30:45 -0400
[Message part 1 (text/plain, inline)]
Hi Alan:

Thanks for your thoughts on this.

On Wed, Oct 4, 2017 at 2:59 PM, Alan Third <alan <at> idiocy.org> wrote:

> On Wed, Oct 04, 2017 at 01:26:18PM -0400, Robert Weiner wrote:
>
> > ​So how is it that Emacs processes a drag event when the mouse button is
> > released in the new frame if it never sees the mouseUp (drag release)
> > event?​  If I drag across frames, on mouseUp, the key binding associated
> > with mouseUp (mouse-1 as opposed to down-mouse-1 is run).
>
> The NSEvent is delivered to the EmacsView belonging to the frame where
> the drag was initiated. I don’t think there’s anything we can do to
> change that.
>

​So you are saying that only one NSEvent is delivered to Emacs for both the
press and release of a drag that crosses frames?
And that Emacs internally internally recognizes both the press and release
of the mouse button and fires their respective key bindings but they both
share the location from that one NSEvent?

If so, why can't the nsterm.m mouseUp (release) handler synthesize an
NSEvent based on the current mouse position that is run prior to invoking
the keybinding for mouseUp?

​​
>
> ​​
> > > The mouse wheel code is also handled in
> ​​
> mouseDown, the difference is
> ​​
> > > that macOS always sends the mouse whe
> ​​
> el event to the emacs frame under
> ​​
> > > the mouse pointer, whereas the mouse cli
> ​​
> ck event is not sent when the
> ​​
> > > frame is not already key (i.e. selected).
> ​​
>
> ​​
​Ok, I understand that now.​
​​​

> ​
> > ​Can you show some sample code that would make macOS send the mouse drag
> ​​
> > release event to the frame under the mouse pointer just as the scroll
> wheel
> ​​
> >
> ​​
> ​​
> c
> ​​
> o
> ​​
> d
> ​​
> e
> ​​
> ​​
> d
> ​​
> o
> ​​
> e
> ​​
> s
> ​​
> .
> ​
>
> ​​
>
> ​​
> I don’t believe it’s possible. As I described before we’d have to do
> ​​
> something like:
> ​​
>
> ​​
>     [...] get a list of NSWindows, iterate over them to find out which
> ​​
>     one the mouse pointer is over, convert that NSWindow back to an Emacs
> ​​
>     frame, and [return it].
> ​​
>
> ​​
> > > AFAICT Emacs does the right thing here, exactly the same thing as
> ​​
> > > every other macOS app.
> ​​
> > >
> ​​
> > ​As Eli noted, this does not happen under MS Windows.


​I just tested under MS Windows 7 with Emacs 25 and saw the same behavior
as on the Mac (mouse-1 drag between frames yields a release event with the
depress frame rather than the release frame).  I'll have to talk to Eli
about this.
​

> ​​
>   I want to have
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
>
> ​​
> > behavior that allows for drags across frames.  The present code does not,
> ​​
>
> ​​
> > so whether it is consistent with Mac UI guidelines, it is not useful for
> ​​
>
> ​​
> > that purpose.  I would like your help in figuring out how to enable su
> ​​
> ch
> ​​
> > behavior as you seem to understand the macOS event flow well.
> ​​
>
> ​​
>
> ​​
> But which behaviour? I can’t work out exactly what we’re talking ab
> ​​
> out
> ​​
> here. Are you trying to get cross‐frame dragging working


​Yes.​

​​
> or
> ​​
> are you
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
>
> ​​
> genuinely concerned that Emacs doesn’t receive a click event when the
> ​​
> frame is selected using the mouse? These seem like two different
> ​​
> things to me.
>

​I want to work around that if possible.  The fact that Emacs can dispatch
on the mouseUp​ event tells me that we just need to determine the proper
window of mouse position at that point and use that instead of the frame
the Mac window system provides.

> ​​
>
> ​​
> > > There’s nothing fancy here, emacsframe is an instance variable
> ​​
>
> ​​
> > > associated with the EmacsView that macOS sends the mouse
> ​​
> event to.
> ​​
> >
> ​​
>
> ​​
> >
> ​​
>
> ​​
> >
> ​​
> ​So show me how and where I could set that variable to the frame of the
> ​​
> >
> ​​
> mouse position at the point of mouseUp​ and I will test it and let people
> ​​
> >
> ​​
> know if it works.
> ​​
>
> F
> ​​
> ns_frame_list_z_order in nsfns.m does some of what’s described
> a
> ​​
> bove... But...
> ​​
>
> ​​
> It looks like there’s maybe a neater way to get the current frame
> ​​
> under the mouse...
> ​​
>
> ​​
>     Lisp_Object frame = Qnil;
> ​​
>     NSWindow *w = [NSApp windowWithWindowNumber:
> ​​
>                          [NSWindow windowNumberAtPoint:[NSEvent
> mouseLocation]
> ​​
>                            belowWindowWithWindowNumber:0]];
> ​​
>     if (w != nil)
> ​​
>       XSETFRAME (frame, ((EmacsView *)[w delegate])->emacsframe);
> ​​
>
> ​​
> I’ve not tested this, so it may not work at all. Note that [NSEvent
> ​​
> mouseLocation] returns an NSPoint indicating where the mouse is *right
> ​​
> now*. It would probably be more sensible to use any co‐ordinates
> ​​
> provided by the event itself.
>

If the coordinates represent the location of the mouseUp event rather than
mouseDown (of which I'm not sure), then why couldn't the frame differ as
well when we have the right functionality together?  Let me see if I can
test with mouseLocation first.

I would suggest that the (mouse-position) function should always return the
uppermost Z-ordered frame at point, even though it fails to do that now.

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 20:09:02 GMT) Full text and rfc822 format available.

Message #44 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Alan Third <alan <at> idiocy.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Wed, 4 Oct 2017 16:07:56 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 4, 2017 at 2:59 PM, Alan Third <alan <at> idiocy.org> wrote:

>
> It looks like there’s maybe a neater way to get the current frame
> under the mouse...
>
>     Lisp_Object frame = Qnil;
>     NSWindow *w = [NSApp windowWithWindowNumber:
>                          [NSWindow windowNumberAtPoint:[NSEvent
> mouseLocation]
>                            belowWindowWithWindowNumber:0]];
>     if (w != nil)
>       XSETFRAME (frame, ((EmacsView *)[w delegate])->emacsframe);
>
>
The ​mouseDown​ function (called by the various mouseUp functions) uses
`emacsframe' to set the appropriate frame.
How does the above modify emacsframe?  Doesn't XSETFRAME just set the value
of the local `frame'?

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 20:13:02 GMT) Full text and rfc822 format available.

Message #47 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Alan Third <alan <at> idiocy.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Wed, 4 Oct 2017 16:11:44 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 4, 2017 at 3:30 PM, Robert Weiner <rsw <at> gnu.org> wrote:

> Hi Alan:
>
>>
>> ​​
>> It looks like there’s maybe a neater way to get the current frame
>> ​​
>> under the mouse...
>> ​​
>>
>> ​​
>>     Lisp_Object frame = Qnil;
>> ​​
>>     NSWindow *w = [NSApp windowWithWindowNumber:
>> ​​
>>                          [NSWindow windowNumberAtPoint:[NSEvent
>> mouseLocation]
>> ​​
>>                            belowWindowWithWindowNumber:0]];
>> ​​
>>     if (w != nil)
>> ​​
>>       XSETFRAME (frame, ((EmacsView *)[w delegate])->emacsframe);
>>
>
​As is, this didn't seem to have any effect.

Bob
​
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 04 Oct 2017 22:10:02 GMT) Full text and rfc822 format available.

Message #50 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: rswgnu <at> gmail.com
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag
 event records wrong release window
Date: Wed, 4 Oct 2017 23:09:01 +0100
On Wed, Oct 04, 2017 at 04:07:56PM -0400, Robert Weiner wrote:
> On Wed, Oct 4, 2017 at 2:59 PM, Alan Third <alan <at> idiocy.org> wrote:
> 
> >
> > It looks like there’s maybe a neater way to get the current frame
> > under the mouse...
> >
> >     Lisp_Object frame = Qnil;
> >     NSWindow *w = [NSApp windowWithWindowNumber:
> >                          [NSWindow windowNumberAtPoint:[NSEvent
> > mouseLocation]
> >                            belowWindowWithWindowNumber:0]];
> >     if (w != nil)
> >       XSETFRAME (frame, ((EmacsView *)[w delegate])->emacsframe);
> >
> >
> The ​mouseDown​ function (called by the various mouseUp functions) uses
> `emacsframe' to set the appropriate frame.
> How does the above modify emacsframe?  Doesn't XSETFRAME just set the value
> of the local `frame'?

Yes. You can’t modify emacsframe because it’s an instance variable.
You’ll need to modify whatever is using it to set the frame in the
emacs event.

So, assuming the code you’re modifying is calling EV_TRAILER, for now,
replace the call to EV_TRAILER with it’s contents:

    XSETFRAME (emacs_event->frame_or_window, emacsframe);
    EV_TRAILER2 (e);

and work from there.

-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Thu, 05 Oct 2017 00:40:01 GMT) Full text and rfc822 format available.

Message #53 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Alan Third <alan <at> idiocy.org>
Cc: 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Wed, 4 Oct 2017 20:38:38 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 4, 2017 at 6:09 PM, Alan Third <alan <at> idiocy.org> wrote:

>
> Yes. You can’t modify emacsframe because it’s an instance variable.
> You’ll need to modify whatever is using it to set the frame in the
> emacs event.
>
> So, assuming the code you’re modifying is calling EV_TRAILER, for now,
> replace the call to EV_TRAILER with it’s contents:
>
>     XSETFRAME (emacs_event->frame_or_window, emacsframe);
>     EV_TRAILER2 (e);
>
> and work from there.
>

​Still doesn't seem to work if that code is used at the end of mouseDown
(called by mouseUp).
Could you test any of your ideas?  It would probably speed the process up
if you have a bit of time.

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Wed, 11 Oct 2017 18:51:01 GMT) Full text and rfc822 format available.

Message #56 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>, martin rudalics <rudalics <at> gmx.at>,
 Alan Third <alan <at> idiocy.org>, 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Wed, 11 Oct 2017 14:49:45 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 11, 2017 at 1:16 PM, Robert Weiner <rsw <at> gnu.org> wrote:

>
> ​Martin wrote:​
>
>> Take the position of the event-end (if it's a frame) and translate it
>> into absolute screen coordinates (the Elisp manual should give you
>> enough clues to do that).  Or, try ‘mouse-absolute-pixel-position’ - it
>> should give you the screen position of the mouse at that time so you can
>> ignore the event completely.
>>
>> Then walk all your windows and compare that position with whatever
>> ‘window-absolute-pixel-edges’ returns for that window.  If you have two
>> or more positives, run ‘frame-list-z-order’ and compare the result
>> against those windows' frames.  No hands, IMHO.
>> ​​
>>
> ​​

​  Eli wrote:
    ​​
Why cannot you compute the frame at button release using the a
​​
lgorithm
         proposed by Martin, given the mouse position at button release?​


>
>> ​​
>>
> I w
> ​​
> rote:
>   ​
> ​​
> frame-list-z-order is Emacs 26 only; I need something that works with
> older versions.​
> ​​
> ​​
> I'll see if I can make this work under Emacs 26 and then we can
> contemplate a solution that would apply to earlier versions.
> ​​
> Thanks for the reminder.  It does still seem to me that there should be a
> function that takes a mouse position and returns
> ​​
> the top-most Emacs window that the position is in or nil.  I'll work on it.
>
​​
​​​And now there is such a function.  It was easier than I expected thanks
to Martin's pointers.  Now how can we make this work (replacing
frame-list-z-order) for Emacs versions prior to 26?  -- Bob

(defun window-at-absolute-pixel-position (&optional position)
  "Return the top-most Emacs window at optional POSITION ((X . Y) in
pixels) or mouse position.
If POSITION is not in a window, return nil.  Considers all windows on the
the same terminal
display as the selected frame."
  (interactive)
  (setq position (or position (mouse-absolute-pixel-position)))
  (let* ((top-to-bottom-frames (frame-list-z-order))
(pos-x (car position))
(pos-y (cdr position))
edges left top right bottom
frame
in-frame
window)
    ;; First find top-most frame containing position.
    (while (and (not in-frame) top-to-bottom-frames)
      (setq frame (car top-to-bottom-frames)
    top-to-bottom-frames (cdr top-to-bottom-frames))
      ;; Check that in-frame is valid with frame-live-p since under macOS
      ;; when position is outside a frame, in-frame could be invalid and
      ;; frame-visible-p would trigger an error in that case.
      (when (and (frame-live-p frame) (frame-visible-p frame))
(setq edges (frame-edges frame)
      left   (nth 0 edges)
      top    (nth 1 edges)
      right  (nth 2 edges)
      bottom (nth 3 edges))
(when (and (>= pos-x left) (<= pos-x right)
   (>= pos-y top)  (<= pos-y bottom))
  (setq in-frame frame))))
    ;; If in-frame is found, find which of its windows contains
    ;; position and return that.  The window-at call below requires
    ;; character coordinates relative to in-frame, so compute them.
    (setq pos-x (/ (- pos-x left) (frame-char-width in-frame))
  pos-y (/ (- pos-y top) (frame-char-height in-frame))
  window (window-at pos-x pos-y in-frame))
    (if (called-interactively-p 'interactive)
  (message "%s at absolute pixel position %s"
   (or window "No Emacs window") position))
    window))
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Thu, 12 Oct 2017 01:36:02 GMT) Full text and rfc822 format available.

Message #59 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>, martin rudalics <rudalics <at> gmx.at>,
 Alan Third <alan <at> idiocy.org>, 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Wed, 11 Oct 2017 21:35:13 -0400
[Message part 1 (text/plain, inline)]
I now have drags working across frames (after manipulating the drag button
release event data to include the proper window and coordinates, though
only in Lisp right now).  As shown in the last message, I also have a
function that finds the proper Emacs window given some display
coordinates.  The only remaining problem seems to be that none of this
accounts for external application windows that may be obscuring an Emacs
frame.

So if I have 2 frames, f1 and f2, and a Chrome web browser window that is
atop f2, then if I drag from f1 into Chrome above f2, my drag release code
reports that the release window is in f2 rather than nil, as it should be.
I am on macOS which uses click to focus, so Emacs still gets the release
event since Chrome has not been selected with a click.

Is there any way to deal with external window z-order layering such that
one can tell within Emacs whether the topmost OS-level window at an
absolute mouse position is an Emacs frame or not?

Thanks,

Bob


On Wed, Oct 11, 2017 at 2:49 PM, Robert Weiner <rsw <at> gnu.org> wrote:

> On Wed, Oct 11, 2017 at 1:16 PM, Robert Weiner <rsw <at> gnu.org> wrote:
>
>>
>> ​Martin wrote:​
>>
>>> Take the position of the event-end (if it's a frame) and translate it
>>> into absolute screen coordinates (the Elisp manual should give you
>>> enough clues to do that).  Or, try ‘mouse-absolute-pixel-position’ - it
>>> should give you the screen position of the mouse at that time so you can
>>> ignore the event completely.
>>>
>>> Then walk all your windows and compare that position with whatever
>>> ‘window-absolute-pixel-edges’ returns for that window.  If you have two
>>> or more positives, run ‘frame-list-z-order’ and compare the result
>>> against those windows' frames.  No hands, IMHO.
>>> ​​
>>>
>> ​​
>
> ​  Eli wrote:
>     ​​
> Why cannot you compute the frame at button release using the a
> ​​
> lgorithm
>          proposed by Martin, given the mouse position at button release?​
>
>
>>
>>> ​​
>>>
>> I w
>> ​​
>> rote:
>>   ​
>> ​​
>> frame-list-z-order is Emacs 26 only; I need something that works with
>> older versions.​
>> ​​
>> ​​
>> I'll see if I can make this work under Emacs 26 and then we can
>> contemplate a solution that would apply to earlier versions.
>> ​​
>> Thanks for the reminder.  It does still seem to me that there should be a
>> function that takes a mouse position and returns
>> ​​
>> the top-most Emacs window that the position is in or nil.  I'll work on
>> it.
>>
> ​​
> ​​​And now there is such a function.  It was easier than I expected thanks
> to Martin's pointers.  Now how can we make this work (replacing
> frame-list-z-order) for Emacs versions prior to 26?  -- Bob
>
> (defun window-at-absolute-pixel-position (&optional position)
>   "Return the top-most Emacs window at optional POSITION ((X . Y) in
> pixels) or mouse position.
> If POSITION is not in a window, return nil.  Considers all windows on the
> the same terminal
> display as the selected frame."
>   (interactive)
>   (setq position (or position (mouse-absolute-pixel-position)))
>   (let* ((top-to-bottom-frames (frame-list-z-order))
> (pos-x (car position))
> (pos-y (cdr position))
> edges left top right bottom
> frame
> in-frame
> window)
>     ;; First find top-most frame containing position.
>     (while (and (not in-frame) top-to-bottom-frames)
>       (setq frame (car top-to-bottom-frames)
>     top-to-bottom-frames (cdr top-to-bottom-frames))
>       ;; Check that in-frame is valid with frame-live-p since under macOS
>       ;; when position is outside a frame, in-frame could be invalid and
>       ;; frame-visible-p would trigger an error in that case.
>       (when (and (frame-live-p frame) (frame-visible-p frame))
> (setq edges (frame-edges frame)
>       left   (nth 0 edges)
>       top    (nth 1 edges)
>       right  (nth 2 edges)
>       bottom (nth 3 edges))
> (when (and (>= pos-x left) (<= pos-x right)
>    (>= pos-y top)  (<= pos-y bottom))
>   (setq in-frame frame))))
>     ;; If in-frame is found, find which of its windows contains
>     ;; position and return that.  The window-at call below requires
>     ;; character coordinates relative to in-frame, so compute them.
>     (setq pos-x (/ (- pos-x left) (frame-char-width in-frame))
>   pos-y (/ (- pos-y top) (frame-char-height in-frame))
>   window (window-at pos-x pos-y in-frame))
>     (if (called-interactively-p 'interactive)
>   (message "%s at absolute pixel position %s"
>    (or window "No Emacs window") position))
>     window))
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Thu, 12 Oct 2017 01:48:02 GMT) Full text and rfc822 format available.

Message #62 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>, martin rudalics <rudalics <at> gmx.at>,
 Alan Third <alan <at> idiocy.org>, 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Wed, 11 Oct 2017 21:47:16 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 11, 2017 at 9:35 PM, Robert Weiner <rsw <at> gnu.org> wrote:

>
> Is there any way to deal with external window z-order layering such that
> one can tell within Emacs whether the topmost OS-level window at an
> absolute mouse position is an Emacs frame or not?
>

​One idea is to expand frame-list-z-order with a 2nd optional argument of
all-display-windows-flag which when non-nil would include all of the
OS-level windows in the returned list.  Maybe a new object type or
frame-variant is needed for this.  Then just add another function that
returns the edge coordinates for such windows and we could account for them
in any z-ordering computations.  What do you think?

Bob
​
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Thu, 12 Oct 2017 08:07:01 GMT) Full text and rfc822 format available.

Message #65 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com, Eli Zaretskii <eliz <at> gnu.org>, 
 Alan Third <alan <at> idiocy.org>, 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Thu, 12 Oct 2017 10:05:52 +0200
> So if I have 2 frames, f1 and f2, and a Chrome web browser window that is
> atop f2, then if I drag from f1 into Chrome above f2, my drag release code
> reports that the release window is in f2 rather than nil, as it should be.
> I am on macOS which uses click to focus, so Emacs still gets the release
> event since Chrome has not been selected with a click.

I would call this a feature: f2 is probably the one meaningful target of
your operation at that screen position.

> Is there any way to deal with external window z-order layering such that
> one can tell within Emacs whether the topmost OS-level window at an
> absolute mouse position is an Emacs frame or not?

Not really.  Compositing window managers on X no more allow to track the
visibility of windows reliably.  So while we can discern the visibility
of our own (window manager) windows based on what we store in their
asscociated frames' 'visible' slots, we can't do that for windows of
other applications.  And processing whatever else XGetWindowAttributes
returns for another application's window might not be trivial either.

It should be possible to do what you want on Windows (where the debugger
also notifies you when an Emacs frame is obscured) though.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Thu, 12 Oct 2017 13:10:02 GMT) Full text and rfc822 format available.

Message #68 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Thu, 12 Oct 2017 09:08:30 -0400
[Message part 1 (text/plain, inline)]
On Thu, Oct 12, 2017 at 4:05 AM, martin rudalics <rudalics <at> gmx.at> wrote:

> > So if I have 2 frames, f1 and f2, and a Chrome web browser window that is
> > atop f2, then if I drag from f1 into Chrome above f2, my drag release
> code
> > reports that the release window is in f2 rather than nil, as it should
> be.
> > I am on macOS which uses click to focus, so Emacs still gets the release
> > event since Chrome has not been selected with a click.
>
> I would call this a feature: f2 is probably the one meaningful target of
> your operation at that screen position.


​I think it is a feature that Emacs receives an event for this but a defect
that it can't distinguish when f2 is atop an external window or not and
thus whether the event was actually directed at f2 or not.

​​
>
> ​​
>
> ​​
> > Is there any way to deal with external window z-order layering such that
> ​​
> > one can tell within Emacs whether the topmost OS-level window at an
> ​​
> > absolute mouse position is an Emacs frame or not?
> ​​
>
> ​​
> Not really.  Compositing window managers on X no more allow to track the
> ​​
> visibility of windows reliably.  So while we can discern the visibility
> ​​
> of our own (window manager) windows based on what we store in their
> ​​
> asscociated frames' 'visible' slots, we can't do that for windows of
> ​​
> other applications.  And processing whatever else XGetWindowAttributes
> ​​
> returns for another application's window might not be trivial either.
>

​Just FYI, I am using the macOS window manager, not X, though as you note,
it is an issue there too.
The application-level window managers must have a z-ordering for all
windows in order to be able to select and raise windows when they are
behind others.  So you are saying that they don't publish this information
in any useful way that Emacs can obtain, right?

Part of the issue is that the macOS window manager uses click-to-focus, so
the release event of the drag does not switch focus to the application
whose window the release falls upon.  However, in drag-n-drop operations,
the window manager automatically switches focus to any compatible
application that the mouse moves over (after a delay) so that the right
application receives the drop (based on Z-order).

Mouse wheel events are also delivered to the topmost Z-order window without
either raising the window or switching focus.

So the window manager always knows where it should deliver at least two
kinds of events and maybe one of those types of events could be used to
help Emacs know whether a release event was over one of its frames or over
the window of an another application.

​
>
> ​​
> It should be poss
> ​​
> ​​
> ible to do what you want on Windows (where the debugger
> ​​
> also notifies you
> ​​
> when an Emacs frame is obscured) though.

​​
​​Well, one platform would be a good start.​  What would the pseudo-code
look like to check whether or not an Emacs frame was uppermost at the point
of mouse release?

Thanks,

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 14 Oct 2017 08:36:02 GMT) Full text and rfc822 format available.

Message #71 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Sat, 14 Oct 2017 10:35:33 +0200
> ​I think it is a feature that Emacs receives an event for this but a defect
> that it can't distinguish when f2 is atop an external window or not and
> thus whether the event was actually directed at f2 or not.

‘mouse-drag-region’ is an Emacs internal function, so it's no defect.
If it were not internal, Emacs would have to be either able to poll the
other window's application as to whether it supports dropping an Emacs
internal string or convert that string to some appropriate coding that
other applications understand.  Neither of these has been done yet and
it will be non-trivial to do that for our various platforms.

> ​Just FYI, I am using the macOS window manager, not X, though as you note,
> it is an issue there too.
> The application-level window managers must have a z-ordering for all
> windows in order to be able to select and raise windows when they are
> behind others.  So you are saying that they don't publish this information
> in any useful way that Emacs can obtain, right?

All I can say is that when you nowadays try to obtain information on
whether a window is really visible under X, chances are that you don't
get it.  Querying the z-order will only tell you something like "window
Y cannot obscure window X because it's lower in the z-order".

> Part of the issue is that the macOS window manager uses click-to-focus, so
> the release event of the drag does not switch focus to the application
> whose window the release falls upon.

As Stefan already mentioned earlier: With a drag operation usually no
focus shifting occurs anyway.

> However, in drag-n-drop operations,
> the window manager automatically switches focus to any compatible
> application that the mouse moves over (after a delay) so that the right
> application receives the drop (based on Z-order).

It's completely up to the window manager which polls the application(s)
whether they are ready to receive the object to drop.  Emacs is not
involved in that process.  It would be involved only to tell whether it
would accept such a string when it's the target of a drop.

> Mouse wheel events are also delivered to the topmost Z-order window without
> either raising the window or switching focus.

Mouse wheel events are completely different and highly window system
dependent.  Sometimes they get caught before Emacs sees them at all and
get transformed to scroll bar thumb drag events to the owner of the
scroll bar nearest to the mouse cursor at the time the wheel gets
scrolled.

> So the window manager always knows where it should deliver

... it never "knows".  Some make better guesses and some make worse ...

> What would the pseudo-code
> look like to check whether or not an Emacs frame was uppermost at the point
> of mouse release?

(1) ‘frame-list-z-order’ would have to be able to return all windows on
your system and (2) a function would be needed to get the attributes of
those windows.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 14 Oct 2017 17:18:02 GMT) Full text and rfc822 format available.

Message #74 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Sat, 14 Oct 2017 13:16:55 -0400
[Message part 1 (text/plain, inline)]
Martin:

Thanks for commenting on this and sharing some of your extensive knowledge
on window event handling and Emacs.

On Sat, Oct 14, 2017 at 4:35 AM, martin rudalics <rudalics <at> gmx.at> wrote:

> > ​I think it is a feature that Emacs receives an event for this but a
> defect
> > that it can't distinguish when f2 is atop an external window or not and
> > thus whether the event was actually directed at f2 or not.
>
> ‘mouse-drag-region’ is an Emacs internal function, so it's no defect.
> If it were not internal, Emacs would have to be either able to poll the
> other window's application as to whether it supports dropping an Emacs
> internal string or convert that string to some appropriate coding that
> other applications understand.  Neither of these has been done yet and
> it will be non-trivial to do that for our various platforms.


​Ok, that indicates that drag-and-drop from Emacs to external applications
is unlikely but it still leaves the issue of recognizing whether a drag
release event maps to an Emacs frame or not (when the frame is covered by
an external app's window).  I already have code that recognizes this in
Lisp; we should make it a primitive so the drag release code in Emacs could
report more useful and accurate information in drag release events.

I guess you are saying that Emacs drag events must start and end within
Emacs frames.  I think about it a bit differently.  Since the mouse can
move in and out of Emacs frames and release events can occur (in logical
Z-ordered OS window space) outside of Emacs, yet still register with Emacs
(when the release occurs within the geometry of a frame but the frame is
covered by another app's window), I think Emacs event handling should
return different information when the release frame is not the topmost
OS-level window at the point of release.  Then handler code could dispatch
as necessary.

I already have Lisp code doing useful things with such information
(presently, I have to adjust the drag release event information).  So I
know it would be helpful to have this as default Emacs event reporting
behavior.

​​
>
> ​​
> > ​Just FYI, I am using the macOS window manager, not X, though as you
> note,
> ​​
> > it is an issue there too.
> ​​
> > The application-level window managers must have a z-ordering for all
> ​​
> > windows in order to be able to select and raise windows when they are
> ​​
> > behind others.  So you are saying that they don't publish this
> information
> ​​
> > in any useful way that Emacs can obtain, right?
> ​​
>
> ​​
> All I can say is that when you nowadays try to obtain information on
> ​​
> whether a window is really visible under X, chances are that you don't
> ​​
> g
> ​​
> e
> ​​
> t
> ​​
> ​​
> i
> ​​
> t
> ​​
> .


​Each window has a 'visible' attribute.  Are you saying this is not
accurate these days?​
​​​

> ​
>   Querying the z-order will only tell you something like "window
> ​​
> Y cannot obscure window X because it's lower in the z-order".


​We just want to know when given a screen position whether an Emacs frame
is topmost at that position or not.​
​​​

> ​​
>
> ​​
> > Part of the issue is that the macOS window manager uses click-to-focus,
> so
> ​​
> > the release event of the drag does not switch focus to the application
> ​​
> > whose window the release falls upon.
> ​​
>
> ​​
> As Stefan already mentioned earlier: With a drag operation usually no
> ​​
> focus shifting occurs anyway.


For the interactive things I am doing, I find that selecting the window of
mouse release is always best but I agree it is not necessary in all
instances.

​​
>
> ​
> > However, in drag-n-drop operations,
> ​​
> > the window manager automatically switches focus to any compatible
> ​​
> > application that the mouse moves over (after a delay) so that the right
> ​​
> > application receives the drop (based on Z-order).
> ​​
>
> ​​
> It's completely up to the window manager which polls the application(s)
> ​​
> whether they are ready to receive the object to drop.  Emacs is not
> ​​
> involved in that process.  It would be involved only to tell whether it
> ​​
> would accept such a string when it's the target of a drop.


​I understand that.  I was just noting that there is an example of a drag
release event handler that selects the window of release as a standard part
of its operation.

​​
>
> ​​
>
> ​​
> > Mouse wheel events are also delivered to the topmost Z-order window
> without
> ​​
> > either raising the window or switching focus.
> ​​
>
> ​​
> Mouse wheel events are completely different and highly window system
> ​​
> dependent.  Sometimes they get caught before Emacs sees them at all and
> ​​
> get transformed to scroll bar thumb drag events to the owner of the
> ​​
> scroll bar nearest to the mouse cursor at the time the wheel gets
> ​​
> scrolled.


​Again, I was just providing context of what might be possible based on
other event handling that occurs already in Emacs under macOS.​

​​
>
> ​
> ​​
> > So the window manager always knows where it should deliver
> ​​
>
> ​​
> ... it never "knows".  Some make better guesses and some make worse ...


​On macOS the scroll wheel events seem to go to the right window 100% of
the time from what I have seen.​

​​
>
> ​
> ​​
> > What would the pseudo-code
> ​​
> > look like to check whether or not an Emacs frame was uppermost at the
> point
> ​​
> > of mouse release?
> ​​
>
> ​​
> (1) ‘frame-list-z-order’ would have to be able to return all windows on
> ​​
> your system


​Is it likely we could build a multi-platform primitive ​that would supply
that information given what you have said?
​​​

> ​​
> and (2) a function would be needed to get the attributes of
> ​​
> those windows.


​2 seems straightforward.

Bob
​​
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 14 Oct 2017 18:49:01 GMT) Full text and rfc822 format available.

Message #77 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Sat, 14 Oct 2017 14:47:37 -0400
[Message part 1 (text/plain, inline)]
On Sat, Oct 14, 2017 at 1:16 PM, Robert Weiner <rsw <at> gnu.org> wrote:

> it still leaves the issue of recognizing whether a drag release event maps
> to an Emacs frame or not (when the frame is covered by an external app's
> window).  I already have code that recognizes this in Lisp; we should make
> it a primitive so the drag release code in Emacs could report more useful
> and accurate information in drag release events.
>

​I misspoke.  I have code that detects when the release falls outside of
the bounds of any Emacs frame.  However, when the release event is over an
Emacs frame that is covered by another application's window, we don't yet
have any information to tell us that, so I cannot detect it yet.  That is
the problem we are discussing how to solve in a general way.

Bob
​
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sun, 15 Oct 2017 03:33:02 GMT) Full text and rfc822 format available.

Message #80 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Sat, 14 Oct 2017 23:31:31 -0400
[Message part 1 (text/plain, inline)]
On Sat, Oct 14, 2017 at 2:47 PM, Robert Weiner <rsw <at> gnu.org> wrote:

> On Sat, Oct 14, 2017 at 1:16 PM, Robert Weiner <rsw <at> gnu.org> wrote:
>
>> it still leaves the issue of recognizing whether a drag release event
>> maps to an Emacs frame or not (when the frame is covered by an external
>> app's window).
>>
>
​I have written a Python script that can be used to get this answer.  (It
uses the Python-to-Objective-C bridge library that exposes the relevant Mac
APIs to Python)​.  The script  takes two arguments, X and Y screen pixel
coordinates, gets a list of all visible application windows in Z-order and
then prints the application name of the first window that intersects the
(X,Y) position, if any.  If that window is an Emacs frame, we have a match
and otherwise, we don't.

This is a short script that really needs to be recoded into an Objective-C
function that can be exposed to Emacs Lisp.  If anyone who is familiar with
macOS Objective-C code would want to work with me on this, email me and
I'll provide the Python code.  It is only about 28 lines.  -- Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sun, 15 Oct 2017 09:41:02 GMT) Full text and rfc822 format available.

Message #83 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Sun, 15 Oct 2017 11:40:10 +0200
> ​Ok, that indicates that drag-and-drop from Emacs to external applications
> is unlikely but it still leaves the issue of recognizing whether a drag
> release event maps to an Emacs frame or not (when the frame is covered by
> an external app's window).  I already have code that recognizes this in
> Lisp; we should make it a primitive so the drag release code in Emacs could
> report more useful and accurate information in drag release events.

Even if the Emacs frame is covered by another application's frame,
nothing prevents us from having that covered Emacs frame accept the
drop.  We could even give frames a "no-accept-drops" parameter and this
way have a drop on such frames pass the drop through to yet another
frame below that does accept drops.

> I guess you are saying that Emacs drag events must start and end within
> Emacs frames.  I think about it a bit differently.  Since the mouse can
> move in and out of Emacs frames and release events can occur (in logical
> Z-ordered OS window space) outside of Emacs, yet still register with Emacs
> (when the release occurs within the geometry of a frame but the frame is
> covered by another app's window), I think Emacs event handling should
> return different information when the release frame is not the topmost
> OS-level window at the point of release.  Then handler code could dispatch
> as necessary.

But to be useful, that "handler code" must be written and such code must
follow a standard interface for the OS used.  Consider the trivial task
that one Emacs instance wants to drop some text to a second Emacs
instance.  How would we trigger the drop event on that second instance?

> ​Each window has a 'visible' attribute.  Are you saying this is not
> accurate these days?​

Yes.  The GTK manual says that

  Modern composited windowing systems with pervasive transparency make
  it impossible to track the visibility of a window reliably,

>> (1) ‘frame-list-z-order’ would have to be able to return all windows on
>> ​​
>> your system
>
>
> ​Is it likely we could build a multi-platform primitive ​that would supply
> that information given what you have said?

At least for top-level windows.  This will work as long a child windows
are fully contained by their parents which IIUC is not necessarily true
for macOS systems.

>> and (2) a function would be needed to get the attributes of
>> ​​
>> those windows.
>
>
> ​2 seems straightforward.

How accurate these attributes will be depends on the windowing system
used.  Look at how hard frame_geometry occasionally works to just get
the real screen estate of an Emacs frame.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Mon, 16 Oct 2017 15:12:02 GMT) Full text and rfc822 format available.

Message #86 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Bob Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>, Eli Zaretskii <eliz <at> gnu.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Emacs bug#28620: (PARTIAL SOLUTION) mouse-position wrong on macOS
 and Windows 7 after mouse-1 click
Date: Mon, 16 Oct 2017 11:11:33 -0400
Robert Weiner <rsw <at> gnu.org> writes:

I wrote:
>
> ​The issue, to recap, is that I can't find a function that
> will report the window that a mouse release button event
> occurs in if the depress and release are in different frames
> (for Emacs 25).
>
> In fact, the release event (drag event) contains the wrong
> frame (that of the depress rather than the release).  The wrong 
> frame is also reported by mouse-position and mouse-pixel-position,
> so window-at can't be used either.

The following is a temporary fix for the mouse-position and
mouse-pixel-position part of the problem.  Something needs to be fixed
in the original functions in the C code, though.  -- Bob

;; From mouse-position:
;;    f = SELECTED_FRAME ();
;;    XSETFRAME (lispy_dummy, f);
;;  It seems like the XSETFRAME macro is not properly copying the value of f on initial frame selection under the macOS window system.
;;  The problem occurs on other systems as well, e.g. Emacs 25.2 under Windows 7.
;;  The function below is a temporary fix for this.
(setq mouse-position-function
      (lambda (frame-x-dot-y)
	"Under macOS, mouse-position and mouse-pixel-position sometimes fail to return the selected-frame (returning the prior frame instead); fix that here."
	(setcar frame-x-dot-y (selected-frame))
	frame-x-dot-y))





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Mon, 16 Oct 2017 15:58:02 GMT) Full text and rfc822 format available.

Message #89 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Bob Weiner <rsw <at> gnu.org>
To: 28620 <at> debbugs.gnu.org
Cc: martin rudalics <rudalics <at> gmx.at>, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#28620: (PARTIAL SOLUTION) Mouse drag event records wrong
 window for release when crossing frames
Date: Mon, 16 Oct 2017 11:57:33 -0400
Robert Weiner <rsw <at> gnu.org> writes:

> With Emacs 25.3 under MacOS 10.12, a drag with mouse-1 depressed from
> the text area of frame F1 to the text area of frame F2 improperly
> generates a drag event whose (posn-window (event-end <event>)) shows
> F1 rather than F2.
>
> Note that for a drag between frames, posn-window should return a frame
> (according to the Elisp manual but not its own doc string).  The bug is
> that the event itself records the wrong frame (the depress frame rather
> than the release frame).
>
> I have confirmed this with Emacs 25.2 under Windows 7 as well.

I have this fixed and working nicely for the GNU Hyperbole package,
which does extensive mouse drag handling.  Hyperbole can now drag buffer
menu items, dired items, and buffers themselves across frames and
display them in any window that receives a release event.  It can also
tell whether the topmost application window at the point of release was
an Emacs frame or a window of another application (for macOS windowing
only), so drags can start in Emacs and end outside.

But this required a good bit of code that I include below just
so you can see what was required.  It would be much simpler once the
drag event release C code in Emacs is improved based upon this work to
at least return the actual window of drag release.

Bob

----------
Code from forthcoming Hyperbole 6.0.2e pre-release (the Python script
at the end will be converted to Objective-C at some point):


(defvar action-key-depress-args nil
  "List of mouse event args from most recent depress of the Action Key.")
(defvar assist-key-depress-args nil
  "List of mouse event args from most recent depress of the Assist Key.")

(defvar action-key-release-args nil
  "List of mouse event args from most recent release of the Action Key.")
(defvar assist-key-release-args nil
  "List of mouse event args from most recent release of the Assist Key.")

(defvar action-key-depress-window nil
  "The last window in which the Action Key was depressed or nil.
This is set to nil when the depress is on an inactive minibuffer.")
(defvar assist-key-depress-window nil
  "The last window in which the Assist Key was depressed or nil.
This is set to nil when the depress is on an inactive minibuffer.")
(defvar action-key-release-window nil
  "The last window in which the Action Key was released or nil.")
(defvar assist-key-release-window nil
  "The last window in which the Assist Key was released or nil.")

(defvar action-key-depress-position nil
  "The last screen position at which the Action Key was depressed or nil.")
(defvar assist-key-depress-position nil
  "The last screen position at which the Assist Key was depressed or nil.")


(defun hmouse-key-release-args-emacs (event)
  "For GNU Emacs, return a possibly modified version of EVENT as a list.
For mouse drags and double and triple clicks, remove any depress location,
compute the actual release location and include that."
  (if (integerp event)
      (list event)
    (let ((ev-type-str (and (listp event) (symbol-name (car event)))))
      (if (or (and ev-type-str
		   (string-match "\\(double\\|triple\\)-mouse" ev-type-str))
	      (not (= (length event) 3)))
	  event
	(let ((pos (event-end event))
	      coords window-and-char-coords)
	  (when (and ev-type-str (string-match "drag-mouse" ev-type-str)
		     ;; end of drag event; If drag crossed frames, the location
		     ;; will contain the frame of the depress point and
		     ;; some relative coordinates; change these to the window of
		     ;; release and window's character coordinates if within a window
		     ;; and to nil if outside of Emacs (as best we can tell).
		     (framep (posn-window pos)))
	    (setq window-and-char-coords (hmouse-window-coordinates event)
		  window (car window-and-char-coords)
		  coords (cadr window-and-char-coords))
	    ;; Modify the values in the event-end structure even if no
	    ;; valid window was found.
	    (setcar pos window)
	    (setcar (nthcdr 2 pos) coords)))
	;; Remove depress coordinates and send only original release coordinates.
	(list (car event) (nth 2 event))))))

(defun hmouse-window-coordinates (&optional event)
  "Return a list (window (x-chars . y-chars)) for optional EVENT.
Always ignores EVENT coordinates and uses current mouse position.
The area of the EVENT is utilized. If EVENT is not given and the
free variable `assist-flag' is non-nil, EVENT is set to
`assist-key-release-args', otherwise, `action-key-release-args'.

The coordinates x-chars and y-chars are relative character
coordinates within the window.  If POSITION is not in a live
window, return nil.  Considers all windows on the selected frame's display."
  (interactive)
  (unless (eventp event)
    (setq event (if assist-flag assist-key-release-args action-key-release-args)))
  (let* ((position (mouse-absolute-pixel-position))
	 (pos-x (car position))
	 (pos-y (cdr position))
	 (window (hmouse-window-at-absolute-pixel-position position t))
	 (edges (when (window-live-p window) (window-edges window t t t)))
	 left top right bottom
	 frame)
    (when edges
      (setq left   (nth 0 edges)
	    top    (nth 1 edges)
	    right  (nth 2 edges)
	    bottom (nth 3 edges))
      (when (or (and event (eq (posn-area (event-start event)) 'mode-line))
		(and (>= pos-x left) (<= pos-x right)
		     (>= pos-y top)  (<= pos-y bottom)))
	;; If position is in a live window, compute position's character
	;; coordinates within the window and return the window with these
	;; coordinates.
	(setq frame (window-frame window)
	      pos-x (round (/ (- pos-x left) (frame-char-width frame)))
	      pos-y (round (/ (- pos-y top)  (+ (frame-char-height frame)
						(hmouse-vertical-line-spacing frame)))))))
    (when (called-interactively-p 'interactive)
      (message "%s at %s coordinates (%s . %s)"
	       (if edges window "No live Emacs window")
	       (if frame "character" "absolute pixel")
	       pos-x pos-y))
    (when edges (list window (cons pos-x pos-y)))))

(defvar hmouse-verify-release-window-flag t
  "When non-nil under the macOS window system, verifies the application of top-most window.
Forces a window system check at a screen position that the top-most
window there is an Emacs frame or treats the location as outside Emacs,
even though an Emacs frame may be below the top-most window.

See function `hmouse-window-at-absolute-pixel-position' for more details.")

(defun hmouse-window-at-absolute-pixel-position (&optional position release-flag)
  "Return the top-most Emacs window at optional POSITION ((x . y) in absolute pixels) or mouse position.
If POSITION is not in a window, return nil.  Considers all windows on
the same display as the selected frame.

If optional RELEASE-FLAG is non-nil, this is part of a Smart Key
release computation, so optimize window selection based on the depress
window already computed.

If the selected frame is a graphical macOS window and
`hmouse-verity-release-window-flag' is non-nil, then return the
top-most Emacs window only if it is the top-most application window at
the position (not below another application's window)."
  (interactive)
  (setq position (or position (mouse-absolute-pixel-position)))
  ;; Proper top-to-bottom listing of frames is available only in Emacs
  ;; 26 and above.  For prior versions, the ordering of the frames
  ;; returned is not guaranteed, so the frame whose window is returned
  ;; may not be the uppermost.
  (let* ((top-to-bottom-frames (if (fboundp 'frame-list-z-order)
				   (frame-list-z-order)
				 (frame-list)))
	 (pos-x (car position))
	 (pos-y (cdr position))
	 edges left top right bottom
	 frame
	 in-frame
	 window)
    ;; First find top-most frame containing position.
    (while (and (not in-frame) top-to-bottom-frames)
      (setq frame (car top-to-bottom-frames)
	    top-to-bottom-frames (cdr top-to-bottom-frames))
      ;; Check that in-frame is valid with frame-live-p since under macOS
      ;; when position is outside a frame, in-frame could be invalid and
      ;; frame-visible-p would trigger an error in that case.
      (when (and (frame-live-p frame) (frame-visible-p frame))
	(setq edges (frame-edges frame)
	      left   (nth 0 edges)
	      top    (nth 1 edges)
	      right  (nth 2 edges)
	      bottom (nth 3 edges))
	(when (and (>= pos-x left) (<= pos-x right)
		   (>= pos-y top)  (<= pos-y bottom))
	  (setq in-frame frame))))
    ;; If in-frame is found, find which of its windows contains
    ;; position and return that.  The window-at call below requires
    ;; character coordinates relative to in-frame, so compute them.
    (when in-frame
      (let ((depress-position (and release-flag (if assist-flag
						    assist-key-depress-position
						  action-key-depress-position)))
	    (depress-window  (and release-flag (if assist-flag
						   assist-key-depress-window
						 action-key-depress-window))))
	(if (and release-flag depress-window (equal position depress-position))
	    ;; This was a click, so we know that the frame of the click
	    ;; is topmost on screen or the mouse events would not have
	    ;; been routed to Emacs.  Reuse saved window of depress rather
	    ;; then running possibly expensive computation to find the
	    ;; topmost application window.
	    (setq window depress-window)
	  (let ((char-x (/ (- pos-x left) (frame-char-width in-frame)))
		(line-y (/ (- pos-y top) (+ (frame-char-height in-frame)
					    (hmouse-vertical-line-spacing in-frame)))))
	    (setq window (window-at char-x line-y in-frame)))
	  ;;
	  ;; Even if in-frame is found, under click-to-focus external window
	  ;; managers, Emacs may have received the drag release event when
	  ;; in-frame was covered by an external application's window.
	  ;; Emacs presently has no way to handle this.  However, for the
	  ;; macOS window system only, Hyperbole has a Python script, topwin, which
	  ;; computes the application of the topmost window at the point of release.
	  ;; If that is Emacs, then we have the right window and nothing need be
	  ;; done; otherwise, set window to nil and return.
	  ;;
	  (when (and hmouse-verify-release-window-flag
		     window (eq (window-system) 'ns))
	    (let ((topwin (executable-find "topwin"))
		  (case-fold-search t)
		  topmost-app)
	      (when (and topwin (file-executable-p topwin))
		(setq topmost-app (shell-command-to-string
				   (format "topwin %d %d" pos-x pos-y)))
		(cond ((string-match "emacs" topmost-app)) ; In an Emacs frame, do nothing.
		      ((or (equal topmost-app "")
			   ;; Any non-Emacs app window
			   (string-match "\\`\\[" topmost-app))
		       ;; Outside of any Emacs frame
		       (setq window nil))
		      (t		; topwin error message
		       ;; Setup of the topwin script is somewhat complicated,
		       ;; so don't trigger an error just because of it.  But
		       ;; display a message so the user knows something happened
		       ;; when topwin encounters an error.
		       (message "(Hyperbole): topwin Python script error: %s" topmost-app)))))))))

    (when (called-interactively-p 'interactive)
      (message "%s at absolute pixel position %s"
	       (or window "No Emacs window") position))
    window))

;; Based on code from subr.el.
(defun hmouse-vertical-line-spacing (frame)
  "Return any extra vertical spacing in pixels between text lines or 0 if none."
  (let ((spacing (when (display-graphic-p frame)
                   (or (with-current-buffer (window-buffer (frame-selected-window frame))
                         line-spacing)
		       (frame-parameter frame 'line-spacing)))))
    (cond ((floatp spacing)
	   (setq spacing (truncate (* spacing (frame-char-height frame)))))
	  ((null spacing)
	   (setq spacing 0)))
    spacing))

------
#!python2
#
# SUMMARY:      topwin: Outputs the [application name] of the topmost window at mouse screen position or nothing if none
# USAGE:        <script> <x-screen-coordinate> <y-screen-coordinate>
#
# REQUIRES:     macOS window system and the python2 and the PyObjC libraries available here: https://pythonhosted.org/pyobjc/install.html
#
# AUTHOR:       Bob Weiner <rsw <at> gnu.org>
# ORIG-DATE:    14-Oct-17 at 16:21:53
#
# Copyright (C) 2017  Free Software Foundation, Inc.
# See the "HY-COPY" file for license information.
#
# DESCRIPTION:  
# DESCRIP-END.

import Quartz
from sys import argv, exit

if len(argv) < 3:
    print "%s: ERROR - Call with 2 numeric arguments, X and Y representing an absolute screen position" % argv[0]
    exit(1)

x = int(argv[1]); y = int(argv[2])

# Return the first window only that x,y falls within since the windows are listed in z-order (top of stack to bottom)
def filter_and_print_top_window(x, y):
    win_x = win_y = win_width = win_height = 0

    for v in Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionOnScreenOnly | Quartz.kCGWindowListExcludeDesktopElements, Quartz.kCGNullWindowID ):
        val = v.valueForKey_
        bounds_val = val('kCGWindowBounds').valueForKey_
        
        # If item has a non-zero WindowLayer, it is not an app and is probably system-level, so skip it.
        if not val('kCGWindowIsOnscreen') or val('kCGWindowLayer'):
            continue

        win_x = int(bounds_val('X')); win_y = int(bounds_val('Y'))
        win_width = int(bounds_val('Width')); win_height = int(bounds_val('Height'))

        if win_x <= x and x < win_x + win_width and win_y <= y and y < win_y + win_height:
            print ('[' + ((val('kCGWindowOwnerName') or '') + ']')).encode('utf8')
            # Add this line back in if you need to see the specific window within the app at the given position.
            # + ('' if val('kCGWindowName') is None else (' ' + val('kCGWindowName') or '')) \

            break

# Filter to just the topmost window at (x,y) screen coordinates and print the bracketed [window name], if any.
filter_and_print_top_window(x, y)





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Mon, 16 Oct 2017 16:32:02 GMT) Full text and rfc822 format available.

Message #92 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Mon, 16 Oct 2017 12:31:06 -0400
[Message part 1 (text/plain, inline)]
On Sun, Oct 15, 2017 at 5:40 AM, martin rudalics <rudalics <at> gmx.at> wrote:

>
> Even if the Emacs frame is covered by another application's frame,
> nothing prevents us from having that covered Emacs frame accept the
> drop.  We could even give frames a "no-accept-drops" parameter and this
> way have a drop on such frames pass the drop through to yet another
> frame below that does accept drops.


​Yes.  My point is that there should be some extension to Emacs'
reporting of window system events that allows a user of such
information to know whether any other application occluded the
Emacs frame at the time and point of release.  Then in cases
where this information can be gleaned from the external window
manager, it can be used in programs.  The user program is still
free to allow a drop to go through in such cases but only if
desired.

​​
>
> ​​
> > I guess you are saying that Emacs drag events must start and end within
> ​​
> > Emacs frames.  I think about it a bit differently.  Since the mouse can
> ​​
> > move in and out of Emacs frames and release events can occur (in logical
> ​​
> > Z-ordered OS window space) outside of Emacs, yet still register with
> Emacs
> ​​
> > (when the release occurs within the geometry of a frame but the frame is
> ​​
> > covered by another app's window), I think Emacs event handling should
> ​​
> > return different information when the release frame is not the topmost
> ​​
> > OS-level window at the point of release.  Then handler code could
> dispatch
> ​​
> > as necessary.
> ​​
>
> ​​
> But to be useful, that "handler code" must be written and such code must
> ​​
> f
> ​​
> o
> ​​
> l
> ​​
> l
> ​​
> o
> ​​
> w
> ​​
> ​​
> a
> ​​
> ​​
> s
> ​​
> t
> ​​
> a
> ​​
> n
> ​​
> d
> ​​
> a
> ​​
> rd interface for the OS used.


​It is not only drag-and-drop that we are interested in.  We
often want to simply call different functions based on whether
the drag release was inside or outside of Emacs.  For example,
Hyperbole now uses a drag release outside of Emacs to clone the
window depressed upon into a new frame.​

​​
>   Consider the trivial task
> ​​
>
> ​​
> that one Emacs instance wants to drop some text to a second Emacs
> ​​
> instance.  How would we trigger the drop event on that second instance?


​Yes, you would need to follow a common drag-and-drop protocol.
I don't understand why that is an issue if that is what you want
to do.

​​
>
> ​
> > ​Each window has a 'visible' attribute.  Are you saying this is not
> ​​
> > accurate these days?​
> ​​
>
> ​​
> Yes.  The GTK manual says that
> ​​
>
> ​​
>   Modern composited windowing systems with pervasive transparency make
> ​​
>   it impossible to track the visibility of a window reliably,


For programmatic purposes when Emacs receives a mouse button
drag release event, we only care about whether the topmost
window-system window at the point of release is an Emacs frame
or not.  If at that point, it is occluded by another window,
we don't care how transparent that window is and whether the
Emacs frame can be "seen" but only whether it is logically
the window clicked upon.  Again, even if it is not, we can
process the event as if it were *if we so choose* but having
the choice is the key issue here.

​​
>
> ​​
>
> ​​
> >> (1) ‘frame-list-z-order’ would have to be able to return all windows on
> ​
> ​
> your system
> ​
> ​​
> >
> ​​
> > ​Is it likely we could build a multi-platform primitive ​that would
> supply
> ​​
> > that information given what you have said?
> ​​
>
> ​​
> At least for top-level windows.  This will work as long a child windows
> ​​
> are fully contained by their parents which IIUC is not necessarily true
> ​​
> for macOS systems.


​Could you give a concrete example of where this might be a problem
so I could test code against it?
​

> ​​
>
> ​
> ​​
> >
> ​​
> > and (2) a function would be needed to get the attributes of
> ​
> ​​
>  those windows.
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
>

​I have figured that part out from the macOS APIs.
​
Bob
​
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 17 Oct 2017 08:59:02 GMT) Full text and rfc822 format available.

Message #95 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Tue, 17 Oct 2017 10:57:34 +0200
> ​Yes, you would need to follow a common drag-and-drop protocol.
> I don't understand why that is an issue if that is what you want
> to do.

Wasn't that something _you_ wanted to do?  If not then we can obviously
ignore it.

> For programmatic purposes when Emacs receives a mouse button
> drag release event, we only care about whether the topmost
> window-system window at the point of release is an Emacs frame
> or not.  If at that point, it is occluded by another window,
> we don't care how transparent that window is and whether the
> Emacs frame can be "seen" but only whether it is logically
> the window clicked upon.  Again, even if it is not, we can
> process the event as if it were *if we so choose* but having
> the choice is the key issue here.

So I warned here about possible problems with "visibility" once and will
drop this issue.

>> At least for top-level windows.  This will work as long a child windows
>> ​​
>> are fully contained by their parents which IIUC is not necessarily true
>> ​​
>> for macOS systems.
>
>
> ​Could you give a concrete example of where this might be a problem
> so I could test code against it?

Hardly.  Child windows are a separate problem because, for example, on X
you currently cannot drop files on them - the drop goes to the parent
window instead.

>>> and (2) a function would be needed to get the attributes of
>> ​
>> ​​
>>   those windows.
>> ​​
>> ​​
>> ​​
>> ​​
>> ​​
>> ​​
>> ​​
>> ​​
>>
>
> ​I have figured that part out from the macOS APIs.

Window attributes are a problem on X.  You will learn about that as soon
as you try to adapt your code for it.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Thu, 19 Oct 2017 18:34:01 GMT) Full text and rfc822 format available.

Message #98 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Thu, 19 Oct 2017 14:32:31 -0400
[Message part 1 (text/plain, inline)]
On Tue, Oct 17, 2017 at 4:57 AM, martin rudalics <rudalics <at> gmx.at> wrote:

> > ​Yes, you would need to follow a common drag-and-drop protocol.
> > I don't understand why that is an issue if that is what you want
> > to do.
>
> Wasn't that something _you_ wanted to do?  If not then we can obviously
> ignore it.


​Yes, I would like Emacs drag-and-drop to work across Emacs frames and
potentially even across other applications using whatever protocol is
common to the platform in use.


>
> >> At least for top-level windows.  This will work as long a child windows
> >> ​are fully contained by their parents which IIUC is not necessarily true
> >> ​
> ​f​
> or macOS systems.
> >
> > ​Could you give a concrete example of where this might be a problem
> > so I could test code against it?
>
> Hardly.  Child windows are a separate problem because, for example, on X
> you currently cannot drop files on them - the drop goes to the parent
> window instead.


​We would certainly live within the constraints of the drag-and-drop
protocol.
​

>
>
> >>> and (2) a function would be needed to get the attributes of
> >>   those windows.
> >
> > ​I have figured that part out from the macOS APIs.
>
> Window attributes are a problem on X.  You will learn about that as soon
> as you try to adapt your code for it.


​Ok.  It would be more helpful if you explained which problems you feel are
relevant to the discussion at hand.
​
Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Fri, 20 Oct 2017 07:57:02 GMT) Full text and rfc822 format available.

Message #101 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Fri, 20 Oct 2017 09:55:46 +0200
> ​Ok.  It would be more helpful if you explained which problems you feel are
> relevant to the discussion at hand.

For example that of getting the screen dimensions of a window.  Have a
look at x_real_pos_and_offsets to get an idea of the tribulations needed
to do that for an Emacs frame.  These are by far the most complicated
operations we do in the X specific code and I have reports that we still
do not get the right results everywhere.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Fri, 20 Oct 2017 14:28:02 GMT) Full text and rfc822 format available.

Message #104 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rsw <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Fri, 20 Oct 2017 10:26:22 -0400
[Message part 1 (text/plain, inline)]
On Fri, Oct 20, 2017 at 3:55 AM, martin rudalics <rudalics <at> gmx.at> wrote:

> > ​Ok.  It would be more helpful if you explained which problems you feel
> are
> > relevant to the discussion at hand.
>
> For example that of getting the screen dimensions of a window.  Have a
> look at x_real_pos_and_offsets to get an idea of the tribulations needed
> to do that for an Emacs frame.  These are by far the most complicated
> operations we do in the X specific code and I have reports that we still
> do not get the right results everywhere.


​Yes, I see.  I am having similar issues when trying to replicate the size
of a frame under the macOS window system.  I can't seem to get the new
frame to match the old frame by using (frame-edges nil 'outer-edges) or
(frame-edges nil 'native-edges).  In earlier versions of Emacs, I don't
remember this being a problem but I can't recall when that was.  What is
the best way available to replicate the size of one frame to another given
the limitations that exist now?

Bob
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 21 Oct 2017 08:06:01 GMT) Full text and rfc822 format available.

Message #107 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com
Cc: Eli Zaretskii <eliz <at> gnu.org>, Alan Third <alan <at> idiocy.org>,
 28620 <at> debbugs.gnu.org
Subject: Re: Interact directly on Emacs bug#28620: mouse drag event records
 wrong release window
Date: Sat, 21 Oct 2017 10:05:03 +0200
> ​Yes, I see.  I am having similar issues when trying to replicate the size
> of a frame under the macOS window system.  I can't seem to get the new
> frame to match the old frame by using (frame-edges nil 'outer-edges) or
> (frame-edges nil 'native-edges).  In earlier versions of Emacs, I don't
> remember this being a problem but I can't recall when that was.  What is
> the best way available to replicate the size of one frame to another given
> the limitations that exist now?

There should be no "limitations".  As a rule,

(setq frame-resize-pixelwise t)
(make-frame (frame-parameters))

should give you an exact replica of the selected frame.  If you only
want to clone the size of the selected frame use

(setq frame-resize-pixelwise t)
(make-frame `((width . ,(frame-parameter nil 'width))
	      (height . ,(frame-parameter nil 'height))))

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 21 Oct 2017 18:06:02 GMT) Full text and rfc822 format available.

Message #110 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Richard Stallman <rms <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: alan <at> idiocy.org, rswgnu <at> gmail.com, 28620 <at> debbugs.gnu.org
Subject: Re: bug#28620: Interact directly on Emacs bug#28620: mouse drag event
 records wrong release window
Date: Sat, 21 Oct 2017 14:05:00 -0400
I am trying to imagine what a mouse drag event would look like.
Since mice don't wear clothing, or makeup, what would distinguish
it from any other mouse event?

-- 
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 27 Jul 2019 09:28:02 GMT) Full text and rfc822 format available.

Message #113 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: rswgnu <at> gmail.com, 28620 <at> debbugs.gnu.org, 36269 <at> debbugs.gnu.org,
 Scott Otterson <scotto <at> sharpleaf.org>
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Sat, 27 Jul 2019 11:26:47 +0200
[Message part 1 (text/plain, inline)]
> With Emacs 25.3 under MacOS 10.12, a drag with mouse-1 depressed from
> the text area of frame F1 to the text area of frame F2 improperly
> generates a drag event whose (posn-window (event-end <event>)) shows
> F1 rather than F2.
>
> Note that for a drag between frames, posn-window should return a frame
> (according to the Elisp manual but not its own doc string).  The bug is
> that the event itself records the wrong frame (the depress frame rather
> than the release frame).
>
> I have confirmed this with Emacs 25.2 under Windows 7 as well.

I tried to address this problem in the attached patch.  Tested with
GTK, Lucid, Motif and Windows builds.  Since my GNUstep Emacs is
currently broken, somebody please verify that it does something
reasonable (if anything at all) on MacOS.  Otherwise, I'd need help
from people working there.

The patch should also fix the mouse drag and drop region vs. mouse
avoidance mode problem.  Please someone verify that it does TRT now.

TIA, martin
[track-mouse.diff (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 27 Jul 2019 10:10:01 GMT) Full text and rfc822 format available.

Message #116 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: rswgnu <at> gmail.com, scotto <at> sharpleaf.org, 28620 <at> debbugs.gnu.org,
 36269 <at> debbugs.gnu.org
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Sat, 27 Jul 2019 13:08:52 +0300
> From: martin rudalics <rudalics <at> gmx.at>
> Date: Sat, 27 Jul 2019 11:26:47 +0200
> 
> I tried to address this problem in the attached patch.  Tested with
> GTK, Lucid, Motif and Windows builds.  Since my GNUstep Emacs is
> currently broken, somebody please verify that it does something
> reasonable (if anything at all) on MacOS.  Otherwise, I'd need help
> from people working there.
> 
> The patch should also fix the mouse drag and drop region vs. mouse
> avoidance mode problem.  Please someone verify that it does TRT now.

Thanks, a few minor comments below.

> +  /* If forced to complete the update, no input is pending or we are
> +     tracking the mouse do the update.  */

Commas missing here.  Should be

  /* If forced to complete the update, no input is pending, or we are
     tracking the mouse, do the update.  */


> -	  /* If this event is on a different frame, return a switch-frame this
> -	     time, and leave the event in the queue for next time.  */
> +	  /* If this event is on a different frame, return a
> +	     switch-frame this time and leave the event in the queue

A comma missing before "and".

> @@ -3995,7 +3992,7 @@ kbd_buffer_get_event (KBOARD **kbp,
>        }
>      }
>    /* Try generating a mouse motion event.  */
> -  else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
> +  else if (some_mouse_moved ())

Can't we have mouse motion events outside track-mouse?

> +  DEFVAR_LISP ("track-mouse", track_mouse,
> +	       doc: /* Non-nil means generate motion events for mouse motion.
> +The sepecial values 'dragging' and 'dropping' assert that the moue
       ^^^^^^^^                                                  ^^^^
Typos.

Also, the quoting in doc strings should be `like this'.

> +      /* While dropping use the last mouse frame only if there is no
> +	 currently focused frame.  */

A comma missing before "use".

There's too much of whitespace changes in the rest of the patch,
making it very hard to review.  Can you show the patch without
whitespace differences?

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sun, 28 Jul 2019 07:35:01 GMT) Full text and rfc822 format available.

Message #119 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rswgnu <at> gmail.com, scotto <at> sharpleaf.org, 28620 <at> debbugs.gnu.org,
 36269 <at> debbugs.gnu.org
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Sun, 28 Jul 2019 09:34:00 +0200
[Message part 1 (text/plain, inline)]
> Thanks, a few minor comments below.

Thanks for the comments.  I hopefully applied all changes you
proposed.

Please keep in mind that I wrote the code almost two years ago and
then forgot about it.  It's only in the context of Bug#36269 that I
resurrected it - with all its inadequacies.

>> @@ -3995,7 +3992,7 @@ kbd_buffer_get_event (KBOARD **kbp,
>>         }
>>       }
>>     /* Try generating a mouse motion event.  */
>> -  else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
>> +  else if (some_mouse_moved ())
>
> Can't we have mouse motion events outside track-mouse?

Not to my knowledge.  In either case, I wouldn't want to change
anything in this regard here.

> There's too much of whitespace changes in the rest of the patch,
> making it very hard to review.  Can you show the patch without
> whitespace differences?

I attach a patch which re-adds some extraneous braces to w32term.c.
If you want me to restore more of the old code, please tell me.

Also, I do not intend to push the changes until someone tells me that
they work.  I neither use the mouse to drop nor mouse avoidance mode
and so have never given it any serious testing.

Thanks, martin
[track-mouse-with-braces.diff (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Mon, 29 Jul 2019 23:22:02 GMT) Full text and rfc822 format available.

Message #122 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Robert Weiner <rswgnu <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, scotto <at> sharpleaf.org, 28620 <at> debbugs.gnu.org,
 36269 <at> debbugs.gnu.org
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Mon, 29 Jul 2019 19:21:28 -0400
Martin:

I just want to say that this is an exciting fix and thank you for working on it.  I don’t have much time these days but will try to test it next weekend.  I use do use MacOS sometimes, so I can test there.

-- Bob

> On Jul 28, 2019, at 3:34 AM, martin rudalics <rudalics <at> gmx.at> wrote:
> 
> > Thanks, a few minor comments below.
> 
> Thanks for the comments.  I hopefully applied all changes you
> proposed.
> 
> Please keep in mind that I wrote the code almost two years ago and
> then forgot about it.  It's only in the context of Bug#36269 that I
> resurrected it - with all its inadequacies.
> 
> >> @@ -3995,7 +3992,7 @@ kbd_buffer_get_event (KBOARD **kbp,
> >>         }
> >>       }
> >>     /* Try generating a mouse motion event.  */
> >> -  else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
> >> +  else if (some_mouse_moved ())
> >
> > Can't we have mouse motion events outside track-mouse?
> 
> Not to my knowledge.  In either case, I wouldn't want to change
> anything in this regard here.
> 
> > There's too much of whitespace changes in the rest of the patch,
> > making it very hard to review.  Can you show the patch without
> > whitespace differences?
> 
> I attach a patch which re-adds some extraneous braces to w32term.c.
> If you want me to restore more of the old code, please tell me.
> 
> Also, I do not intend to push the changes until someone tells me that
> they work.  I neither use the mouse to drop nor mouse avoidance mode
> and so have never given it any serious testing.
> 
> Thanks, martin
> <track-mouse-with-braces.diff>




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 30 Jul 2019 07:01:02 GMT) Full text and rfc822 format available.

Message #125 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Robert Weiner <rswgnu <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, scotto <at> sharpleaf.org, 28620 <at> debbugs.gnu.org,
 36269 <at> debbugs.gnu.org
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Tue, 30 Jul 2019 09:00:17 +0200
> I don’t have much time these days but will try to test it next
> weekend.  I use do use MacOS sometimes, so I can test there.

Your original report just turned two years old so there really is
no hurry ...

Thanks in advance, martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sat, 03 Aug 2019 11:26:01 GMT) Full text and rfc822 format available.

Message #128 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: rswgnu <at> gmail.com, scotto <at> sharpleaf.org, 28620 <at> debbugs.gnu.org,
 36269 <at> debbugs.gnu.org
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Sat, 03 Aug 2019 14:25:13 +0300
> Cc: rswgnu <at> gmail.com, 28620 <at> debbugs.gnu.org, 36269 <at> debbugs.gnu.org,
>  scotto <at> sharpleaf.org
> From: martin rudalics <rudalics <at> gmx.at>
> Date: Sun, 28 Jul 2019 09:34:00 +0200
> 
>  > There's too much of whitespace changes in the rest of the patch,
>  > making it very hard to review.  Can you show the patch without
>  > whitespace differences?
> 
> I attach a patch which re-adds some extraneous braces to w32term.c.

Thanks, that helped a lot.

> Also, I do not intend to push the changes until someone tells me that
> they work.  I neither use the mouse to drop nor mouse avoidance mode
> and so have never given it any serious testing.

I think you should push this to master, and we will have enough time
before the release to see if there are any problems with it.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Sun, 04 Aug 2019 08:00:02 GMT) Full text and rfc822 format available.

Message #131 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rswgnu <at> gmail.com, scotto <at> sharpleaf.org, 28620 <at> debbugs.gnu.org,
 36269 <at> debbugs.gnu.org
Subject: Re: bug#28620: Mouse drag event records wrong window for release when
 crossing frames
Date: Sun, 4 Aug 2019 09:59:40 +0200
> I think you should push this to master, and we will have enough time
> before the release to see if there are any problems with it.

Done.  Let's see what it breaks.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#28620; Package emacs. (Tue, 18 Aug 2020 11:32:02 GMT) Full text and rfc822 format available.

Message #134 received at 28620 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefan <at> marxist.se>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, rswgnu <at> gmail.com, scotto <at> sharpleaf.org,
 28620 <at> debbugs.gnu.org, 36269 <at> debbugs.gnu.org
Subject: Re: bug#36269: bug#28620: Mouse drag event records wrong window for
 release when crossing frames
Date: Tue, 18 Aug 2020 11:31:30 +0000
martin rudalics <rudalics <at> gmx.at> writes:

>> I think you should push this to master, and we will have enough time
>> before the release to see if there are any problems with it.
>
> Done.  Let's see what it breaks.

From skimming the thread, the patch here was pushed and there doesn't
seem to me that there is anything more to do here.

Should this bug be closed?

Best regards,
Stefan Kangas




Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Tue, 18 Aug 2020 12:16:01 GMT) Full text and rfc822 format available.

Notification sent to rswgnu <at> gmail.com:
bug acknowledged by developer. (Tue, 18 Aug 2020 12:16:01 GMT) Full text and rfc822 format available.

Message #139 received at 28620-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Kangas <stefan <at> marxist.se>
Cc: rudalics <at> gmx.at, rswgnu <at> gmail.com, scotto <at> sharpleaf.org,
 36269-done <at> debbugs.gnu.org, 28620-done <at> debbugs.gnu.org
Subject: Re: bug#36269: bug#28620: Mouse drag event records wrong window for
 release when crossing frames
Date: Tue, 18 Aug 2020 15:15:27 +0300
> From: Stefan Kangas <stefan <at> marxist.se>
> Date: Tue, 18 Aug 2020 11:31:30 +0000
> Cc: Eli Zaretskii <eliz <at> gnu.org>, rswgnu <at> gmail.com, scotto <at> sharpleaf.org, 
> 	28620 <at> debbugs.gnu.org, 36269 <at> debbugs.gnu.org
> 
> martin rudalics <rudalics <at> gmx.at> writes:
> 
> >> I think you should push this to master, and we will have enough time
> >> before the release to see if there are any problems with it.
> >
> > Done.  Let's see what it breaks.
> 
> >From skimming the thread, the patch here was pushed and there doesn't
> seem to me that there is anything more to do here.
> 
> Should this bug be closed?

It should be; done.

Thanks.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 16 Sep 2020 11:24:06 GMT) Full text and rfc822 format available.

This bug report was last modified 3 years and 222 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.