diff options
| author | Po Lu | 2022-07-09 04:50:06 +0000 |
|---|---|---|
| committer | Po Lu | 2022-07-09 04:50:35 +0000 |
| commit | edabfe4ff66090b3b2c433962df4cfe1a68259fd (patch) | |
| tree | 89d27a45082768a61bdcbcb49bfb25a7f4637b98 /src | |
| parent | f400c60237f04781b60423492c583beea6c77e8e (diff) | |
| download | emacs-edabfe4ff66090b3b2c433962df4cfe1a68259fd.tar.gz emacs-edabfe4ff66090b3b2c433962df4cfe1a68259fd.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/haiku_select.cc | 39 | ||||
| -rw-r--r-- | src/haikuselect.c | 10 | ||||
| -rw-r--r-- | src/haikuselect.h | 3 | ||||
| -rw-r--r-- | 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) | |||
| 451 | void | 451 | void |
| 452 | be_handle_clipboard_changed_message (void) | 452 | be_handle_clipboard_changed_message (void) |
| 453 | { | 453 | { |
| 454 | int64 n_clipboard, n_primary, n_secondary; | ||
| 455 | |||
| 456 | n_clipboard = system_clipboard->SystemCount (); | ||
| 457 | n_primary = primary->SystemCount (); | ||
| 458 | n_secondary = secondary->SystemCount (); | ||
| 459 | |||
| 454 | if (count_clipboard != -1 | 460 | if (count_clipboard != -1 |
| 455 | && (system_clipboard->SystemCount () | 461 | && (n_clipboard > count_clipboard + 1) |
| 456 | > count_clipboard + 1) | ||
| 457 | && owned_clipboard) | 462 | && owned_clipboard) |
| 458 | { | 463 | { |
| 459 | owned_clipboard = false; | 464 | owned_clipboard = false; |
| 460 | haiku_selection_disowned (CLIPBOARD_CLIPBOARD); | 465 | haiku_selection_disowned (CLIPBOARD_CLIPBOARD, |
| 466 | n_clipboard); | ||
| 461 | } | 467 | } |
| 462 | 468 | ||
| 463 | if (count_primary != -1 | 469 | if (count_primary != -1 |
| 464 | && (primary->SystemCount () | 470 | && (n_primary > count_primary + 1) |
| 465 | > count_primary + 1) | ||
| 466 | && owned_primary) | 471 | && owned_primary) |
| 467 | { | 472 | { |
| 468 | owned_primary = false; | 473 | owned_primary = false; |
| 469 | haiku_selection_disowned (CLIPBOARD_PRIMARY); | 474 | haiku_selection_disowned (CLIPBOARD_PRIMARY, |
| 475 | n_primary); | ||
| 470 | } | 476 | } |
| 471 | 477 | ||
| 472 | if (count_secondary != -1 | 478 | if (count_secondary != -1 |
| 473 | && (secondary->SystemCount () | 479 | && (n_secondary > count_secondary + 1) |
| 474 | > count_secondary + 1) | ||
| 475 | && owned_secondary) | 480 | && owned_secondary) |
| 476 | { | 481 | { |
| 477 | owned_secondary = false; | 482 | owned_secondary = false; |
| 478 | haiku_selection_disowned (CLIPBOARD_SECONDARY); | 483 | haiku_selection_disowned (CLIPBOARD_SECONDARY, |
| 484 | n_secondary); | ||
| 479 | } | 485 | } |
| 480 | } | 486 | } |
| 481 | 487 | ||
| @@ -487,3 +493,18 @@ be_start_watching_selection (enum haiku_clipboard id) | |||
| 487 | clipboard = get_clipboard_object (id); | 493 | clipboard = get_clipboard_object (id); |
| 488 | clipboard->StartWatching (be_app); | 494 | clipboard->StartWatching (be_app); |
| 489 | } | 495 | } |
| 496 | |||
| 497 | bool | ||
| 498 | be_selection_outdated_p (enum haiku_clipboard id, int64 count) | ||
| 499 | { | ||
| 500 | if (id == CLIPBOARD_CLIPBOARD && count_clipboard > count) | ||
| 501 | return true; | ||
| 502 | |||
| 503 | if (id == CLIPBOARD_PRIMARY && count_primary > count) | ||
| 504 | return true; | ||
| 505 | |||
| 506 | if (id == CLIPBOARD_SECONDARY && count_secondary > count) | ||
| 507 | return true; | ||
| 508 | |||
| 509 | return false; | ||
| 510 | } | ||
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) | |||
| 1024 | void | 1024 | void |
| 1025 | haiku_handle_selection_clear (struct input_event *ie) | 1025 | haiku_handle_selection_clear (struct input_event *ie) |
| 1026 | { | 1026 | { |
| 1027 | enum haiku_clipboard id; | ||
| 1028 | |||
| 1029 | id = haiku_get_clipboard_name (ie->arg); | ||
| 1030 | |||
| 1031 | if (be_selection_outdated_p (id, ie->timestamp)) | ||
| 1032 | return; | ||
| 1033 | |||
| 1027 | CALLN (Frun_hook_with_args, | 1034 | CALLN (Frun_hook_with_args, |
| 1028 | Qhaiku_lost_selection_functions, ie->arg); | 1035 | Qhaiku_lost_selection_functions, ie->arg); |
| 1029 | 1036 | ||
| @@ -1033,7 +1040,7 @@ haiku_handle_selection_clear (struct input_event *ie) | |||
| 1033 | } | 1040 | } |
| 1034 | 1041 | ||
| 1035 | void | 1042 | void |
| 1036 | haiku_selection_disowned (enum haiku_clipboard id) | 1043 | haiku_selection_disowned (enum haiku_clipboard id, int64 count) |
| 1037 | { | 1044 | { |
| 1038 | struct input_event ie; | 1045 | struct input_event ie; |
| 1039 | 1046 | ||
| @@ -1055,6 +1062,7 @@ haiku_selection_disowned (enum haiku_clipboard id) | |||
| 1055 | break; | 1062 | break; |
| 1056 | } | 1063 | } |
| 1057 | 1064 | ||
| 1065 | ie.timestamp = count; | ||
| 1058 | kbd_buffer_store_event (&ie); | 1066 | kbd_buffer_store_event (&ie); |
| 1059 | } | 1067 | } |
| 1060 | 1068 | ||
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" | |||
| 39 | { | 39 | { |
| 40 | #endif | 40 | #endif |
| 41 | /* Defined in haikuselect.c. */ | 41 | /* Defined in haikuselect.c. */ |
| 42 | extern void haiku_selection_disowned (enum haiku_clipboard); | 42 | extern void haiku_selection_disowned (enum haiku_clipboard, int64); |
| 43 | 43 | ||
| 44 | /* Defined in haiku_select.cc. */ | 44 | /* Defined in haiku_select.cc. */ |
| 45 | extern void be_clipboard_init (void); | 45 | extern void be_clipboard_init (void); |
| @@ -66,6 +66,7 @@ extern int be_lock_clipboard_message (enum haiku_clipboard, void **, bool); | |||
| 66 | extern void be_unlock_clipboard (enum haiku_clipboard, bool); | 66 | extern void be_unlock_clipboard (enum haiku_clipboard, bool); |
| 67 | extern void be_handle_clipboard_changed_message (void); | 67 | extern void be_handle_clipboard_changed_message (void); |
| 68 | extern void be_start_watching_selection (enum haiku_clipboard); | 68 | extern void be_start_watching_selection (enum haiku_clipboard); |
| 69 | extern bool be_selection_outdated_p (enum haiku_clipboard, int64); | ||
| 69 | 70 | ||
| 70 | #ifdef __cplusplus | 71 | #ifdef __cplusplus |
| 71 | }; | 72 | }; |
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 | |||
| 26 | 26 | ||
| 27 | #ifdef HAVE_X_WINDOWS | 27 | #ifdef HAVE_X_WINDOWS |
| 28 | # include <X11/X.h> | 28 | # include <X11/X.h> |
| 29 | #elif defined HAVE_HAIKU | ||
| 30 | # include <support/SupportDefs.h> | ||
| 31 | typedef int64 Time; | ||
| 29 | #else | 32 | #else |
| 30 | typedef unsigned long Time; | 33 | typedef unsigned long Time; |
| 31 | #endif | 34 | #endif |