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:
parent
af729b1dfd
commit
5bdf413b19
2 changed files with 48 additions and 9 deletions
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue