diff options
| author | Po Lu | 2022-06-09 07:20:22 +0000 |
|---|---|---|
| committer | Po Lu | 2022-06-09 07:21:42 +0000 |
| commit | 0936d6fa20894159d75eb1933325d653e4820d90 (patch) | |
| tree | 996e887e25efd6c0e50f2afa8aa083987f08bd13 /src | |
| parent | 43f8690ebf3439af90cf72c619e75afb4cff1a83 (diff) | |
| download | emacs-0936d6fa20894159d75eb1933325d653e4820d90.tar.gz emacs-0936d6fa20894159d75eb1933325d653e4820d90.zip | |
Implement `follow-tooltip' for DND on Haiku
* lisp/term/haiku-win.el (x-begin-drag): Implement
`follow-tooltip'.
* src/haikufns.c (Fx_show_tip): Record last dx and dy.
(syms_of_haikufns): New staticpros.
* src/haikuselect.c (haiku_unwind_drag_message): Clear new flag.
(Fhaiku_drag_message): New argument `follow-tooltip'. Set new
flag.
(haiku_dnd_compute_tip_xy): New function.
(haiku_note_drag_motion): Move tooltip if flag is true.
* src/haikuterm.c (haiku_read_socket): Don't generate help event
if mouse moves onto a tooltip during DND.
* src/haikuterm.h: Update prototypes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/haikufns.c | 10 | ||||
| -rw-r--r-- | src/haikuselect.c | 77 | ||||
| -rw-r--r-- | src/haikuterm.c | 9 | ||||
| -rw-r--r-- | src/haikuterm.h | 4 |
4 files changed, 95 insertions, 5 deletions
diff --git a/src/haikufns.c b/src/haikufns.c index 6a79eede0e7..0b8bf89d85a 100644 --- a/src/haikufns.c +++ b/src/haikufns.c | |||
| @@ -50,6 +50,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 50 | /* The frame of the currently visible tooltip. */ | 50 | /* The frame of the currently visible tooltip. */ |
| 51 | Lisp_Object tip_frame; | 51 | Lisp_Object tip_frame; |
| 52 | 52 | ||
| 53 | /* The X and Y deltas of the last call to `x-show-tip'. */ | ||
| 54 | Lisp_Object tip_dx, tip_dy; | ||
| 55 | |||
| 53 | /* The window-system window corresponding to the frame of the | 56 | /* The window-system window corresponding to the frame of the |
| 54 | currently visible tooltip. */ | 57 | currently visible tooltip. */ |
| 55 | static Window tip_window; | 58 | static Window tip_window; |
| @@ -2352,6 +2355,9 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, | |||
| 2352 | else | 2355 | else |
| 2353 | CHECK_FIXNUM (dy); | 2356 | CHECK_FIXNUM (dy); |
| 2354 | 2357 | ||
| 2358 | tip_dx = dx; | ||
| 2359 | tip_dy = dy; | ||
| 2360 | |||
| 2355 | if (use_system_tooltips) | 2361 | if (use_system_tooltips) |
| 2356 | { | 2362 | { |
| 2357 | int root_x, root_y; | 2363 | int root_x, root_y; |
| @@ -3165,6 +3171,10 @@ syms_of_haikufns (void) | |||
| 3165 | staticpro (&tip_last_string); | 3171 | staticpro (&tip_last_string); |
| 3166 | tip_last_parms = Qnil; | 3172 | tip_last_parms = Qnil; |
| 3167 | staticpro (&tip_last_parms); | 3173 | staticpro (&tip_last_parms); |
| 3174 | tip_dx = Qnil; | ||
| 3175 | staticpro (&tip_dx); | ||
| 3176 | tip_dy = Qnil; | ||
| 3177 | staticpro (&tip_dy); | ||
| 3168 | 3178 | ||
| 3169 | DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size, | 3179 | DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size, |
| 3170 | doc: /* SKIP: real doc in xfns.c. */); | 3180 | doc: /* SKIP: real doc in xfns.c. */); |
diff --git a/src/haikuselect.c b/src/haikuselect.c index 80604252cb9..b69fcfff13e 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c | |||
| @@ -33,6 +33,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 33 | the nested event loop inside be_drag_message. */ | 33 | the nested event loop inside be_drag_message. */ |
| 34 | struct frame *haiku_dnd_frame; | 34 | struct frame *haiku_dnd_frame; |
| 35 | 35 | ||
| 36 | /* Whether or not to move the tip frame during drag-and-drop. */ | ||
| 37 | bool haiku_dnd_follow_tooltip; | ||
| 38 | |||
| 36 | static void haiku_lisp_to_message (Lisp_Object, void *); | 39 | static void haiku_lisp_to_message (Lisp_Object, void *); |
| 37 | 40 | ||
| 38 | static enum haiku_clipboard | 41 | static enum haiku_clipboard |
| @@ -752,10 +755,13 @@ haiku_unwind_drag_message (void *message) | |||
| 752 | { | 755 | { |
| 753 | haiku_dnd_frame = NULL; | 756 | haiku_dnd_frame = NULL; |
| 754 | BMessage_delete (message); | 757 | BMessage_delete (message); |
| 758 | |||
| 759 | if (haiku_dnd_follow_tooltip) | ||
| 760 | Fx_hide_tip (); | ||
| 755 | } | 761 | } |
| 756 | 762 | ||
| 757 | DEFUN ("haiku-drag-message", Fhaiku_drag_message, Shaiku_drag_message, | 763 | DEFUN ("haiku-drag-message", Fhaiku_drag_message, Shaiku_drag_message, |
| 758 | 2, 3, 0, | 764 | 2, 4, 0, |
| 759 | doc: /* Begin dragging MESSAGE from FRAME. | 765 | doc: /* Begin dragging MESSAGE from FRAME. |
| 760 | 766 | ||
| 761 | MESSAGE an alist of strings, denoting message field names, to a list | 767 | MESSAGE an alist of strings, denoting message field names, to a list |
| @@ -789,8 +795,12 @@ FRAME is a window system frame that must be visible, from which the | |||
| 789 | drag will originate. | 795 | drag will originate. |
| 790 | 796 | ||
| 791 | ALLOW-SAME-FRAME, if nil or not specified, means that MESSAGE will be | 797 | ALLOW-SAME-FRAME, if nil or not specified, means that MESSAGE will be |
| 792 | ignored if it is dropped on top of FRAME. */) | 798 | ignored if it is dropped on top of FRAME. |
| 793 | (Lisp_Object frame, Lisp_Object message, Lisp_Object allow_same_frame) | 799 | |
| 800 | FOLLOW-TOOLTIP, if non-nil, will cause any non-system tooltip | ||
| 801 | currently being displayed to move along with the mouse pointer. */) | ||
| 802 | (Lisp_Object frame, Lisp_Object message, Lisp_Object allow_same_frame, | ||
| 803 | Lisp_Object follow_tooltip) | ||
| 794 | { | 804 | { |
| 795 | specpdl_ref idx; | 805 | specpdl_ref idx; |
| 796 | void *be_message; | 806 | void *be_message; |
| @@ -804,15 +814,18 @@ ignored if it is dropped on top of FRAME. */) | |||
| 804 | error ("Frame is invisible"); | 814 | error ("Frame is invisible"); |
| 805 | 815 | ||
| 806 | haiku_dnd_frame = f; | 816 | haiku_dnd_frame = f; |
| 817 | haiku_dnd_follow_tooltip = !NILP (follow_tooltip); | ||
| 807 | be_message = be_create_simple_message (); | 818 | be_message = be_create_simple_message (); |
| 808 | 819 | ||
| 809 | record_unwind_protect_ptr (haiku_unwind_drag_message, be_message); | 820 | record_unwind_protect_ptr (haiku_unwind_drag_message, be_message); |
| 810 | haiku_lisp_to_message (message, be_message); | 821 | haiku_lisp_to_message (message, be_message); |
| 822 | |||
| 811 | rc = be_drag_message (FRAME_HAIKU_VIEW (f), be_message, | 823 | rc = be_drag_message (FRAME_HAIKU_VIEW (f), be_message, |
| 812 | !NILP (allow_same_frame), | 824 | !NILP (allow_same_frame), |
| 813 | block_input, unblock_input, | 825 | block_input, unblock_input, |
| 814 | process_pending_signals, | 826 | process_pending_signals, |
| 815 | haiku_should_quit_drag); | 827 | haiku_should_quit_drag); |
| 828 | |||
| 816 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | 829 | FRAME_DISPLAY_INFO (f)->grabbed = 0; |
| 817 | 830 | ||
| 818 | if (rc) | 831 | if (rc) |
| @@ -918,6 +931,44 @@ after it starts. */) | |||
| 918 | return SAFE_FREE_UNBIND_TO (depth, Qnil); | 931 | return SAFE_FREE_UNBIND_TO (depth, Qnil); |
| 919 | } | 932 | } |
| 920 | 933 | ||
| 934 | static void | ||
| 935 | haiku_dnd_compute_tip_xy (int *root_x, int *root_y) | ||
| 936 | { | ||
| 937 | int min_x, min_y, max_x, max_y; | ||
| 938 | int width, height; | ||
| 939 | |||
| 940 | width = FRAME_PIXEL_WIDTH (XFRAME (tip_frame)); | ||
| 941 | height = FRAME_PIXEL_HEIGHT (XFRAME (tip_frame)); | ||
| 942 | |||
| 943 | min_x = 0; | ||
| 944 | min_y = 0; | ||
| 945 | be_get_screen_dimensions (&max_x, &max_y); | ||
| 946 | |||
| 947 | if (*root_y + XFIXNUM (tip_dy) <= min_y) | ||
| 948 | *root_y = min_y; /* Can happen for negative dy */ | ||
| 949 | else if (*root_y + XFIXNUM (tip_dy) + height <= max_y) | ||
| 950 | /* It fits below the pointer */ | ||
| 951 | *root_y += XFIXNUM (tip_dy); | ||
| 952 | else if (height + XFIXNUM (tip_dy) + min_y <= *root_y) | ||
| 953 | /* It fits above the pointer. */ | ||
| 954 | *root_y -= height + XFIXNUM (tip_dy); | ||
| 955 | else | ||
| 956 | /* Put it on the top. */ | ||
| 957 | *root_y = min_y; | ||
| 958 | |||
| 959 | if (*root_x + XFIXNUM (tip_dx) <= min_x) | ||
| 960 | *root_x = 0; /* Can happen for negative dx */ | ||
| 961 | else if (*root_x + XFIXNUM (tip_dx) + width <= max_x) | ||
| 962 | /* It fits to the right of the pointer. */ | ||
| 963 | *root_x += XFIXNUM (tip_dx); | ||
| 964 | else if (width + XFIXNUM (tip_dx) + min_x <= *root_x) | ||
| 965 | /* It fits to the left of the pointer. */ | ||
| 966 | *root_x -= width + XFIXNUM (tip_dx); | ||
| 967 | else | ||
| 968 | /* Put it left justified on the screen -- it ought to fit that way. */ | ||
| 969 | *root_x = min_x; | ||
| 970 | } | ||
| 971 | |||
| 921 | static Lisp_Object | 972 | static Lisp_Object |
| 922 | haiku_note_drag_motion_1 (void *data) | 973 | haiku_note_drag_motion_1 (void *data) |
| 923 | { | 974 | { |
| @@ -936,6 +987,26 @@ haiku_note_drag_motion_2 (enum nonlocal_exit exit, Lisp_Object error) | |||
| 936 | void | 987 | void |
| 937 | haiku_note_drag_motion (void) | 988 | haiku_note_drag_motion (void) |
| 938 | { | 989 | { |
| 990 | struct frame *tip_f; | ||
| 991 | int x, y; | ||
| 992 | |||
| 993 | if (FRAMEP (tip_frame) && haiku_dnd_follow_tooltip | ||
| 994 | && FIXNUMP (tip_dx) && FIXNUMP (tip_dy)) | ||
| 995 | { | ||
| 996 | tip_f = XFRAME (tip_frame); | ||
| 997 | |||
| 998 | if (FRAME_LIVE_P (tip_f)) | ||
| 999 | { | ||
| 1000 | BView_get_mouse (FRAME_HAIKU_VIEW (haiku_dnd_frame), | ||
| 1001 | &x, &y); | ||
| 1002 | BView_convert_to_screen (FRAME_HAIKU_VIEW (haiku_dnd_frame), | ||
| 1003 | &x, &y); | ||
| 1004 | |||
| 1005 | haiku_dnd_compute_tip_xy (&x, &y); | ||
| 1006 | BWindow_set_offset (FRAME_HAIKU_WINDOW (tip_f), x, y); | ||
| 1007 | } | ||
| 1008 | } | ||
| 1009 | |||
| 939 | internal_catch_all (haiku_note_drag_motion_1, NULL, | 1010 | internal_catch_all (haiku_note_drag_motion_1, NULL, |
| 940 | haiku_note_drag_motion_2); | 1011 | haiku_note_drag_motion_2); |
| 941 | } | 1012 | } |
diff --git a/src/haikuterm.c b/src/haikuterm.c index 55e8640ec21..d47e61e60dd 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c | |||
| @@ -3286,10 +3286,15 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 3286 | if (FRAME_TOOLTIP_P (f)) | 3286 | if (FRAME_TOOLTIP_P (f)) |
| 3287 | { | 3287 | { |
| 3288 | /* Dismiss the tooltip if the mouse moves onto a | 3288 | /* Dismiss the tooltip if the mouse moves onto a |
| 3289 | tooltip frame. FIXME: for some reason we don't get | 3289 | tooltip frame (except when drag-and-drop is in |
| 3290 | leave notification events for this. */ | 3290 | progress and we are trying to move the tooltip |
| 3291 | along with the mouse pointer). FIXME: for some | ||
| 3292 | reason we don't get leave notification events for | ||
| 3293 | this. */ | ||
| 3291 | 3294 | ||
| 3292 | if (any_help_event_p | 3295 | if (any_help_event_p |
| 3296 | && !(be_drag_and_drop_in_progress () | ||
| 3297 | && haiku_dnd_follow_tooltip) | ||
| 3293 | && !((EQ (track_mouse, Qdrag_source) | 3298 | && !((EQ (track_mouse, Qdrag_source) |
| 3294 | || EQ (track_mouse, Qdropping)) | 3299 | || EQ (track_mouse, Qdropping)) |
| 3295 | && gui_mouse_grabbed (x_display_list))) | 3300 | && gui_mouse_grabbed (x_display_list))) |
diff --git a/src/haikuterm.h b/src/haikuterm.h index 41b1a85b000..ea20289b5d1 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h | |||
| @@ -219,7 +219,11 @@ extern struct haiku_display_info *x_display_list; | |||
| 219 | extern struct font_driver const haikufont_driver; | 219 | extern struct font_driver const haikufont_driver; |
| 220 | 220 | ||
| 221 | extern Lisp_Object tip_frame; | 221 | extern Lisp_Object tip_frame; |
| 222 | extern Lisp_Object tip_dx; | ||
| 223 | extern Lisp_Object tip_dy; | ||
| 224 | |||
| 222 | extern struct frame *haiku_dnd_frame; | 225 | extern struct frame *haiku_dnd_frame; |
| 226 | extern bool haiku_dnd_follow_tooltip; | ||
| 223 | 227 | ||
| 224 | extern frame_parm_handler haiku_frame_parm_handlers[]; | 228 | extern frame_parm_handler haiku_frame_parm_handlers[]; |
| 225 | 229 | ||