From d41178368eb73873f34c15b58062a7447802c914 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. --- doc/lispref/commands.texi | 32 +++++++++++++++++++ etc/NEWS | 19 ++++++++--- src/keyboard.c | 67 +++++++++++++++++++++++++++++++++++++++ src/termhooks.h | 3 ++ 4 files changed, 117 insertions(+), 4 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 39514145a1e..c3891b70406 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2756,6 +2756,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 @@ -4029,6 +4037,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/etc/NEWS b/etc/NEWS index ade635aa924..df1aff9213e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -486,9 +486,9 @@ Emacs exit. ** Message --- -*** In-Reply-To header contains only a message id. -The In-Reply-To header created when replying to a message now contains -only the originating message's id, conforming to RFC5322. The previous +*** "In-Reply-To" header contains only a message id. +The "In-Reply-To" header created when replying to a message now contains +only the originating message's id, conforming to RFC 5322. The previous behavior included additional information about the originating message. The new variable 'message-header-use-obsolete-in-reply-to', nil by default, can be set to a non-nil value to restore the previous behavior. @@ -993,7 +993,7 @@ instead. Since Python 2 EOL was over 5 years ago, this release removes Python 2-only builtins such as "file" from the default highlighting in 'python-mode' and 'python-ts-mode'. If you would like them highlighted, -customize the new user option `python-2-support' to a non-nil value and +customize the new user option 'python-2-support' to a non-nil value and restart Emacs. --- @@ -1354,6 +1354,17 @@ provide instructions for finding the definition. New convenience function 'find-function-update-type-alist' offers a concise way to update a symbol's 'find-function-type-alist' property. +** Special Events + ++++ +*** New primitive 'insert-special-event'. +This function inserts the special EVENT into the input event queue. + ++++ +*** New event type 'sleep-event'. +This event is sent when the device running Emacs enters or leaves the +sleep state. + * Changes in Emacs 31.1 on Non-Free Operating Systems diff --git a/src/keyboard.c b/src/keyboard.c index 2d8c45c05ee..ace5e1e3fef 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); @@ -14017,6 +14082,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