aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorPo Lu2022-06-06 11:08:19 +0800
committerPo Lu2022-06-06 11:08:19 +0800
commitb90d2a6a63f1b7f73d2cb7e976148e8195fc5502 (patch)
tree965057d58b783e920711e05138ad56184ceec6c4 /src/keyboard.c
parent0a36671f415bd681ddca0bad8612aca031fd407d (diff)
downloademacs-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.c64
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
393static union buffered_input_event *
394prev_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
3707void
3708kbd_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
7246static bool 7254static bool
7247get_input_pending (int flags) 7255get_input_pending (int flags)