aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-01-02 02:37:21 +0000
committerPo Lu2022-01-02 02:37:21 +0000
commit5bdf413b1902c8bbebdef774a701fa1badce9e32 (patch)
treeb884d9094e68d222352d1e34abf5fe5f5b25891d
parentaf729b1dfd235de400f6a0998a968222417596bf (diff)
downloademacs-5bdf413b1902c8bbebdef774a701fa1badce9e32.tar.gz
emacs-5bdf413b1902c8bbebdef774a701fa1badce9e32.zip
Fix mouse face problems when moving between two frames on Haiku
* src/haiku_support.cc (movement_locker): New locker. (MouseMoved): Lock that locker. (BWindow_new): (BWindow_quit): Use LockLooper instead of Lock. * src/haikuterm.c (haiku_read_socket): Clear mouse face if a motion event is received for a frame other than the one that is currently displaying the mouse face.
-rw-r--r--src/haiku_support.cc30
-rw-r--r--src/haikuterm.c27
2 files changed, 48 insertions, 9 deletions
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 8bd7c04ee89..64f9aa8a552 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -92,6 +92,26 @@ static BLocker key_map_lock;
92 92
93static BLocker child_frame_lock; 93static BLocker child_frame_lock;
94 94
95/* A LeaveNotify event (well, the closest equivalent on Haiku, which
96 is a B_MOUSE_MOVED event with `transit' set to B_EXITED_VIEW) might
97 be sent out-of-order with regards to motion events from other
98 windows, such as when the mouse pointer rapidly moves from an
99 undecorated child frame to its parent. This can cause a failure to
100 clear the mouse face on the former if an event for the latter is
101 read by Emacs first and ends up showing the mouse face there.
102
103 While this lock doesn't really ensure that the events will be
104 delivered in the correct order, it makes them arrive in the correct
105 order "most of the time" on my machine, which is good enough and
106 preferable to adding a lot of extra complexity to the event
107 handling code to sort motion events by their timestamps.
108
109 Obviously this depends on the number of execution units that are
110 available, and the scheduling priority of each thread involved in
111 the input handling, but it will be good enough for most people. */
112
113static BLocker movement_locker;
114
95extern "C" 115extern "C"
96{ 116{
97 extern _Noreturn void emacs_abort (void); 117 extern _Noreturn void emacs_abort (void);
@@ -1181,7 +1201,11 @@ public:
1181 ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x), 1201 ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x),
1182 -(point.y - tt_absl_pos.y))); 1202 -(point.y - tt_absl_pos.y)));
1183 1203
1184 haiku_write (MOUSE_MOTION, &rq); 1204 if (movement_locker.Lock ())
1205 {
1206 haiku_write (MOUSE_MOTION, &rq);
1207 movement_locker.Unlock ();
1208 }
1185 } 1209 }
1186 1210
1187 void 1211 void
@@ -1570,7 +1594,7 @@ BWindow_new (void *_view)
1570 if (!vw) 1594 if (!vw)
1571 { 1595 {
1572 *v = NULL; 1596 *v = NULL;
1573 window->Lock (); 1597 window->LockLooper ();
1574 window->Quit (); 1598 window->Quit ();
1575 return NULL; 1599 return NULL;
1576 } 1600 }
@@ -1590,7 +1614,7 @@ BWindow_new (void *_view)
1590void 1614void
1591BWindow_quit (void *window) 1615BWindow_quit (void *window)
1592{ 1616{
1593 ((BWindow *) window)->Lock (); 1617 ((BWindow *) window)->LockLooper ();
1594 ((BWindow *) window)->Quit (); 1618 ((BWindow *) window)->Quit ();
1595} 1619}
1596 1620
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 044249f7928..5447683a6ed 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -2798,6 +2798,27 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2798 previous_help_echo_string = help_echo_string; 2798 previous_help_echo_string = help_echo_string;
2799 help_echo_string = Qnil; 2799 help_echo_string = Qnil;
2800 2800
2801 /* A LeaveNotify event (well, the closest equivalent on Haiku, which
2802 is a B_MOUSE_MOVED event with `transit' set to B_EXITED_VIEW) might
2803 be sent out-of-order with regards to motion events from other
2804 windows, such as when the mouse pointer rapidly moves from an
2805 undecorated child frame to its parent. This can cause a failure to
2806 clear the mouse face on the former if an event for the latter is
2807 read by Emacs first and ends up showing the mouse face there.
2808
2809 In case the `movement_locker' (also see the comment
2810 there) doesn't take care of the problem, work
2811 around it by clearing the mouse face now, if it is
2812 currently shown on a different frame. */
2813
2814 if (hlinfo->mouse_face_hidden
2815 || (f != hlinfo->mouse_face_mouse_frame
2816 && !NILP (hlinfo->mouse_face_window)))
2817 {
2818 hlinfo->mouse_face_hidden = 0;
2819 clear_mouse_face (hlinfo);
2820 }
2821
2801 if (f != dpyinfo->last_mouse_glyph_frame 2822 if (f != dpyinfo->last_mouse_glyph_frame
2802 || b->x < r.x || b->x >= r.x + r.width 2823 || b->x < r.x || b->x >= r.x + r.width
2803 || b->y < r.y || b->y >= r.y + r.height) 2824 || b->y < r.y || b->y >= r.y + r.height)
@@ -2812,12 +2833,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
2812 help_echo_object, help_echo_pos); 2833 help_echo_object, help_echo_pos);
2813 } 2834 }
2814 2835
2815 if (MOUSE_HL_INFO (f)->mouse_face_hidden)
2816 {
2817 MOUSE_HL_INFO (f)->mouse_face_hidden = 0;
2818 clear_mouse_face (MOUSE_HL_INFO (f));
2819 }
2820
2821 if (!NILP (Vmouse_autoselect_window)) 2836 if (!NILP (Vmouse_autoselect_window))
2822 { 2837 {
2823 static Lisp_Object last_mouse_window; 2838 static Lisp_Object last_mouse_window;