diff options
| author | Po Lu | 2022-06-06 11:08:19 +0800 |
|---|---|---|
| committer | Po Lu | 2022-06-06 11:08:19 +0800 |
| commit | b90d2a6a63f1b7f73d2cb7e976148e8195fc5502 (patch) | |
| tree | 965057d58b783e920711e05138ad56184ceec6c4 /src/keyboard.c | |
| parent | 0a36671f415bd681ddca0bad8612aca031fd407d (diff) | |
| download | emacs-b90d2a6a63f1b7f73d2cb7e976148e8195fc5502.tar.gz emacs-b90d2a6a63f1b7f73d2cb7e976148e8195fc5502.zip | |
Rework X selections to make it safe to run the debugger inside converters
* src/keyboard.c (prev_kbd_event): Delete function.
(readable_events): Return 1 if
x_detect_pending_selection_requests returns true.
(kbd_buffer_unget_event): Also delete function, since nested
selection requests are really handled correctly.
(kbd_buffer_get_event): Handle events from the special X
deferred selection queue as well.
* src/keyboard.h: Update prototypes.
* src/xselect.c (struct selection_event_queue)
(selection_input_event_equal, x_queue_event)
(x_start_queuing_selection_requests)
(x_stop_queuing_selection_requests): Delete structs, since they
are no longer required.
(x_handle_selection_request, x_handle_selection_event): Allow
nested selection events.
* src/xterm.c (struct x_selection_request_event): New struct.
(x_handle_pending_selection_requests_1)
(x_handle_pending_selection_requests): Handle all events in the
new selection event queue.
(x_push_selection_request, x_detect_pending_selection_requests):
New functions.
(x_dnd_begin_drag_and_drop): Drain the selection queue here as
well.
(handle_one_xevent): When inside a nested event loop, just push
selections to that queue.
(XTread_socket): Allow reading X events if x_dnd_unwind_flag is
true, even though DND is in progress.
(x_delete_display): Delete pending selection events for the
display that is going away.
* src/xterm.h: Update prototypes.
Diffstat (limited to 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 274c7b3fa84..55d710ed627 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -389,14 +389,6 @@ next_kbd_event (union buffered_input_event *ptr) | |||
| 389 | return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1; | 389 | return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1; |
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | #ifdef HAVE_X11 | ||
| 393 | static union buffered_input_event * | ||
| 394 | prev_kbd_event (union buffered_input_event *ptr) | ||
| 395 | { | ||
| 396 | return ptr == kbd_buffer ? kbd_buffer + KBD_BUFFER_SIZE - 1 : ptr - 1; | ||
| 397 | } | ||
| 398 | #endif | ||
| 399 | |||
| 400 | /* Like EVENT_START, but assume EVENT is an event. | 392 | /* Like EVENT_START, but assume EVENT is an event. |
| 401 | This pacifies gcc -Wnull-dereference, which might otherwise | 393 | This pacifies gcc -Wnull-dereference, which might otherwise |
| 402 | complain about earlier checks that EVENT is indeed an event. */ | 394 | complain about earlier checks that EVENT is indeed an event. */ |
| @@ -3528,6 +3520,11 @@ readable_events (int flags) | |||
| 3528 | return 1; | 3520 | return 1; |
| 3529 | } | 3521 | } |
| 3530 | 3522 | ||
| 3523 | #ifdef HAVE_X_WINDOWS | ||
| 3524 | if (x_detect_pending_selection_requests ()) | ||
| 3525 | return 1; | ||
| 3526 | #endif | ||
| 3527 | |||
| 3531 | if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && some_mouse_moved ()) | 3528 | if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && some_mouse_moved ()) |
| 3532 | return 1; | 3529 | return 1; |
| 3533 | if (single_kboard) | 3530 | if (single_kboard) |
| @@ -3699,25 +3696,6 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, | |||
| 3699 | Vquit_flag = Vthrow_on_input; | 3696 | Vquit_flag = Vthrow_on_input; |
| 3700 | } | 3697 | } |
| 3701 | 3698 | ||
| 3702 | |||
| 3703 | #ifdef HAVE_X11 | ||
| 3704 | |||
| 3705 | /* Put a selection input event back in the head of the event queue. */ | ||
| 3706 | |||
| 3707 | void | ||
| 3708 | kbd_buffer_unget_event (struct selection_input_event *event) | ||
| 3709 | { | ||
| 3710 | /* Don't let the very last slot in the buffer become full, */ | ||
| 3711 | union buffered_input_event *kp = prev_kbd_event (kbd_fetch_ptr); | ||
| 3712 | if (kp != kbd_store_ptr) | ||
| 3713 | { | ||
| 3714 | kp->sie = *event; | ||
| 3715 | kbd_fetch_ptr = kp; | ||
| 3716 | } | ||
| 3717 | } | ||
| 3718 | |||
| 3719 | #endif | ||
| 3720 | |||
| 3721 | /* Limit help event positions to this range, to avoid overflow problems. */ | 3699 | /* Limit help event positions to this range, to avoid overflow problems. */ |
| 3722 | #define INPUT_EVENT_POS_MAX \ | 3700 | #define INPUT_EVENT_POS_MAX \ |
| 3723 | ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \ | 3701 | ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \ |
| @@ -3874,6 +3852,11 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3874 | struct timespec *end_time) | 3852 | struct timespec *end_time) |
| 3875 | { | 3853 | { |
| 3876 | Lisp_Object obj, str; | 3854 | Lisp_Object obj, str; |
| 3855 | #ifdef HAVE_X_WINDOWS | ||
| 3856 | bool had_pending_selection_requests; | ||
| 3857 | |||
| 3858 | had_pending_selection_requests = false; | ||
| 3859 | #endif | ||
| 3877 | 3860 | ||
| 3878 | #ifdef subprocesses | 3861 | #ifdef subprocesses |
| 3879 | if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4) | 3862 | if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4) |
| @@ -3926,10 +3909,18 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3926 | #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL) | 3909 | #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL) |
| 3927 | gobble_input (); | 3910 | gobble_input (); |
| 3928 | #endif | 3911 | #endif |
| 3912 | |||
| 3929 | if (kbd_fetch_ptr != kbd_store_ptr) | 3913 | if (kbd_fetch_ptr != kbd_store_ptr) |
| 3930 | break; | 3914 | break; |
| 3931 | if (some_mouse_moved ()) | 3915 | if (some_mouse_moved ()) |
| 3932 | break; | 3916 | break; |
| 3917 | #ifdef HAVE_X_WINDOWS | ||
| 3918 | if (x_detect_pending_selection_requests ()) | ||
| 3919 | { | ||
| 3920 | had_pending_selection_requests = true; | ||
| 3921 | break; | ||
| 3922 | } | ||
| 3923 | #endif | ||
| 3933 | if (end_time) | 3924 | if (end_time) |
| 3934 | { | 3925 | { |
| 3935 | struct timespec now = current_timespec (); | 3926 | struct timespec now = current_timespec (); |
| @@ -3966,6 +3957,16 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3966 | gobble_input (); | 3957 | gobble_input (); |
| 3967 | } | 3958 | } |
| 3968 | 3959 | ||
| 3960 | #ifdef HAVE_X_WINDOWS | ||
| 3961 | /* Handle pending selection requests. This can happen if Emacs | ||
| 3962 | enters a recursive edit inside a nested event loop (probably | ||
| 3963 | because the debugger opened) or someone called | ||
| 3964 | `read-char'. */ | ||
| 3965 | |||
| 3966 | if (had_pending_selection_requests) | ||
| 3967 | x_handle_pending_selection_requests (); | ||
| 3968 | #endif | ||
| 3969 | |||
| 3969 | if (CONSP (Vunread_command_events)) | 3970 | if (CONSP (Vunread_command_events)) |
| 3970 | { | 3971 | { |
| 3971 | Lisp_Object first; | 3972 | Lisp_Object first; |
| @@ -4345,6 +4346,10 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 4345 | ? movement_frame->last_mouse_device | 4346 | ? movement_frame->last_mouse_device |
| 4346 | : virtual_core_pointer_name); | 4347 | : virtual_core_pointer_name); |
| 4347 | } | 4348 | } |
| 4349 | #ifdef HAVE_X_WINDOWS | ||
| 4350 | else if (had_pending_selection_requests) | ||
| 4351 | obj = Qnil; | ||
| 4352 | #endif | ||
| 4348 | else | 4353 | else |
| 4349 | /* We were promised by the above while loop that there was | 4354 | /* We were promised by the above while loop that there was |
| 4350 | something for us to read! */ | 4355 | something for us to read! */ |
| @@ -7241,7 +7246,10 @@ lucid_event_type_list_p (Lisp_Object object) | |||
| 7241 | If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal | 7246 | If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal |
| 7242 | events (FOCUS_IN_EVENT). | 7247 | events (FOCUS_IN_EVENT). |
| 7243 | If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse | 7248 | If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse |
| 7244 | movements and toolkit scroll bar thumb drags. */ | 7249 | movements and toolkit scroll bar thumb drags. |
| 7250 | |||
| 7251 | On X, this also returns if the selection event chain is full, since | ||
| 7252 | that's also "keyboard input". */ | ||
| 7245 | 7253 | ||
| 7246 | static bool | 7254 | static bool |
| 7247 | get_input_pending (int flags) | 7255 | get_input_pending (int flags) |