aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-06-09 07:20:22 +0000
committerPo Lu2022-06-09 07:21:42 +0000
commit0936d6fa20894159d75eb1933325d653e4820d90 (patch)
tree996e887e25efd6c0e50f2afa8aa083987f08bd13 /src
parent43f8690ebf3439af90cf72c619e75afb4cff1a83 (diff)
downloademacs-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.c10
-rw-r--r--src/haikuselect.c77
-rw-r--r--src/haikuterm.c9
-rw-r--r--src/haikuterm.h4
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. */
51Lisp_Object tip_frame; 51Lisp_Object tip_frame;
52 52
53/* The X and Y deltas of the last call to `x-show-tip'. */
54Lisp_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. */
55static Window tip_window; 58static 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. */
34struct frame *haiku_dnd_frame; 34struct frame *haiku_dnd_frame;
35 35
36/* Whether or not to move the tip frame during drag-and-drop. */
37bool haiku_dnd_follow_tooltip;
38
36static void haiku_lisp_to_message (Lisp_Object, void *); 39static void haiku_lisp_to_message (Lisp_Object, void *);
37 40
38static enum haiku_clipboard 41static 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
757DEFUN ("haiku-drag-message", Fhaiku_drag_message, Shaiku_drag_message, 763DEFUN ("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
761MESSAGE an alist of strings, denoting message field names, to a list 767MESSAGE 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
789drag will originate. 795drag will originate.
790 796
791ALLOW-SAME-FRAME, if nil or not specified, means that MESSAGE will be 797ALLOW-SAME-FRAME, if nil or not specified, means that MESSAGE will be
792ignored if it is dropped on top of FRAME. */) 798ignored if it is dropped on top of FRAME.
793 (Lisp_Object frame, Lisp_Object message, Lisp_Object allow_same_frame) 799
800FOLLOW-TOOLTIP, if non-nil, will cause any non-system tooltip
801currently 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
934static void
935haiku_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
921static Lisp_Object 972static Lisp_Object
922haiku_note_drag_motion_1 (void *data) 973haiku_note_drag_motion_1 (void *data)
923{ 974{
@@ -936,6 +987,26 @@ haiku_note_drag_motion_2 (enum nonlocal_exit exit, Lisp_Object error)
936void 987void
937haiku_note_drag_motion (void) 988haiku_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;
219extern struct font_driver const haikufont_driver; 219extern struct font_driver const haikufont_driver;
220 220
221extern Lisp_Object tip_frame; 221extern Lisp_Object tip_frame;
222extern Lisp_Object tip_dx;
223extern Lisp_Object tip_dy;
224
222extern struct frame *haiku_dnd_frame; 225extern struct frame *haiku_dnd_frame;
226extern bool haiku_dnd_follow_tooltip;
223 227
224extern frame_parm_handler haiku_frame_parm_handlers[]; 228extern frame_parm_handler haiku_frame_parm_handlers[];
225 229