diff options
| author | Po Lu | 2022-01-02 02:37:21 +0000 |
|---|---|---|
| committer | Po Lu | 2022-01-02 02:37:21 +0000 |
| commit | 5bdf413b1902c8bbebdef774a701fa1badce9e32 (patch) | |
| tree | b884d9094e68d222352d1e34abf5fe5f5b25891d | |
| parent | af729b1dfd235de400f6a0998a968222417596bf (diff) | |
| download | emacs-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.cc | 30 | ||||
| -rw-r--r-- | src/haikuterm.c | 27 |
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 | ||
| 93 | static BLocker child_frame_lock; | 93 | static 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 | |||
| 113 | static BLocker movement_locker; | ||
| 114 | |||
| 95 | extern "C" | 115 | extern "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) | |||
| 1590 | void | 1614 | void |
| 1591 | BWindow_quit (void *window) | 1615 | BWindow_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; |