unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
@ 2017-10-12 16:27 Robert Weiner
  2017-10-12 16:42 ` Robert Weiner
  2017-10-13  9:57 ` Tak Kunihiro
  0 siblings, 2 replies; 16+ messages in thread
From: Robert Weiner @ 2017-10-12 16:27 UTC (permalink / raw)
  To: emacs-devel

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

Presently the function mouse-drag-and-drop-region works only within a
single frame.  The code attached below fixes that and allows for drops in
windows of other frames.  Please try it out and send feedback with any
issues.

There is one remaining issue that I see in the last 3 lines of the
function.  I would like to have focus shift to the frame of the drop since
typically one might be doing more editing there (maybe this could be an
option), but under the macOS windowing system, focus reverts to the source
window and frame rather than the one the code selects.  Is there a way to
make that work.

Bob

------

(setq mouse-drag-and-drop-region 'shift)

(defun mouse-drag-and-drop-region (event)
  "Move text in the region to point where mouse is dragged to.
The transportation of text is also referred as `drag and drop'.
When text is dragged over to a different buffer, or if a
modifier key was pressed when dropping, and the value of the
variable `mouse-drag-and-drop-region' is that modifier, the text
is copied instead of being cut."
  (interactive "e")
  (require 'tooltip)
  (let ((start (region-beginning))
        (end (region-end))
        (point (point))
        (buffer (current-buffer))
        (source-window (selected-window))
event-handler
release-pos
        value-selection)
    (track-mouse
      ;; When event was click instead of drag, skip loop
      (while (or (mouse-movement-p (setq event (read-event)))
(setq event-handler (and (consp event)
  (intern-soft (concat "handle-"
       (symbol-name
(event-basic-type event)))))))
(if (fboundp event-handler)
    (progn (funcall event-handler event) (setq event-handler nil))
  (setq event-handler nil))
          (unless value-selection ; initialization
            (delete-overlay mouse-secondary-overlay)
            (setq value-selection (buffer-substring start end))
            (move-overlay mouse-secondary-overlay start end)) ;
(deactivate-mark)
          (ignore-errors (deactivate-mark) ; deactivate any existing region
in other window
(mouse-set-point event)
(tooltip-show value-selection)))
      (tooltip-hide))
    ;; Do not modify buffer under mouse when "event was click",
    ;;                                       "drag negligible", or
    ;;                                       "drag to read-only".
    (if (or (equal (mouse-posn-property (event-end event) 'face) 'region) ;
"event was click"
    (and (setq release-point (posn-point (event-end event)))
(member 'secondary-selection ; "drag negligible"
(mapcar (lambda (xxx) (overlay-get xxx 'face))
(overlays-at release-point))))
            buffer-read-only)
        ;; Do not modify buffer under mouse.
        (cond
         ;; "drag negligible" or "drag to read-only", restore region.
         (value-selection
          (select-window source-window) ; In case miss drag to other window
          (goto-char point)
          (setq deactivate-mark nil)
          (activate-mark))
         ;; "event was click"
         (t
          (deactivate-mark)
          (mouse-set-point event)))
      ;; Modify buffer under mouse by inserting text.
      (push-mark)
      (insert value-selection)
      (when (not (equal (mark) (point))) ; on successful insert
        (setq deactivate-mark nil)
        (activate-mark)) ; have region on destination
        (let ((dest-window (selected-window))) ; when beyond buffer
  ;; Take care of initial region on source.
  (if (equal (current-buffer) buffer) ; when same buffer
              (let (deactivate-mark) ; remove text
(unless (member mouse-drag-and-drop-region (event-modifiers event))
  (kill-region (overlay-start mouse-secondary-overlay)
                               (overlay-end mouse-secondary-overlay))))
            (select-window source-window)
            (goto-char point) ; restore point in source-window
            (activate-mark)) ; restore region
  ;; Ensure change focus to any new frame; typically edits
  ;; would continue in its selected window where the text was
  ;; dropped.
          (select-frame (window-frame dest-window))
  (select-window dest-window)))
    (delete-overlay mouse-secondary-overlay)))

[-- Attachment #2: Type: text/html, Size: 11986 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-12 16:27 Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames Robert Weiner
@ 2017-10-12 16:42 ` Robert Weiner
  2017-10-12 17:11   ` Robert Weiner
  2017-10-13  9:57 ` Tak Kunihiro
  1 sibling, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-10-12 16:42 UTC (permalink / raw)
  To: emacs-devel

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

2 small fixes; release-point was misnamed in the let and indentation was
wrong in the latter part of the code.
Use this version.  -- Bob

(setq mouse-drag-and-drop-region 'shift)

(defun mouse-drag-and-drop-region (event)
  "Move text in the region to point where mouse is dragged to.
The transportation of text is also referred as `drag and drop'.
When text is dragged over to a different buffer, or if a
modifier key was pressed when dropping, and the value of the
variable `mouse-drag-and-drop-region' is that modifier, the text
is copied instead of being cut."
  (interactive "e")
  (require 'tooltip)
  (let ((start (region-beginning))
        (end (region-end))
        (point (point))
        (buffer (current-buffer))
        (source-window (selected-window))
event-handler
release-point
        value-selection)
    (track-mouse
      ;; When event was click instead of drag, skip loop
      (while (or (mouse-movement-p (setq event (read-event)))
(setq event-handler (and (consp event)
  (intern-soft (concat "handle-"
       (symbol-name
(event-basic-type event)))))))
(if (fboundp event-handler)
    (progn (funcall event-handler event) (setq event-handler nil))
  (setq event-handler nil))
        (unless value-selection ; initialization
          (delete-overlay mouse-secondary-overlay)
          (setq value-selection (buffer-substring start end))
          (move-overlay mouse-secondary-overlay start end)) ;
(deactivate-mark)
        (ignore-errors (deactivate-mark) ; deactivate any existing region
in other window
       (mouse-set-point event)
       (tooltip-show value-selection)))
      (tooltip-hide))
    ;; Do not modify buffer under mouse when "event was click",
    ;;                                       "drag negligible", or
    ;;                                       "drag to read-only".
    (if (or (equal (mouse-posn-property (event-end event) 'face) 'region) ;
"event was click"
    (and (setq release-point (posn-point (event-end event)))
(member 'secondary-selection ; "drag negligible"
(mapcar (lambda (xxx) (overlay-get xxx 'face))
(overlays-at release-point))))
            buffer-read-only)
        ;; Do not modify buffer under mouse.
        (cond
         ;; "drag negligible" or "drag to read-only", restore region.
         (value-selection
          (select-window source-window) ; In case miss drag to other window
          (goto-char point)
          (setq deactivate-mark nil)
          (activate-mark))
         ;; "event was click"
         (t
          (deactivate-mark)
          (mouse-set-point event)))
      ;; Modify buffer under mouse by inserting text.
      (push-mark)
      (insert value-selection)
      (when (not (equal (mark) (point))) ; on successful insert
        (setq deactivate-mark nil)
        (activate-mark)) ; have region on destination
      (let ((dest-window (selected-window))) ; when beyond buffer
;; Take care of initial region on source.
(if (equal (current-buffer) buffer) ; when same buffer
            (let (deactivate-mark)     ; remove text
      (unless (member mouse-drag-and-drop-region (event-modifiers event))
(kill-region (overlay-start mouse-secondary-overlay)
                             (overlay-end mouse-secondary-overlay))))
          (select-window source-window)
          (goto-char point)       ; restore point in source-window
          (activate-mark))       ; restore region
;; Ensure change focus to any new frame; typically edits
;; would continue in its selected window where the text was
;; dropped.
        (select-frame (window-frame dest-window))
(select-window dest-window)))
    (delete-overlay mouse-secondary-overlay)))

[-- Attachment #2: Type: text/html, Size: 11269 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-12 16:42 ` Robert Weiner
@ 2017-10-12 17:11   ` Robert Weiner
  0 siblings, 0 replies; 16+ messages in thread
From: Robert Weiner @ 2017-10-12 17:11 UTC (permalink / raw)
  To: emacs-devel

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

I rewrote the doc strings for clarity.  -- Bob

(defcustom mouse-drag-and-drop-region nil
  "If non-nil, then text regions can be dragged and dropped to new
locations.
Normally, drops within the same buffer move the text of the region; drops
to a different buffer copy the region.  However, if this value is a modifier
symbol, such as `control' or `shift' or `meta', and the matching modifier
key is pressed when dropping the region, then the region text is always
copied.  The drop location must be within the text area of an Emacs window."
  :type 'symbol
  :version "26.1"
  :group 'mouse)

(defun mouse-drag-and-drop-region (event)
  "Drag and drop the active region text to the point of mouse button
release.
Normally, drops within the same buffer move the region text and drops
to a different buffer copy it.  However, if a modifier key is pressed
when dropping, and the value of the variable `mouse-drag-and-drop-region'
is the symbol for that modifier, then the text is always copied.  The drop
location must be within the text area of an Emacs window."


On Thu, Oct 12, 2017 at 12:42 PM, Robert Weiner <rsw@gnu.org> wrote:

> 2 small fixes; release-point was misnamed in the let and indentation was
> wrong in the latter part of the code.
> Use this version.  -- Bob
>
> (setq mouse-drag-and-drop-region 'shift)
>
> (defun mouse-drag-and-drop-region (event)
>   "Move text in the region to point where mouse is dragged to.
> The transportation of text is also referred as `drag and drop'.
> When text is dragged over to a different buffer, or if a
> modifier key was pressed when dropping, and the value of the
> variable `mouse-drag-and-drop-region' is that modifier, the text
> is copied instead of being cut."
>   (interactive "e")
>   (require 'tooltip)
>   (let ((start (region-beginning))
>         (end (region-end))
>         (point (point))
>         (buffer (current-buffer))
>         (source-window (selected-window))
> event-handler
> release-point
>         value-selection)
>     (track-mouse
>       ;; When event was click instead of drag, skip loop
>       (while (or (mouse-movement-p (setq event (read-event)))
> (setq event-handler (and (consp event)
>   (intern-soft (concat "handle-"
>        (symbol-name
> (event-basic-type event)))))))
> (if (fboundp event-handler)
>     (progn (funcall event-handler event) (setq event-handler nil))
>   (setq event-handler nil))
>         (unless value-selection ; initialization
>           (delete-overlay mouse-secondary-overlay)
>           (setq value-selection (buffer-substring start end))
>           (move-overlay mouse-secondary-overlay start end)) ;
> (deactivate-mark)
>         (ignore-errors (deactivate-mark) ; deactivate any existing region
> in other window
>        (mouse-set-point event)
>        (tooltip-show value-selection)))
>       (tooltip-hide))
>     ;; Do not modify buffer under mouse when "event was click",
>     ;;                                       "drag negligible", or
>     ;;                                       "drag to read-only".
>     (if (or (equal (mouse-posn-property (event-end event) 'face) 'region)
> ; "event was click"
>     (and (setq release-point (posn-point (event-end event)))
> (member 'secondary-selection ; "drag negligible"
> (mapcar (lambda (xxx) (overlay-get xxx 'face))
> (overlays-at release-point))))
>             buffer-read-only)
>         ;; Do not modify buffer under mouse.
>         (cond
>          ;; "drag negligible" or "drag to read-only", restore region.
>          (value-selection
>           (select-window source-window) ; In case miss drag to other window
>           (goto-char point)
>           (setq deactivate-mark nil)
>           (activate-mark))
>          ;; "event was click"
>          (t
>           (deactivate-mark)
>           (mouse-set-point event)))
>       ;; Modify buffer under mouse by inserting text.
>       (push-mark)
>       (insert value-selection)
>       (when (not (equal (mark) (point))) ; on successful insert
>         (setq deactivate-mark nil)
>         (activate-mark)) ; have region on destination
>       (let ((dest-window (selected-window))) ; when beyond buffer
> ;; Take care of initial region on source.
> (if (equal (current-buffer) buffer) ; when same buffer
>             (let (deactivate-mark)     ; remove text
>       (unless (member mouse-drag-and-drop-region (event-modifiers event))
> (kill-region (overlay-start mouse-secondary-overlay)
>                              (overlay-end mouse-secondary-overlay))))
>           (select-window source-window)
>           (goto-char point)       ; restore point in source-window
>           (activate-mark))       ; restore region
> ;; Ensure change focus to any new frame; typically edits
> ;; would continue in its selected window where the text was
> ;; dropped.
>         (select-frame (window-frame dest-window))
> (select-window dest-window)))
>     (delete-overlay mouse-secondary-overlay)))
>

[-- Attachment #2: Type: text/html, Size: 14495 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-12 16:27 Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames Robert Weiner
  2017-10-12 16:42 ` Robert Weiner
@ 2017-10-13  9:57 ` Tak Kunihiro
  2017-10-16 13:45   ` Robert Weiner
  1 sibling, 1 reply; 16+ messages in thread
From: Tak Kunihiro @ 2017-10-13  9:57 UTC (permalink / raw)
  To: Robert Weiner; +Cc: rswgnu, emacs-devel

I tried the revised `mouse-drag-and-drop-region' on Emacs -Q 26.0.90 on
macOS 10.9.5.  I can drag text within a frame but cannot do so among
frames.  I think I miss something.  Do you have idea?



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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-13  9:57 ` Tak Kunihiro
@ 2017-10-16 13:45   ` Robert Weiner
  2017-10-16 14:13     ` Robert Weiner
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-10-16 13:45 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: emacs-devel

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

On Fri, Oct 13, 2017 at 5:57 AM, Tak Kunihiro <homeros.misasa@gmail.com>
wrote:

> I tried the revised `mouse-drag-and-drop-region' on Emacs -Q 26.0.90 on
> macOS 10.9.5.  I can drag text within a frame but cannot do so among
> frames.  I think I miss something.  Do you have idea?
>

​The yellow visual rectangle of the text being dragged seems to get stuck
at the source frame but if you continue your drag and release in another
frame with a non-read-only buffer, your text should be properly dropped
there.  Is this what you did?  Try it a couple different times to ensure
there is not some initialization warm up problem.

For clarity, here is the latest code:

(defcustom mouse-drag-and-drop-region nil
  "If non-nil, then text regions can be dragged and dropped to new
locations.
Normally, drops within the same buffer move the text of the region; drops
to a different buffer copy the region.  However, if this value is a modifier
symbol, such as `control' or `shift' or `meta', and the matching modifier
key is pressed when dropping the region, then the region text is always
copied.  The drop location must be within the text area of an Emacs window."
  :type 'symbol
  :version "26.1"
  :group 'mouse)

(defun mouse-drag-and-drop-region (event)
  "Drag and drop the active region text to the point of mouse button
release.
Normally, drops within the same buffer move the region text and drops
to a different buffer copy it.  However, if a modifier key is pressed
when dropping, and the value of the variable `mouse-drag-and-drop-region'
is the symbol for that modifier, then the text is always copied.  The drop
location must be within the text area of an Emacs window."
  (interactive "e")
  (require 'tooltip)
  (let ((start (region-beginning))
        (end (region-end))
        (point (point))
        (buffer (current-buffer))
        (source-window (selected-window))
event-handler
release-point
        value-selection)
    (track-mouse
      ;; When event was click instead of drag, skip loop
      (while (or (mouse-movement-p (setq event (read-event)))
(setq event-handler (and (consp event)
  (intern-soft (concat "handle-"
       (symbol-name
(event-basic-type event)))))))
(if (fboundp event-handler)
    (progn (funcall event-handler event) (setq event-handler nil))
  (setq event-handler nil))
        (unless value-selection ; initialization
          (delete-overlay mouse-secondary-overlay)
          (setq value-selection (buffer-substring start end))
          (move-overlay mouse-secondary-overlay start end)) ;
(deactivate-mark)
        (ignore-errors (deactivate-mark) ; deactivate any existing region
in other window
       (mouse-set-point event)
       (tooltip-show value-selection)))
      (tooltip-hide))
    ;; Do not modify buffer under mouse when "event was click",
    ;;                                       "drag negligible", or
    ;;                                       "drag to read-only".
    (if (or (equal (mouse-posn-property (event-end event) 'face) 'region) ;
"event was click"
    (and (setq release-point (posn-point (event-end event)))
(member 'secondary-selection ; "drag negligible"
(mapcar (lambda (xxx) (overlay-get xxx 'face))
(overlays-at release-point))))
            buffer-read-only)
        ;; Do not modify buffer under mouse.
        (cond
         ;; "drag negligible" or "drag to read-only", restore region.
         (value-selection
          (select-window source-window) ; In case miss drag to other window
          (goto-char point)
          (setq deactivate-mark nil)
          (activate-mark))
         ;; "event was click"
         (t
          (deactivate-mark)
          (mouse-set-point event)))
      ;; Modify buffer under mouse by inserting text.
      (push-mark)
      (insert value-selection)
      (when (not (equal (mark) (point))) ; on successful insert
        (setq deactivate-mark nil)
        (activate-mark)) ; have region on destination
      (let ((dest-window (selected-window))) ; when beyond buffer
;; Take care of initial region on source.
(if (equal (current-buffer) buffer) ; when same buffer
            (let (deactivate-mark)     ; remove text
      (unless (member mouse-drag-and-drop-region (event-modifiers event))
(kill-region (overlay-start mouse-secondary-overlay)
                             (overlay-end mouse-secondary-overlay))))
          (select-window source-window)
          (goto-char point)       ; restore point in source-window
          (activate-mark))       ; restore region
;; Ensure change focus to any new frame; typically edits
;; would continue in its selected window where the text was
;; dropped.
        (select-frame (window-frame dest-window))
(select-window dest-window)))
    (delete-overlay mouse-secondary-overlay)))

​

[-- Attachment #2: Type: text/html, Size: 13841 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-16 13:45   ` Robert Weiner
@ 2017-10-16 14:13     ` Robert Weiner
  2017-10-19  0:43       ` Tak Kunihiro
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-10-16 14:13 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: emacs-devel

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

On Mon, Oct 16, 2017 at 9:45 AM, Robert Weiner <rsw@gnu.org> wrote:

> On Fri, Oct 13, 2017 at 5:57 AM, Tak Kunihiro <homeros.misasa@gmail.com>
> wrote:
>
>> I tried the revised `mouse-drag-and-drop-region' on Emacs -Q 26.0.90 on
>> macOS 10.9.5.  I can drag text within a frame but cannot do so among
>> frames.  I think I miss something.  Do you have idea?
>>
>
> ​The yellow visual rectangle of the text being dragged seems to get stuck
> at the source frame but if you continue your drag and release in another
> frame with a non-read-only buffer, your text should be properly dropped
> there.  Is this what you did?  Try it a couple different times to ensure
> there is not some initialization warm up problem.
>

​I see the issue now; the standard Emacs code does not handle cross-frame
drags well.  Replace the mouse-set-point function from mouse.el with the
version below and then the yellow rectangle of text will follow you to the
drag release frame and your drag-and-drops should work as you expect (with
the mouse-drag-and-drop-region changes from before).  -- Bob​

(defun mouse-set-point (event &optional promote-to-region)
  "Move point to the position clicked on with the mouse.
This should be bound to a mouse click event type.
If PROMOTE-TO-REGION is non-nil and event is a multiple-click,
select the corresponding element around point, with the resulting position
of
point determined by `mouse-select-region-move-to-beginning'."
  (interactive "e\np")
  (let ((start-w-or-f (posn-window (event-start event)))
(end-w-or-f   (posn-window (event-end event))))
    (if (framep start-w-or-f)
(with-selected-frame start-w-or-f (setq start-w-or-f (selected-window))))
    (if (framep end-w-or-f)
(with-selected-frame end-w-or-f (setq end-w-or-f (selected-window))))
    (if (and (window-minibuffer-p start-w-or-f)
     (not (minibuffer-window-active-p start-w-or-f)))
;; Select the ending frame only, not the window pressed within.
(select-frame (window-frame end-w-or-f))
      ;; Give temporary modes such as isearch a chance to turn off.
      (run-hooks 'mouse-leave-buffer-hook)
      (if (and promote-to-region (> (event-click-count event) 1))
  (progn (mouse-set-region event)
(when (and (boundp 'mouse-select-region-move-to-beginning)
    mouse-select-region-move-to-beginning)
   (when (> (posn-point (event-start event)) (region-beginning))
     (exchange-point-and-mark))))
;; Use event-end in case called from mouse-drag-region.
;; If EVENT is a click, event-end and event-start give same value.
(if (and (window-minibuffer-p end-w-or-f)
(not (minibuffer-window-active-p end-w-or-f)))
    ;; Select the ending frame only, not the window pressed within.
    (select-frame (window-frame end-w-or-f))
  (condition-case ()
      (posn-set-point (event-end event))
    (error (select-frame (window-frame end-w-or-f)))))))))

[-- Attachment #2: Type: text/html, Size: 6714 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-16 14:13     ` Robert Weiner
@ 2017-10-19  0:43       ` Tak Kunihiro
  2017-10-26 22:07         ` Robert Weiner
  0 siblings, 1 reply; 16+ messages in thread
From: Tak Kunihiro @ 2017-10-19  0:43 UTC (permalink / raw)
  To: Robert Weiner; +Cc: Tak Kunihiro, rswgnu, emacs-devel

>>>  I tried the revised `mouse-drag-and-drop-region' on Emacs -Q
>>>  26.0.90 on macOS 10.9.5. I can drag text within a frame but cannot
>>>  do so among frames. I think I miss something. Do you have idea?
>>
> ​I see the issue now; the standard Emacs code does not handle
> cross-frame drags well. Replace the mouse-set-point function from
> mouse.el with the version below

GNU Emacs 27.0.50 (build 1, x86_64-apple-darwin13.4.0, NS appkit-1265.21 Version 10.9.5 (Build 13F1911)) of 2017-10-17
Emacs -Q

I cannot drag text among frames yet.  I think I still miss something.
Can you show recipe that starts from emacs -Q?



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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-19  0:43       ` Tak Kunihiro
@ 2017-10-26 22:07         ` Robert Weiner
  2017-11-01  2:04           ` Tak Kunihiro
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-10-26 22:07 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: emacs-devel

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

On Wed, Oct 18, 2017 at 8:43 PM, Tak Kunihiro <homeros.misasa@gmail.com>
wrote:

> >>>  I tried the revised `mouse-drag-and-drop-region' on Emacs -Q
> >>>  26.0.90 on macOS 10.9.5. I can drag text within a frame but cannot
> >>>  do so among frames. I think I miss something. Do you have idea?
> >>
> > ​I see the issue now; the standard Emacs code does not handle
> > cross-frame drags well. Replace the mouse-set-point function from
> > mouse.el with the version below
>
> GNU Emacs 27.0.50 (build 1, x86_64-apple-darwin13.4.0, NS appkit-1265.21
> Version 10.9.5 (Build 13F1911)) of 2017-10-17
> Emacs -Q
>
> I cannot drag text among frames yet.  I think I still miss something.
> Can you show recipe that starts from emacs -Q?
>

​See if adding this fixes it:

    ;; 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."
    (if frame-x-dot-y (setcar frame-x-dot-y (selected-frame)))
    frame-x-dot-y))​

[-- Attachment #2: Type: text/html, Size: 3530 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-10-26 22:07         ` Robert Weiner
@ 2017-11-01  2:04           ` Tak Kunihiro
  2017-11-01 15:24             ` Robert Weiner
  0 siblings, 1 reply; 16+ messages in thread
From: Tak Kunihiro @ 2017-11-01  2:04 UTC (permalink / raw)
  To: Robert Weiner; +Cc: Tak Kunihiro, rswgnu, emacs-devel

>  I cannot drag text among frames yet. I think I still miss something.
>  Can you show recipe that starts from emacs -Q?
>
> ​See if adding this fixes it:
>
> (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."
> 		    (if frame-x-dot-y (setcar frame-x-dot-y (selected-frame)))
> 		    frame-x-dot-y))

;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00804.html
;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00591.html
;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00588.html

;; GNU Emacs 27.0.50 (build 2, x86_64-apple-darwin13.4.0, NS appkit-1265.21 Version 10.9.5 (Build 13F1911))
;;  of 2017-11-01
;; ./Emacs -Q
;; M-x eval-buffer

I start to see yellow preview text by tooltip on destination frame.
However, I cannot drop the text yet.  I still miss something.



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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-01  2:04           ` Tak Kunihiro
@ 2017-11-01 15:24             ` Robert Weiner
  2017-11-01 17:16               ` Alan Third
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-11-01 15:24 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: emacs-devel

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

On Tue, Oct 31, 2017 at 10:04 PM, Tak Kunihiro <homeros.misasa@gmail.com>
wrote:

> >  I cannot drag text among frames yet. I think I still miss something.
> >  Can you show recipe that starts from emacs -Q?
> >
> > ​See if adding this fixes it:
> >
> > (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."
> >                   (if frame-x-dot-y (setcar frame-x-dot-y
> (selected-frame)))
> >                   frame-x-dot-y))
>
> ;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00804.html
> ;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00591.html
> ;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00588.html
>
> ;; GNU Emacs 27.0.50 (build 2, x86_64-apple-darwin13.4.0, NS
> appkit-1265.21 Version 10.9.5 (Build 13F1911))
> ;;  of 2017-11-01
> ;; ./Emacs -Q
> ;; M-x eval-buffer
>
> I start to see yellow preview text by tooltip on destination frame.
> However, I cannot drop the text yet.  I still miss something.
>

​Maybe it would be best if someone fixed the XSETFRAME macro in
​mouse-position so it works properly under the macOS window system so we
could avoid any work arounds on this.  -- 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.

[-- Attachment #2: Type: text/html, Size: 3357 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-01 15:24             ` Robert Weiner
@ 2017-11-01 17:16               ` Alan Third
  2017-11-01 20:18                 ` Robert Weiner
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Third @ 2017-11-01 17:16 UTC (permalink / raw)
  To: rswgnu; +Cc: Tak Kunihiro, emacs-devel

On Wed, Nov 01, 2017 at 11:24:44AM -0400, Robert Weiner wrote:
> ​Maybe it would be best if someone fixed the XSETFRAME macro in
> ​mouse-position so it works properly under the macOS window system so we
> could avoid any work arounds on this.  -- 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.

That’s not the problem. I’ve explained this to you before.

ns_mouse_position uses dpyinfo->last_mouse_frame, which is set in
mouseDown. MouseDown is *not called* on macOS for the first click,
instead the frame is selected.

This means, like other macOS applications, the first click in the
window JUST selects that window, it has no other effect.

The docstring for mouse-position says:

    Return a list (FRAME X . Y) giving the current mouse frame and
    position.

To my way of reading that, ‘current mouse frame’ != ‘current selected
frame’, it will be the last frame that a mouse action of some sort was
registered in.

On macOS that doesn’t include the first click in the frame as it’s not
registered as an input by Emacs.

Is this behaviour wrong? I don’t know, but it seems to match the
documentation.

I’m sure Martin suggested this before, but if you’re trying to
implement cross‐frame/window dragging, would it not be better to try
and use the standard implementation for each platform?
-- 
Alan Third



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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-01 17:16               ` Alan Third
@ 2017-11-01 20:18                 ` Robert Weiner
  2017-11-01 20:41                   ` Robert Weiner
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-11-01 20:18 UTC (permalink / raw)
  To: Alan Third; +Cc: Tak Kunihiro, emacs-devel

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

Alan:

I always appreciate your detailed knowledge here but something needs
to change with the frame handling code.  Through Lisp changes most of
which are independent of the window system, I have made cross-frame
drags work in a natural and useful manner, similar to how clicking on a
window
or frame works naturally now.  The changes simply rely on which frame
is currently selected, so they do not involve or require any changes to
whether or not the window system requires a click to select a frame.

But the changes are more complex than I'd like and are tied in with the
elaborate mouse handling that the Hyperbole package provides.  They really
should be done at the C-level so that they affect all cross-frame drags and
make them operate naturally.  This should be part of the discussion here.

On Wed, Nov 1, 2017 at 1:16 PM, Alan Third <alan@idiocy.org> wrote:

> On Wed, Nov 01, 2017 at 11:24:44AM -0400, Robert Weiner wrot
> ​​
> e:
> > ​Maybe it would be best if someone fixed the XSETFRAME mac
> ​​
> ro in
> > ​mouse-position so it works properly under the macOS window s
> ​​
> ystem so we
> > could avoid any work arounds on this.  -- 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.
> ​​
>
> ​​
> That’s not the problem. I’ve explained this to you before.
>
​​
​​Just to be clear, you are saying that in the calls above, you believe
that lispy_dummy ends up with the value of f (whatever that is), not the
frame prior to the selected frame, correct?

​​
>
> ​​
> ns_mouse_position uses dpyinfo->last_mouse_frame, which is set in
> ​​
> mouseDown. MouseDown is *not called* on macOS for the first click,
> ​​
> instead the frame is selected.
> ​​
>
> ​​
> This means, like other macOS applications, the first click in the
> ​​
> window JUST selects that window, it has no other effect.
>

​So that is what is done now but I don't believe there
is any particular use case that requires it stay this
way.  We could trigger an update to that data structure
whenever a new frame is selected, couldn't we?​
​​

> ​​
>
> ​​
> The docstring for mouse-position says:
> ​​
>
> ​​
>     Return a list (FRAME X . Y) giving the current mouse frame and
> ​​
>     position.
> ​​
>
> ​​
> To my way of reading that, ‘current mouse frame’ != ‘current selected
> ​​
> frame’, it will be the last frame that a mouse action of some sort was
> ​​
> registered in.
>

​I see what you are saying but I don't see a use case.
I see many use cases for having those two values be the
same.​

So what triggers dpyinfo->last_mouse_frame to change?
Another mouse event?  Why not a select-frame event?

​​
>
> ​​
> On macOS that doesn’t include the first click in the frame as it’s not
> ​​
> registered as an input by Emacs.
>

​But Emacs does receive a select-frame or a focus-in
event, so that could be utilized to trigger any updates
necessary.  Do you agree with that?
​

> ​​
>
> ​​
> Is this behaviour wrong? I don’t know, but it seems to match the
> ​​
> documentation.
>

​We need Emacs to do useful things.  If there is no
active use for this behavior and it actually prevents
obvious things such as cross-frame drags from working right,
then it should be changed independent of any conformance
to existing documentation.

Take the simple example of using a drag to swap the buffers
in two Emacs windows.  Presently, you can do this pretty easily
in a single frame but not across frames.  Why should the behavior
be any different?  Would users ever prefer two different
behaviors; not likely, since they would just think in terms of windows
and not really care about any of the mechanics.  I have this
working across frames and it is pretty effortless in use and
quite involved in implementation because the basic functions
like mouse-position do not presently allow for cross-frame drags
on macOS.
​​


> ​​
>
> ​​
> I’m sure Martin suggested this before, but if you’re trying to
> ​​
> implement cross‐frame/window dragging, would it not be better to try
> ​​
> and use the standard implementation for each platform?
>

​Most of my interest is in dragging between Emacs frames, with a little
interest for drags outside of Emacs.  I think the mechanics of internal
dragging can be dealt with separately from per-platform drag-and-drop
across applications.

I hope this at least sparks your interest in helping to improve
the core Emacs behavior here.

Bob
​​
​​
​​
​​

[-- Attachment #2: Type: text/html, Size: 14986 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-01 20:18                 ` Robert Weiner
@ 2017-11-01 20:41                   ` Robert Weiner
  2017-11-02  9:51                     ` martin rudalics
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-11-01 20:41 UTC (permalink / raw)
  To: Alan Third; +Cc: Tak Kunihiro, emacs-devel

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

I have been using this snippet without a problem for a while.  Is it
sufficient
to resolve the issues we are discussing with mouse-position and
mouse-pixel-position?

    (setq mouse-position-function
  (lambda (frame-x-dot-y)
    "Under macOS and Windows 7, mouse-position and mouse-pixel-position
sometimes return the prior frame; change to always return the selected
frame."
    (if (consp frame-x-dot-y) (setcar frame-x-dot-y (selected-frame)))
    frame-x-dot-y))

Bob

[-- Attachment #2: Type: text/html, Size: 1269 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-01 20:41                   ` Robert Weiner
@ 2017-11-02  9:51                     ` martin rudalics
  2017-11-02 19:00                       ` Robert Weiner
  0 siblings, 1 reply; 16+ messages in thread
From: martin rudalics @ 2017-11-02  9:51 UTC (permalink / raw)
  To: rswgnu, Alan Third; +Cc: Tak Kunihiro, emacs-devel

 > I have been using this snippet without a problem for a while.  Is it
 > sufficient
 > to resolve the issues we are discussing with mouse-position and
 > mouse-pixel-position?
 >
 >      (setq mouse-position-function
 >    (lambda (frame-x-dot-y)
 >      "Under macOS and Windows 7, mouse-position and mouse-pixel-position
 > sometimes return the prior frame; change to always return the selected
 > frame."
 >      (if (consp frame-x-dot-y) (setcar frame-x-dot-y (selected-frame)))
 >      frame-x-dot-y))


I don't have the slightest idea why you wanted to do that.

‘frame-x-dot-y’ should be the Emacs frame under the mouse which is not
necessarily the selected frame.  Why do you want it to be the selected
frame?  Don't you want to drop your object on the frame under the mouse?

martin




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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-02  9:51                     ` martin rudalics
@ 2017-11-02 19:00                       ` Robert Weiner
  2017-11-02 20:16                         ` martin rudalics
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Weiner @ 2017-11-02 19:00 UTC (permalink / raw)
  To: martin rudalics; +Cc: Alan Third, Tak Kunihiro, emacs-devel

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

On Thu, Nov 2, 2017 at 5:51 AM, martin rudalics <rudalics@gmx.at> wrote:

>
> ‘frame-x-dot-y’ should be the Emacs frame under the mouse which is not
> necessarily the selected frame.  Why do you want it to be the selected
> ​​
> frame?  Don't you want to drop your object on the frame under the mouse?

​​
​I see your point and agree.
​​
​But this is not what mouse-position and ​pixel-position return by default
(when mouse-position-function is nil)
on MacOS.  They always return the last registered frame which is the frame
that was last clicked upon twice (as you
have noted, a single click does not register with Emacs but only selects
the frame).  This seemed to be the case under
Windows 7 for me as well, using Emacs -q under Emacs 25.3 and Emacs 26.

Since I always reference the mouse position after a click or drag and can
make the new frame be selected after a drag,
I wrote the function this way to give me the most recently selected frame.

There needs to be a fix in the core of Emacs so these functions can return
the frame under the mouse regardless of how
the window manager handles selecting frames, I think.

Bob

[-- Attachment #2: Type: text/html, Size: 2927 bytes --]

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

* Re: Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames
  2017-11-02 19:00                       ` Robert Weiner
@ 2017-11-02 20:16                         ` martin rudalics
  0 siblings, 0 replies; 16+ messages in thread
From: martin rudalics @ 2017-11-02 20:16 UTC (permalink / raw)
  To: rswgnu; +Cc: Alan Third, Tak Kunihiro, emacs-devel

 > This seemed to be the case under
 > Windows 7 for me as well, using Emacs -q under Emacs 25.3 and Emacs 26.
[...]
 > There needs to be a fix in the core of Emacs so these functions can return
 > the frame under the mouse regardless of how
 > the window manager handles selecting frames, I think.

As fas as Windows 7 is concerned, have a look at w32term.c.  In the
function w32_mouse_position you will see a call to GetCursorPos which
should retrieve the position of the mouse cursor into pt.  Then you will
see the check for x_mouse_grabbed.  If this check succeeds, then the
frame where the mouse was initially grabbed is taken.  Otherwise,
calling WindowFromPoint will try to get the window wfp at pt.  If the
call succeeds, the call of x_any_window_to_frame tries to establish the
Emacs frame f1 from wfp.

Step with GDB through these lines and you will see where it fails to
retrieve the frame under the mouse cursor.  If the problem is with the
x_mouse_grabbed check then the explanation is obvious: Mouse drags by
design only work within one and the same frame.  Otherwise we have to
dig further.

martin

BTW: Have a look at https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19988
where this issue has been discussed already in some depth.



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

end of thread, other threads:[~2017-11-02 20:16 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-12 16:27 Emacs 26: Code that fixes mouse-drag-and-drop-region to work across frames Robert Weiner
2017-10-12 16:42 ` Robert Weiner
2017-10-12 17:11   ` Robert Weiner
2017-10-13  9:57 ` Tak Kunihiro
2017-10-16 13:45   ` Robert Weiner
2017-10-16 14:13     ` Robert Weiner
2017-10-19  0:43       ` Tak Kunihiro
2017-10-26 22:07         ` Robert Weiner
2017-11-01  2:04           ` Tak Kunihiro
2017-11-01 15:24             ` Robert Weiner
2017-11-01 17:16               ` Alan Third
2017-11-01 20:18                 ` Robert Weiner
2017-11-01 20:41                   ` Robert Weiner
2017-11-02  9:51                     ` martin rudalics
2017-11-02 19:00                       ` Robert Weiner
2017-11-02 20:16                         ` martin rudalics

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).