From 1e1a66831bf1d8ca33b3ad37d23211fa98d92e63 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Tue, 5 Apr 2022 00:54:03 +0000 Subject: [PATCH] Respect new DND options when dragging to ourselves on Haiku * lisp/mouse.el (mouse-drag-and-drop-region): Allow dragging to the current frame if we know `return-frame' doesn't work. * lisp/term/haiku-win.el (haiku-dnd-drag-handler): New function. * src/haiku_support.cc (MouseMoved): Don't send drag motion events for the drag frame. * src/haikuselect.c (haiku_note_drag_motion_1) (haiku_note_drag_motion_2, haiku_note_drag_motion): New functions. (syms_of_haikuselect): New variable `haiku-drag-track-function'. * src/haikuterm.c (haiku_read_socket): Note mouse motion in that case.q * src/haikuterm.h: Update prototypes. --- lisp/mouse.el | 7 ++++++- lisp/term/haiku-win.el | 15 +++++++++++++++ src/haiku_support.cc | 14 ++++++++++++-- src/haikuselect.c | 28 ++++++++++++++++++++++++++++ src/haikuterm.c | 3 +++ src/haikuterm.h | 1 + 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/lisp/mouse.el b/lisp/mouse.el index 26a17365da2..b66cfad4878 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -3190,7 +3190,12 @@ is copied instead of being cut." (if mouse-drag-and-drop-region-cut-when-buffers-differ 'XdndActionMove 'XdndActionCopy) - (posn-window (event-end event)) 'now) + (posn-window (event-end event)) 'now + ;; On platforms where we know + ;; `return-frame' doesn't + ;; work, allow dropping on + ;; the drop frame. + (eq window-system 'haiku)) (quit nil)))) (when (framep drag-action-or-frame) ;; With some window managers `x-begin-drag' diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 5b4ef0aaef8..fd0b68b5fcb 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -277,6 +277,21 @@ This is necessary because on Haiku `use-system-tooltip' doesn't take effect on menu items until the menu bar is updated again." (force-mode-line-update t)) +;; Note that `mouse-position' can't return the actual frame the mouse +;; pointer is under, so this only works for the frame where the drop +;; started. +(defun haiku-dnd-drag-handler () + "Handle mouse movement during drag-and-drop." + (let ((track-mouse 'drag-source) + (mouse-position (mouse-pixel-position))) + (when (car mouse-position) + (dnd-handle-movement (posn-at-x-y (cadr mouse-position) + (cddr mouse-position) + (car mouse-position))) + (redisplay)))) + +(setq haiku-drag-track-function #'haiku-dnd-drag-handler) + (defun x-begin-drag (targets &optional action frame _return-frame allow-current-frame) "SKIP: real doc in xfns.c." (unless haiku-dnd-selection-value diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 40112e2b717..830255d3f07 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1524,13 +1524,23 @@ public: MouseMoved (BPoint point, uint32 transit, const BMessage *drag_msg) { struct haiku_mouse_motion_event rq; + int32 windowid; + EmacsWindow *window; + window = (EmacsWindow *) Window (); rq.just_exited_p = transit == B_EXITED_VIEW; rq.x = point.x; rq.y = point.y; - rq.window = this->Window (); + rq.window = window; rq.time = system_time (); - rq.dnd_message = drag_msg != NULL; + + if (drag_msg && (drag_msg->IsSourceRemote () + || drag_msg->FindInt32 ("emacs:window_id", + &windowid) != B_OK + || windowid != window->window_id)) + rq.dnd_message = true; + else + rq.dnd_message = false; if (ToolTip ()) ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x), diff --git a/src/haikuselect.c b/src/haikuselect.c index f6199ccc1e7..c3053688f5a 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -791,6 +791,28 @@ ignored if it is dropped on top of FRAME. */) return unbind_to (idx, Qnil); } +static Lisp_Object +haiku_note_drag_motion_1 (void *data) +{ + if (!NILP (Vhaiku_drag_track_function)) + return call0 (Vhaiku_drag_track_function); + + return Qnil; +} + +static Lisp_Object +haiku_note_drag_motion_2 (enum nonlocal_exit exit, Lisp_Object error) +{ + return Qnil; +} + +void +haiku_note_drag_motion (void) +{ + internal_catch_all (haiku_note_drag_motion_1, NULL, + haiku_note_drag_motion_2); +} + void syms_of_haikuselect (void) { @@ -800,6 +822,12 @@ Otherwise, an error will be signalled if adding a file reference to a system message failed. */); haiku_signal_invalid_refs = true; + DEFVAR_LISP ("haiku-drag-track-function", Vhaiku_drag_track_function, + doc: /* If non-nil, a function to call upon mouse movement while dragging a message. +The function is called without any arguments. `mouse-position' can be +used to retrieve the current position of the mouse. */); + Vhaiku_drag_track_function = Qnil; + DEFSYM (QSECONDARY, "SECONDARY"); DEFSYM (QCLIPBOARD, "CLIPBOARD"); DEFSYM (QSTRING, "STRING"); diff --git a/src/haikuterm.c b/src/haikuterm.c index e2d6a9a4670..1270fba4101 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3155,6 +3155,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) XSETINT (inev.y, b->y); XSETFRAME (inev.frame_or_window, f); } + else + haiku_note_drag_motion (); + break; } } diff --git a/src/haikuterm.h b/src/haikuterm.h index 5f8052f0f99..8f311b2ab12 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -293,6 +293,7 @@ extern void haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel); extern Lisp_Object haiku_menu_show (struct frame *f, int x, int y, int menu_flags, Lisp_Object title, const char **error_name); extern Lisp_Object haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents); +extern void haiku_note_drag_motion (void); extern void initialize_frame_menubar (struct frame *f); -- 2.39.5