From edabfe4ff66090b3b2c433962df4cfe1a68259fd Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 9 Jul 2022 04:50:06 +0000 Subject: [PATCH] Fix race conditions handling selection clear events on Haiku * src/haiku_select.cc (be_handle_clipboard_changed_message): Include current clipboard count. (be_selection_outdated_p): New function. * src/haikuselect.c (haiku_handle_selection_clear): Ignore outdated events. (haiku_selection_disowned): New argument `count'. Include it in the timestamp field of the selection clear event. * src/haikuselect.h: Update prototypes. * src/systime.h: Define `Time' to an appropriate value on Haiku. --- src/haiku_select.cc | 39 ++++++++++++++++++++++++++++++--------- src/haikuselect.c | 10 +++++++++- src/haikuselect.h | 3 ++- src/systime.h | 3 +++ 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/haiku_select.cc b/src/haiku_select.cc index edb821e3132..e1f2a815241 100644 --- a/src/haiku_select.cc +++ b/src/haiku_select.cc @@ -451,31 +451,37 @@ be_unlock_clipboard (enum haiku_clipboard clipboard, bool discard) void be_handle_clipboard_changed_message (void) { + int64 n_clipboard, n_primary, n_secondary; + + n_clipboard = system_clipboard->SystemCount (); + n_primary = primary->SystemCount (); + n_secondary = secondary->SystemCount (); + if (count_clipboard != -1 - && (system_clipboard->SystemCount () - > count_clipboard + 1) + && (n_clipboard > count_clipboard + 1) && owned_clipboard) { owned_clipboard = false; - haiku_selection_disowned (CLIPBOARD_CLIPBOARD); + haiku_selection_disowned (CLIPBOARD_CLIPBOARD, + n_clipboard); } if (count_primary != -1 - && (primary->SystemCount () - > count_primary + 1) + && (n_primary > count_primary + 1) && owned_primary) { owned_primary = false; - haiku_selection_disowned (CLIPBOARD_PRIMARY); + haiku_selection_disowned (CLIPBOARD_PRIMARY, + n_primary); } if (count_secondary != -1 - && (secondary->SystemCount () - > count_secondary + 1) + && (n_secondary > count_secondary + 1) && owned_secondary) { owned_secondary = false; - haiku_selection_disowned (CLIPBOARD_SECONDARY); + haiku_selection_disowned (CLIPBOARD_SECONDARY, + n_secondary); } } @@ -487,3 +493,18 @@ be_start_watching_selection (enum haiku_clipboard id) clipboard = get_clipboard_object (id); clipboard->StartWatching (be_app); } + +bool +be_selection_outdated_p (enum haiku_clipboard id, int64 count) +{ + if (id == CLIPBOARD_CLIPBOARD && count_clipboard > count) + return true; + + if (id == CLIPBOARD_PRIMARY && count_primary > count) + return true; + + if (id == CLIPBOARD_SECONDARY && count_secondary > count) + return true; + + return false; +} diff --git a/src/haikuselect.c b/src/haikuselect.c index 03aba1f9baa..9d8c4a2cd16 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -1024,6 +1024,13 @@ init_haiku_select (void) void haiku_handle_selection_clear (struct input_event *ie) { + enum haiku_clipboard id; + + id = haiku_get_clipboard_name (ie->arg); + + if (be_selection_outdated_p (id, ie->timestamp)) + return; + CALLN (Frun_hook_with_args, Qhaiku_lost_selection_functions, ie->arg); @@ -1033,7 +1040,7 @@ haiku_handle_selection_clear (struct input_event *ie) } void -haiku_selection_disowned (enum haiku_clipboard id) +haiku_selection_disowned (enum haiku_clipboard id, int64 count) { struct input_event ie; @@ -1055,6 +1062,7 @@ haiku_selection_disowned (enum haiku_clipboard id) break; } + ie.timestamp = count; kbd_buffer_store_event (&ie); } diff --git a/src/haikuselect.h b/src/haikuselect.h index d027834e8b6..61efeb9cd93 100644 --- a/src/haikuselect.h +++ b/src/haikuselect.h @@ -39,7 +39,7 @@ extern "C" { #endif /* Defined in haikuselect.c. */ -extern void haiku_selection_disowned (enum haiku_clipboard); +extern void haiku_selection_disowned (enum haiku_clipboard, int64); /* Defined in haiku_select.cc. */ extern void be_clipboard_init (void); @@ -66,6 +66,7 @@ extern int be_lock_clipboard_message (enum haiku_clipboard, void **, bool); extern void be_unlock_clipboard (enum haiku_clipboard, bool); extern void be_handle_clipboard_changed_message (void); extern void be_start_watching_selection (enum haiku_clipboard); +extern bool be_selection_outdated_p (enum haiku_clipboard, int64); #ifdef __cplusplus }; diff --git a/src/systime.h b/src/systime.h index 75088bd4a62..085a7ddeaba 100644 --- a/src/systime.h +++ b/src/systime.h @@ -26,6 +26,9 @@ INLINE_HEADER_BEGIN #ifdef HAVE_X_WINDOWS # include +#elif defined HAVE_HAIKU +# include +typedef int64 Time; #else typedef unsigned long Time; #endif -- 2.39.5