1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-18 00:50:44 -08:00

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.
This commit is contained in:
Po Lu 2022-01-02 02:37:21 +00:00
parent af729b1dfd
commit 5bdf413b19
2 changed files with 48 additions and 9 deletions

View file

@ -92,6 +92,26 @@ static BLocker key_map_lock;
static BLocker child_frame_lock;
/* A LeaveNotify event (well, the closest equivalent on Haiku, which
is a B_MOUSE_MOVED event with `transit' set to B_EXITED_VIEW) might
be sent out-of-order with regards to motion events from other
windows, such as when the mouse pointer rapidly moves from an
undecorated child frame to its parent. This can cause a failure to
clear the mouse face on the former if an event for the latter is
read by Emacs first and ends up showing the mouse face there.
While this lock doesn't really ensure that the events will be
delivered in the correct order, it makes them arrive in the correct
order "most of the time" on my machine, which is good enough and
preferable to adding a lot of extra complexity to the event
handling code to sort motion events by their timestamps.
Obviously this depends on the number of execution units that are
available, and the scheduling priority of each thread involved in
the input handling, but it will be good enough for most people. */
static BLocker movement_locker;
extern "C"
{
extern _Noreturn void emacs_abort (void);
@ -1181,7 +1201,11 @@ public:
ToolTip ()->SetMouseRelativeLocation (BPoint (-(point.x - tt_absl_pos.x),
-(point.y - tt_absl_pos.y)));
haiku_write (MOUSE_MOTION, &rq);
if (movement_locker.Lock ())
{
haiku_write (MOUSE_MOTION, &rq);
movement_locker.Unlock ();
}
}
void
@ -1570,7 +1594,7 @@ BWindow_new (void *_view)
if (!vw)
{
*v = NULL;
window->Lock ();
window->LockLooper ();
window->Quit ();
return NULL;
}
@ -1590,7 +1614,7 @@ BWindow_new (void *_view)
void
BWindow_quit (void *window)
{
((BWindow *) window)->Lock ();
((BWindow *) window)->LockLooper ();
((BWindow *) window)->Quit ();
}

View file

@ -2798,6 +2798,27 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
/* A LeaveNotify event (well, the closest equivalent on Haiku, which
is a B_MOUSE_MOVED event with `transit' set to B_EXITED_VIEW) might
be sent out-of-order with regards to motion events from other
windows, such as when the mouse pointer rapidly moves from an
undecorated child frame to its parent. This can cause a failure to
clear the mouse face on the former if an event for the latter is
read by Emacs first and ends up showing the mouse face there.
In case the `movement_locker' (also see the comment
there) doesn't take care of the problem, work
around it by clearing the mouse face now, if it is
currently shown on a different frame. */
if (hlinfo->mouse_face_hidden
|| (f != hlinfo->mouse_face_mouse_frame
&& !NILP (hlinfo->mouse_face_window)))
{
hlinfo->mouse_face_hidden = 0;
clear_mouse_face (hlinfo);
}
if (f != dpyinfo->last_mouse_glyph_frame
|| b->x < r.x || b->x >= r.x + r.width
|| 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)
help_echo_object, help_echo_pos);
}
if (MOUSE_HL_INFO (f)->mouse_face_hidden)
{
MOUSE_HL_INFO (f)->mouse_face_hidden = 0;
clear_mouse_face (MOUSE_HL_INFO (f));
}
if (!NILP (Vmouse_autoselect_window))
{
static Lisp_Object last_mouse_window;