From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Robert Weiner Newsgroups: gmane.emacs.bugs Subject: bug#28620: Interact directly on Emacs bug#28620: mouse drag event records wrong release window Date: Wed, 11 Oct 2017 21:35:13 -0400 Message-ID: References: <83wp4e3nvx.fsf@gnu.org> <8360bx340d.fsf@gnu.org> <8360bw19es.fsf@gnu.org> <83vajwytja.fsf@gnu.org> <83poa4yqyq.fsf@gnu.org> <83376qouoj.fsf@gnu.org> Reply-To: rswgnu@gmail.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="001a113a0518154d2a055b4f8f22" X-Trace: blaine.gmane.org 1507772184 24436 195.159.176.226 (12 Oct 2017 01:36:24 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 12 Oct 2017 01:36:24 +0000 (UTC) To: Eli Zaretskii , martin rudalics , Alan Third , 28620@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Oct 12 03:36:15 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2SPu-00040y-5v for geb-bug-gnu-emacs@m.gmane.org; Thu, 12 Oct 2017 03:36:06 +0200 Original-Received: from localhost ([::1]:43272 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2SQ1-0006Pu-H2 for geb-bug-gnu-emacs@m.gmane.org; Wed, 11 Oct 2017 21:36:13 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39452) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2SPu-0006Pc-4l for bug-gnu-emacs@gnu.org; Wed, 11 Oct 2017 21:36:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2SPq-0002Fd-UB for bug-gnu-emacs@gnu.org; Wed, 11 Oct 2017 21:36:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:54208) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e2SPq-0002FV-QK for bug-gnu-emacs@gnu.org; Wed, 11 Oct 2017 21:36:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1e2SPq-0001n4-G1 for bug-gnu-emacs@gnu.org; Wed, 11 Oct 2017 21:36:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Robert Weiner Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 12 Oct 2017 01:36:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 28620 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 28620-submit@debbugs.gnu.org id=B28620.15077721566866 (code B ref 28620); Thu, 12 Oct 2017 01:36:02 +0000 Original-Received: (at 28620) by debbugs.gnu.org; 12 Oct 2017 01:35:56 +0000 Original-Received: from localhost ([127.0.0.1]:34656 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2SPj-0001mg-IS for submit@debbugs.gnu.org; Wed, 11 Oct 2017 21:35:56 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:48243) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2SPi-0001mR-4F for 28620@debbugs.gnu.org; Wed, 11 Oct 2017 21:35:54 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2SPZ-00023q-M6 for 28620@debbugs.gnu.org; Wed, 11 Oct 2017 21:35:48 -0400 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:34724) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2SPZ-00023Z-Gy for 28620@debbugs.gnu.org; Wed, 11 Oct 2017 21:35:45 -0400 Original-Received: from mail-qt0-f181.google.com ([209.85.216.181]:51698) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1e2SPZ-00016d-3F for 28620@debbugs.gnu.org; Wed, 11 Oct 2017 21:35:45 -0400 Original-Received: by mail-qt0-f181.google.com with SMTP id q4so10838649qtq.8 for <28620@debbugs.gnu.org>; Wed, 11 Oct 2017 18:35:45 -0700 (PDT) X-Gm-Message-State: AMCzsaXo1a2lcF4F/7ck/iRtzSKsRApnnz6WRV5Eq9P6PGd9EeN0uzq2 e8dGy6HuNo6khz2cFQ6mSzJaWRnNEOY3LWB/GA4= X-Google-Smtp-Source: AOwi7QD5fp18DoOQHTnPnieU70l4vkimlqewJOgNxJ0fYEYJhgr005d0NvWxEBFN/sLrMwbPbAdybcykEqxN0/Mnees= X-Received: by 10.200.48.74 with SMTP id g10mr1368275qte.121.1507772144632; Wed, 11 Oct 2017 18:35:44 -0700 (PDT) Original-Received: by 10.237.34.225 with HTTP; Wed, 11 Oct 2017 18:35:13 -0700 (PDT) In-Reply-To: X-Gmail-Original-Message-ID: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:138237 Archived-At: --001a113a0518154d2a055b4f8f22 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 wrote: > On Wed, Oct 11, 2017 at 1:16 PM, Robert Weiner wrote: > >> >> =E2=80=8BMartin wrote:=E2=80=8B >> >>> 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 =E2=80=98mouse-absolute-pixel-positi= on=E2=80=99 - it >>> should give you the screen position of the mouse at that time so you ca= n >>> ignore the event completely. >>> >>> Then walk all your windows and compare that position with whatever >>> =E2=80=98window-absolute-pixel-edges=E2=80=99 returns for that window. = If you have two >>> or more positives, run =E2=80=98frame-list-z-order=E2=80=99 and compare= the result >>> against those windows' frames. No hands, IMHO. >>> =E2=80=8B=E2=80=8B >>> >> =E2=80=8B=E2=80=8B > > =E2=80=8B Eli wrote: > =E2=80=8B=E2=80=8B > Why cannot you compute the frame at button release using the a > =E2=80=8B=E2=80=8B > lgorithm > proposed by Martin, given the mouse position at button release?= =E2=80=8B > > >> >>> =E2=80=8B=E2=80=8B >>> >> I w >> =E2=80=8B=E2=80=8B >> rote: >> =E2=80=8B >> =E2=80=8B=E2=80=8B >> frame-list-z-order is Emacs 26 only; I need something that works with >> older versions.=E2=80=8B >> =E2=80=8B=E2=80=8B >> =E2=80=8B=E2=80=8B >> 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. >> =E2=80=8B=E2=80=8B >> Thanks for the reminder. It does still seem to me that there should be = a >> function that takes a mouse position and returns >> =E2=80=8B=E2=80=8B >> the top-most Emacs window that the position is in or nil. I'll work on >> it. >> > =E2=80=8B=E2=80=8B > =E2=80=8B=E2=80=8B=E2=80=8BAnd now there is such a function. It was easi= er 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 (>=3D pos-x left) (<=3D pos-x right) > (>=3D pos-y top) (<=3D 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)) > --001a113a0518154d2a055b4f8f22 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I now have drags working across frames (after manipulating the= drag button release event data to include the proper window and coordinate= s, though only in Lisp right now).=C2=A0 As shown in the last message, I al= so have a function that finds the proper Emacs window given some display co= ordinates.=C2=A0 The only remaining problem seems to be that none of this a= ccounts for external application windows that may be obscuring an Emacs fra= me.

So if I have 2 frames, f1 and f2, and a Chrome web browser windo= w that is atop f2, then if I drag from f1 into Chrome above f2, my drag rel= ease code reports that the release window is in f2 rather than nil, as it s= hould be.=C2=A0 I am on macOS which uses click to focus, so Emacs still get= s the release event since Chrome has not been selected with a click.
<= div class=3D"gmail_default" style=3D"font-family:monospace,monospace">
<= /div>
Is there any way to deal with external window z-order layering such that o= ne 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@gnu.org> wrote:
On Wed, Oct 11, 2017 at 1:16 PM, Robert Wein= er <rsw@gnu.org> wrote:

=E2=80=8BMartin wrote:=E2=80=8B
=
Take the position of the ev= ent-end (if it's a frame) and translate it
into absolute screen coor= dinates (the Elisp manual should give you
enough clues to do that).=C2= =A0 Or, try =E2=80=98mouse-absolute-pixel-position=E2=80=99 - it
sh= ould give you the screen position of the mouse at that time so you can
i= gnore the event completely.

Then walk all your windows and compare t= hat position with whatever
=E2=80=98window-absolute-pixel-edges=E2=80=99= returns for that window.=C2=A0 If you have two
or more positives, run = =E2=80=98frame-list-z-order=E2=80=99 and compare the result
against thos= e windows' frames.=C2=A0 No hands, IMHO.
=E2=80=8B=E2=80=8B
=E2=80=8B=E2=80=8B
=C2=A0
=E2=80=8B=C2=A0 Eli wrote:
<= div class=3D"gmail_default" style=3D"font-family:monospace,monospace;displa= y:inline">=C2=A0 =C2=A0 =E2=80=8B=E2=80=8B
Why cannot you compute the = frame at button release using the a
=E2=80=8B=E2=80=8B
lgori= thm
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0proposed by Martin, given the mouse position at button release?= =E2=80=8B
=C2=A0
=C2=A0
=E2=80=8B=E2=80=8B
I w
=E2=80=8B=E2=80=8B
rote:
<= /span>
=C2=A0 =E2=80=8B=E2=80=8B=E2=80=8B
frame-list-z-order is Emacs 26 only; I need = something that works with older versions.=E2=80=8B
=E2=80=8B=E2=80=8B
=E2=80=8B=E2=80=8B
I'll see if I can make this work under E= macs 26 and then we can contemplate a solution that would apply to earlier = versions.
=E2=80=8B=E2=80= =8B
Thanks for the reminder.=C2=A0 It does still seem to me that there= should be a function that takes a mouse position and returns
=E2=80=8B=E2=80=8B
the top-most Ema= cs window that the position is in or nil.=C2=A0 I'll work on it.
<= /span>
=E2=80=8B=E2=80=8B
=E2=80=8B= =E2=80=8B=E2=80=8BAnd now there is such a function.=C2=A0 It was easier tha= n I expected thanks to Martin's pointers.=C2=A0 Now how can we make thi= s work (replacing frame-list-z-order) for Emacs versions prior to 26?=C2=A0= -- Bob

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

--001a113a0518154d2a055b4f8f22--