diff options
| author | Po Lu | 2022-07-20 07:37:24 +0000 |
|---|---|---|
| committer | Po Lu | 2022-07-20 07:37:41 +0000 |
| commit | 83753d05ebb784d1d59687f3f488721f8a2edbb2 (patch) | |
| tree | 54973449ac07c0b151e1be9d103a38a38c309c37 | |
| parent | 32db1682903a3a6a59f81426ab699531f08acd2f (diff) | |
| download | emacs-83753d05ebb784d1d59687f3f488721f8a2edbb2.tar.gz emacs-83753d05ebb784d1d59687f3f488721f8a2edbb2.zip | |
Implement wheel movement during DND on Haiku
* lisp/term/haiku-win.el (haiku-dnd-wheel-count): New defvar.
(haiku-note-wheel-click, haiku-handle-drag-wheel): New
functions.
* src/haiku_support.cc (EmacsWindow): Get rid of window ID
logic.
(MessageReceived, MouseMoved, be_drag_message): Use thread ID to
identify windows instead of window ID.
* src/haikuselect.c (Fhaiku_drag_message): Record whether or not
the DND frame is a valid drop target.
(haiku_note_drag_wheel): New function.
(syms_of_haikuselect): New defvar.
* src/haikuterm.c (haiku_read_socket): Call
`haiku_note_drag_wheel' when appropriate.
* src/haikuterm.h: Update prototypes.
| -rw-r--r-- | lisp/term/haiku-win.el | 54 | ||||
| -rw-r--r-- | src/haiku_support.cc | 32 | ||||
| -rw-r--r-- | src/haikuselect.c | 45 | ||||
| -rw-r--r-- | src/haikuterm.c | 3 | ||||
| -rw-r--r-- | src/haikuterm.h | 1 |
5 files changed, 115 insertions, 20 deletions
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index ec1e2f384a9..4a8db7c3217 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el | |||
| @@ -459,7 +459,59 @@ take effect on menu items until the menu bar is updated again." | |||
| 459 | message allow-current-frame | 459 | message allow-current-frame |
| 460 | follow-tooltip)))) | 460 | follow-tooltip)))) |
| 461 | 461 | ||
| 462 | (add-variable-watcher 'use-system-tooltips #'haiku-use-system-tooltips-watcher) | 462 | (add-variable-watcher 'use-system-tooltips |
| 463 | #'haiku-use-system-tooltips-watcher) | ||
| 464 | |||
| 465 | (defvar haiku-dnd-wheel-count nil | ||
| 466 | "Cons used to determine how many times the wheel has been turned. | ||
| 467 | The car is just that; cdr is the timestamp of the last wheel | ||
| 468 | movement.") | ||
| 469 | |||
| 470 | (defun haiku-note-wheel-click (timestamp) | ||
| 471 | "Note that the mouse wheel was moved at TIMESTAMP during drag-and-drop. | ||
| 472 | Return the number of clicks that were made in quick succession." | ||
| 473 | (if (not (integerp double-click-time)) | ||
| 474 | 1 | ||
| 475 | (let ((cell haiku-dnd-wheel-count)) | ||
| 476 | (unless cell | ||
| 477 | (setq cell (cons 0 timestamp)) | ||
| 478 | (setq haiku-dnd-wheel-count cell)) | ||
| 479 | (when (< (cdr cell) (- timestamp double-click-time)) | ||
| 480 | (setcar cell 0)) | ||
| 481 | (setcar cell (1+ (car cell))) | ||
| 482 | (setcdr cell timestamp) | ||
| 483 | (car cell)))) | ||
| 484 | |||
| 485 | (defvar haiku-drag-wheel-function) | ||
| 486 | |||
| 487 | (defun haiku-handle-drag-wheel (frame x y horizontal up) | ||
| 488 | "Handle wheel movement during drag-and-drop. | ||
| 489 | FRAME is the frame on top of which the wheel moved. | ||
| 490 | X and Y are the frame-relative coordinates of the wheel movement. | ||
| 491 | HORIZONTAL is whether or not the wheel movement was horizontal. | ||
| 492 | UP is whether or not the wheel moved up (or left)." | ||
| 493 | ;; FIXME: redisplay is very slow after this. | ||
| 494 | (let ((function (cond | ||
| 495 | ((and (not horizontal) up) | ||
| 496 | mwheel-scroll-up-function) | ||
| 497 | ((not horizontal) | ||
| 498 | mwheel-scroll-down-function) | ||
| 499 | (up (if mouse-wheel-flip-direction | ||
| 500 | mwheel-scroll-right-function | ||
| 501 | mwheel-scroll-left-function)) | ||
| 502 | (t (if mouse-wheel-flip-direction | ||
| 503 | mwheel-scroll-left-function | ||
| 504 | mwheel-scroll-right-function)))) | ||
| 505 | (timestamp (time-convert nil 1000))) | ||
| 506 | (when function | ||
| 507 | (let ((posn (posn-at-x-y x y frame))) | ||
| 508 | (when (windowp (posn-window posn)) | ||
| 509 | (with-selected-window (posn-window posn) | ||
| 510 | (funcall function | ||
| 511 | (or (and (not mouse-wheel-progressive-speed) 1) | ||
| 512 | (haiku-note-wheel-click (car timestamp)))))))))) | ||
| 513 | |||
| 514 | (setq haiku-drag-wheel-function #'haiku-handle-drag-wheel) | ||
| 463 | 515 | ||
| 464 | 516 | ||
| 465 | ;;;; Session management. | 517 | ;;;; Session management. |
diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 1f7f372a9b4..098739cd98b 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc | |||
| @@ -189,10 +189,6 @@ static BMessage volatile *popup_track_message; | |||
| 189 | number. */ | 189 | number. */ |
| 190 | static int32 volatile alert_popup_value; | 190 | static int32 volatile alert_popup_value; |
| 191 | 191 | ||
| 192 | /* The current window ID. This is increased every time a frame is | ||
| 193 | created. */ | ||
| 194 | static int current_window_id; | ||
| 195 | |||
| 196 | /* The view that has the passive grab. */ | 192 | /* The view that has the passive grab. */ |
| 197 | static void *grab_view; | 193 | static void *grab_view; |
| 198 | 194 | ||
| @@ -698,7 +694,6 @@ public: | |||
| 698 | was_shown_p (false), | 694 | was_shown_p (false), |
| 699 | menu_bar_active_p (false), | 695 | menu_bar_active_p (false), |
| 700 | override_redirect_p (false), | 696 | override_redirect_p (false), |
| 701 | window_id (current_window_id), | ||
| 702 | menus_begun (NULL), | 697 | menus_begun (NULL), |
| 703 | z_group (Z_GROUP_NONE), | 698 | z_group (Z_GROUP_NONE), |
| 704 | tooltip_p (false), | 699 | tooltip_p (false), |
| @@ -941,12 +936,11 @@ public: | |||
| 941 | if (msg->WasDropped ()) | 936 | if (msg->WasDropped ()) |
| 942 | { | 937 | { |
| 943 | BPoint whereto; | 938 | BPoint whereto; |
| 944 | int32 windowid; | 939 | int64 threadid; |
| 945 | struct haiku_drag_and_drop_event rq; | 940 | struct haiku_drag_and_drop_event rq; |
| 946 | 941 | ||
| 947 | if (msg->FindInt32 ("emacs:window_id", &windowid) == B_OK | 942 | if (msg->FindInt64 ("emacs:thread_id", &threadid) == B_OK |
| 948 | && !msg->IsSourceRemote () | 943 | && threadid == find_thread (NULL)) |
| 949 | && windowid == this->window_id) | ||
| 950 | return; | 944 | return; |
| 951 | 945 | ||
| 952 | whereto = msg->DropPoint (); | 946 | whereto = msg->DropPoint (); |
| @@ -1794,7 +1788,7 @@ public: | |||
| 1794 | MouseMoved (BPoint point, uint32 transit, const BMessage *drag_msg) | 1788 | MouseMoved (BPoint point, uint32 transit, const BMessage *drag_msg) |
| 1795 | { | 1789 | { |
| 1796 | struct haiku_mouse_motion_event rq; | 1790 | struct haiku_mouse_motion_event rq; |
| 1797 | int32 windowid; | 1791 | int64 threadid; |
| 1798 | EmacsWindow *window; | 1792 | EmacsWindow *window; |
| 1799 | 1793 | ||
| 1800 | window = (EmacsWindow *) Window (); | 1794 | window = (EmacsWindow *) Window (); |
| @@ -1810,9 +1804,9 @@ public: | |||
| 1810 | rq.time = system_time (); | 1804 | rq.time = system_time (); |
| 1811 | 1805 | ||
| 1812 | if (drag_msg && (drag_msg->IsSourceRemote () | 1806 | if (drag_msg && (drag_msg->IsSourceRemote () |
| 1813 | || drag_msg->FindInt32 ("emacs:window_id", | 1807 | || drag_msg->FindInt64 ("emacs:thread_id", |
| 1814 | &windowid) != B_OK | 1808 | &threadid) != B_OK |
| 1815 | || windowid != window->window_id)) | 1809 | || threadid != find_thread (NULL))) |
| 1816 | rq.dnd_message = true; | 1810 | rq.dnd_message = true; |
| 1817 | else | 1811 | else |
| 1818 | rq.dnd_message = false; | 1812 | rq.dnd_message = false; |
| @@ -5046,13 +5040,17 @@ be_drag_message (void *view, void *message, bool allow_same_view, | |||
| 5046 | BMessage cancel_message (CANCEL_DROP); | 5040 | BMessage cancel_message (CANCEL_DROP); |
| 5047 | struct object_wait_info infos[2]; | 5041 | struct object_wait_info infos[2]; |
| 5048 | ssize_t stat; | 5042 | ssize_t stat; |
| 5043 | thread_id window_thread; | ||
| 5049 | 5044 | ||
| 5050 | block_input_function (); | 5045 | block_input_function (); |
| 5051 | 5046 | ||
| 5052 | if (!allow_same_view && | 5047 | if (!allow_same_view) |
| 5053 | (msg->ReplaceInt32 ("emacs:window_id", window->window_id) | 5048 | window_thread = window->Looper ()->Thread (); |
| 5054 | == B_NAME_NOT_FOUND)) | 5049 | |
| 5055 | msg->AddInt32 ("emacs:window_id", window->window_id); | 5050 | if (!allow_same_view |
| 5051 | && (msg->ReplaceInt64 ("emacs:thread_id", window_thread) | ||
| 5052 | == B_NAME_NOT_FOUND)) | ||
| 5053 | msg->AddInt64 ("emacs:thread_id", window_thread); | ||
| 5056 | 5054 | ||
| 5057 | if (!vw->LockLooper ()) | 5055 | if (!vw->LockLooper ()) |
| 5058 | gui_abort ("Failed to lock view looper for drag"); | 5056 | gui_abort ("Failed to lock view looper for drag"); |
diff --git a/src/haikuselect.c b/src/haikuselect.c index daad98da2b4..268d8b1ec92 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c | |||
| @@ -37,6 +37,10 @@ struct frame *haiku_dnd_frame; | |||
| 37 | /* Whether or not to move the tip frame during drag-and-drop. */ | 37 | /* Whether or not to move the tip frame during drag-and-drop. */ |
| 38 | bool haiku_dnd_follow_tooltip; | 38 | bool haiku_dnd_follow_tooltip; |
| 39 | 39 | ||
| 40 | /* Whether or not the current DND frame is able to receive drops from | ||
| 41 | the current drag-and-drop operation. */ | ||
| 42 | bool haiku_dnd_allow_same_frame; | ||
| 43 | |||
| 40 | static void haiku_lisp_to_message (Lisp_Object, void *); | 44 | static void haiku_lisp_to_message (Lisp_Object, void *); |
| 41 | 45 | ||
| 42 | static enum haiku_clipboard | 46 | static enum haiku_clipboard |
| @@ -830,6 +834,8 @@ currently being displayed to move along with the mouse pointer. */) | |||
| 830 | 834 | ||
| 831 | haiku_dnd_frame = f; | 835 | haiku_dnd_frame = f; |
| 832 | haiku_dnd_follow_tooltip = !NILP (follow_tooltip); | 836 | haiku_dnd_follow_tooltip = !NILP (follow_tooltip); |
| 837 | haiku_dnd_allow_same_frame = !NILP (allow_same_frame); | ||
| 838 | |||
| 833 | be_message = be_create_simple_message (); | 839 | be_message = be_create_simple_message (); |
| 834 | 840 | ||
| 835 | record_unwind_protect_ptr (haiku_unwind_drag_message, be_message); | 841 | record_unwind_protect_ptr (haiku_unwind_drag_message, be_message); |
| @@ -1038,6 +1044,31 @@ haiku_note_drag_motion (void) | |||
| 1038 | } | 1044 | } |
| 1039 | 1045 | ||
| 1040 | void | 1046 | void |
| 1047 | haiku_note_drag_wheel (struct input_event *ie) | ||
| 1048 | { | ||
| 1049 | bool horizontal, up; | ||
| 1050 | |||
| 1051 | up = false; | ||
| 1052 | horizontal = false; | ||
| 1053 | |||
| 1054 | if (ie->modifiers & up_modifier) | ||
| 1055 | up = true; | ||
| 1056 | |||
| 1057 | if (ie->kind == HORIZ_WHEEL_EVENT) | ||
| 1058 | horizontal = true; | ||
| 1059 | |||
| 1060 | ie->kind = NO_EVENT; | ||
| 1061 | |||
| 1062 | if (!NILP (Vhaiku_drag_wheel_function) | ||
| 1063 | && (haiku_dnd_allow_same_frame | ||
| 1064 | || XFRAME (ie->frame_or_window) != haiku_dnd_frame)) | ||
| 1065 | safe_call (6, Vhaiku_drag_wheel_function, ie->frame_or_window, | ||
| 1066 | ie->x, ie->y, horizontal ? Qt : Qnil, up ? Qt : Qnil); | ||
| 1067 | |||
| 1068 | redisplay_preserve_echo_area (35); | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | void | ||
| 1041 | init_haiku_select (void) | 1072 | init_haiku_select (void) |
| 1042 | { | 1073 | { |
| 1043 | be_clipboard_init (); | 1074 | be_clipboard_init (); |
| @@ -1100,13 +1131,13 @@ void | |||
| 1100 | syms_of_haikuselect (void) | 1131 | syms_of_haikuselect (void) |
| 1101 | { | 1132 | { |
| 1102 | DEFVAR_BOOL ("haiku-signal-invalid-refs", haiku_signal_invalid_refs, | 1133 | DEFVAR_BOOL ("haiku-signal-invalid-refs", haiku_signal_invalid_refs, |
| 1103 | doc: /* If nil, silently ignore invalid file names in system messages. | 1134 | doc: /* If nil, silently ignore invalid file names in system messages. |
| 1104 | Otherwise, an error will be signalled if adding a file reference to a | 1135 | Otherwise, an error will be signalled if adding a file reference to a |
| 1105 | system message failed. */); | 1136 | system message failed. */); |
| 1106 | haiku_signal_invalid_refs = true; | 1137 | haiku_signal_invalid_refs = true; |
| 1107 | 1138 | ||
| 1108 | DEFVAR_LISP ("haiku-drag-track-function", Vhaiku_drag_track_function, | 1139 | DEFVAR_LISP ("haiku-drag-track-function", Vhaiku_drag_track_function, |
| 1109 | doc: /* If non-nil, a function to call upon mouse movement while dragging a message. | 1140 | doc: /* If non-nil, a function to call upon mouse movement while dragging a message. |
| 1110 | The function is called without any arguments. `mouse-position' can be | 1141 | The function is called without any arguments. `mouse-position' can be |
| 1111 | used to retrieve the current position of the mouse. */); | 1142 | used to retrieve the current position of the mouse. */); |
| 1112 | Vhaiku_drag_track_function = Qnil; | 1143 | Vhaiku_drag_track_function = Qnil; |
| @@ -1116,6 +1147,16 @@ used to retrieve the current position of the mouse. */); | |||
| 1116 | These are only called if a connection to the Haiku display was opened. */); | 1147 | These are only called if a connection to the Haiku display was opened. */); |
| 1117 | Vhaiku_lost_selection_functions = Qnil; | 1148 | Vhaiku_lost_selection_functions = Qnil; |
| 1118 | 1149 | ||
| 1150 | DEFVAR_LISP ("haiku-drag-wheel-function", Vhaiku_drag_wheel_function, | ||
| 1151 | doc: /* Function called upon wheel movement while dragging a message. | ||
| 1152 | If non-nil, it is called with 5 arguments when the mouse wheel moves | ||
| 1153 | while a drag-and-drop operation is in progress: the frame where the | ||
| 1154 | mouse moved, the frame-relative X and Y positions where the mouse | ||
| 1155 | moved, whether or not the wheel movement was horizontal, and whether | ||
| 1156 | or not the wheel moved up (or left, if the movement was | ||
| 1157 | horizontal). */); | ||
| 1158 | Vhaiku_drag_wheel_function = Qnil; | ||
| 1159 | |||
| 1119 | DEFSYM (QSECONDARY, "SECONDARY"); | 1160 | DEFSYM (QSECONDARY, "SECONDARY"); |
| 1120 | DEFSYM (QCLIPBOARD, "CLIPBOARD"); | 1161 | DEFSYM (QCLIPBOARD, "CLIPBOARD"); |
| 1121 | DEFSYM (QSTRING, "STRING"); | 1162 | DEFSYM (QSTRING, "STRING"); |
diff --git a/src/haikuterm.c b/src/haikuterm.c index bcb3af0e2c3..7630d9c103c 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c | |||
| @@ -3867,6 +3867,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 3867 | : down_modifier); | 3867 | : down_modifier); |
| 3868 | py = 0.0f; | 3868 | py = 0.0f; |
| 3869 | px = 0.0f; | 3869 | px = 0.0f; |
| 3870 | |||
| 3871 | if (be_drag_and_drop_in_progress ()) | ||
| 3872 | haiku_note_drag_wheel (&inev); | ||
| 3870 | } | 3873 | } |
| 3871 | 3874 | ||
| 3872 | break; | 3875 | break; |
diff --git a/src/haikuterm.h b/src/haikuterm.h index 46a2218e492..02a364f6712 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h | |||
| @@ -333,6 +333,7 @@ extern Lisp_Object haiku_popup_dialog (struct frame *, Lisp_Object, Lisp_Object) | |||
| 333 | extern void haiku_activate_menubar (struct frame *); | 333 | extern void haiku_activate_menubar (struct frame *); |
| 334 | extern void haiku_wait_for_event (struct frame *, int); | 334 | extern void haiku_wait_for_event (struct frame *, int); |
| 335 | extern void haiku_note_drag_motion (void); | 335 | extern void haiku_note_drag_motion (void); |
| 336 | extern void haiku_note_drag_wheel (struct input_event *); | ||
| 336 | 337 | ||
| 337 | extern void initialize_frame_menubar (struct frame *); | 338 | extern void initialize_frame_menubar (struct frame *); |
| 338 | 339 | ||