From e555b2bd28ba4dedb2a6532508d1b2cfdaa4c653 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Fri, 7 Feb 2025 12:04:05 +0100 Subject: [PATCH] New function insert-special-event and special event sleep-event * doc/lispref/commands.texi (Misc Events): Add sleep-event. (Special Events): New function insert-special-event. * etc/NEWS: New function insert-special-event. New event 'sleep-event'. Fix typos. * src/keyboard.c (Finsert_special_event): New defun. (syms_of_keyboard): Declare Qsleep_event. Define subroutine Sinsert_special_event. Add sleep-event to Vspecial_event_map. (Bug#63620) (kbd_buffer_get_event, make_lispy_event) (init_while_no_input_ignore_events, is_ignored_event): * src/termhooks.h (event_kind): Add SLEEP_EVENT. (cherry picked from commit d41178368eb73873f34c15b58062a7447802c914) --- doc/lispref/commands.texi | 32 +++++++++++++++++++ src/keyboard.c | 67 +++++++++++++++++++++++++++++++++++++++ src/termhooks.h | 3 ++ 3 files changed, 102 insertions(+) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 97b9712f4a7..d2e32ff7196 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2754,6 +2754,14 @@ To test the signal handler, you can make Emacs send a signal to itself: (signal-process (emacs-pid) 'sigusr1) @end smallexample +@cindex @code{sleep-event} event +@item (sleep-event @var{sleep-wake}) +This event is injected when the device Emacs is running on enters or +leaves the sleep state. A non-@code{nil} @var{sleep-wake} indicates +entering the sleep state. + +This is implemented only on GNU/Linux. + @cindex @code{language-change} event @item language-change This kind of event is generated on MS-Windows when the input language @@ -4013,6 +4021,30 @@ The keymap which defines how to handle special events---and which events are special---is in the variable @code{special-event-map} (@pxref{Controlling Active Maps}). +@defun insert-special-event +@cindex inserting special events +This function inserts a special event into the input event queue. Only +event types which are contained in the @code{special-event-map} keymap +are accepted. As a result, the handler specified in the keymap is +invoked. + +The function returns @code{nil}. Example: + +@example +(defun my-event-handler (event) + (interactive "e") + (message "Event arrived: %S" event)) +@result{} my-event-handler + +(keymap-set special-event-map "" #'my-event-handler) +@result{} my-event-handler + +(insert-special-event '(sleep-event t)) +@result{} nil +@result{} "Event arrived: (sleep-event t)" +@end example +@end defun + @node Waiting @section Waiting for Elapsed Time or Input @cindex waiting diff --git a/src/keyboard.c b/src/keyboard.c index 83e00cc517a..d51b79e7f6b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4273,6 +4273,7 @@ kbd_buffer_get_event (KBOARD **kbp, case CONFIG_CHANGED_EVENT: case FOCUS_OUT_EVENT: case SELECT_WINDOW_EVENT: + case SLEEP_EVENT: { obj = make_lispy_event (&event->ie); kbd_fetch_ptr = next_kbd_event (event); @@ -7110,6 +7111,9 @@ make_lispy_event (struct input_event *event) #endif #endif /* USE_FILE_NOTIFY */ + case SLEEP_EVENT: + return Fcons (Qsleep_event, event->arg); + case CONFIG_CHANGED_EVENT: return list3 (Qconfig_changed_event, event->arg, event->frame_or_window); @@ -11631,6 +11635,63 @@ If CHECK-TIMERS is non-nil, timers that are ready to run will do so. */) ? Qt : Qnil); } +DEFUN ("insert-special-event", Finsert_special_event, Sinsert_special_event, + 1, 1, 0, + doc: /* Insert the special EVENT into the input event queue. +Only 'input_event' slots KIND and ARG are set. */) + (Lisp_Object event) +{ + /* Check, that it is a special event. */ + CHECK_CONS (event); + if (NILP (access_keymap + (get_keymap (Vspecial_event_map, 0, 1), event, 0, 0, 1))) + signal_error ("Invalid event kind", XCAR (event)); + + /* Construct an input event. */ + struct input_event ie; + EVENT_INIT (ie); + ie.kind = + (EQ (XCAR (event), Qdelete_frame) ? DELETE_WINDOW_EVENT +#ifdef HAVE_NTGUI + : EQ (XCAR (event), Qend_session) ? END_SESSION_EVENT +#endif +#ifdef HAVE_NS + : EQ (XCAR (event), Qns_put_working_text) ? KEY_NS_PUT_WORKING_TEXT +#endif +#ifdef HAVE_NS + : EQ (XCAR (event), Qns_unput_working_text) ? KEY_NS_UNPUT_WORKING_TEXT +#endif + : EQ (XCAR (event), Qiconify_frame) ? ICONIFY_EVENT + : EQ (XCAR (event), Qmake_frame_visible) ? DEICONIFY_EVENT + // : EQ (XCAR (event), Qselect_window) ? SELECT_WINDOW_EVENT + : EQ (XCAR (event), Qsave_session) ? SAVE_SESSION_EVENT +#ifdef HAVE_DBUS + : EQ (XCAR (event), Qdbus_event) ? DBUS_EVENT +#endif +#ifdef THREADS_ENABLED + : EQ (XCAR (event), Qthread_event) ? THREAD_EVENT +#endif +#ifdef USE_FILE_NOTIFY + : EQ (XCAR (event), Qfile_notify) ? FILE_NOTIFY_EVENT +#endif /* USE_FILE_NOTIFY */ + : EQ (XCAR (event), Qconfig_changed_event) ? CONFIG_CHANGED_EVENT +#if defined (WINDOWSNT) + : EQ (XCAR (event), Qlanguage_change) ? LANGUAGE_CHANGE_EVENT +#endif + : EQ (XCAR (event), Qfocus_in) ? FOCUS_IN_EVENT + : EQ (XCAR (event), Qfocus_out) ? FOCUS_OUT_EVENT + : EQ (XCAR (event), Qmove_frame) ? MOVE_FRAME_EVENT + : EQ (XCAR (event), Qsleep_event) ? SLEEP_EVENT + : NO_EVENT); + ie.frame_or_window = Qnil; + ie.arg = CDR (event); + + /* Store it into the input event queue. */ + kbd_buffer_store_event (&ie); + + return (Qnil); +} + /* Reallocate recent_keys copying the recorded keystrokes in the right order. */ static void @@ -12803,6 +12864,7 @@ init_while_no_input_ignore_events (void) #ifdef THREADS_ENABLED events = Fcons (Qthread_event, events); #endif + events = Fcons (Qsleep_event, events); return events; } @@ -12826,6 +12888,7 @@ is_ignored_event (union buffered_input_event *event) #ifdef HAVE_DBUS case DBUS_EVENT: ignore_event = Qdbus_event; break; #endif + case SLEEP_EVENT: ignore_event = Qsleep_event; break; default: ignore_event = Qnil; break; } @@ -12931,6 +12994,7 @@ syms_of_keyboard (void) #endif /* USE_FILE_NOTIFY */ DEFSYM (Qtouch_end, "touch-end"); + DEFSYM (Qsleep_event, "sleep-event"); /* Menu and tool bar item parts. */ DEFSYM (QCenable, ":enable"); @@ -13144,6 +13208,7 @@ syms_of_keyboard (void) defsubr (&Srecursive_edit); defsubr (&Sinternal_track_mouse); defsubr (&Sinput_pending_p); + defsubr (&Sinsert_special_event); defsubr (&Slossage_size); defsubr (&Srecent_keys); defsubr (&Sthis_command_keys); @@ -14005,6 +14070,8 @@ keys_of_keyboard (void) "handle-focus-out"); initial_define_lispy_key (Vspecial_event_map, "move-frame", "handle-move-frame"); + initial_define_lispy_key (Vspecial_event_map, "sleep-event", + "ignore"); } /* Mark the pointers in the kboard objects. diff --git a/src/termhooks.h b/src/termhooks.h index 0795148f1af..a77ca25e159 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -291,6 +291,9 @@ enum event_kind , FILE_NOTIFY_EVENT #endif + /* Sleep/wake event. */ + , SLEEP_EVENT + /* Pre-edit text was changed. */ , PREEDIT_TEXT_EVENT -- 2.39.5