UI/AppKit: Store the original key-down event for WebContent processing

When a shortcut is an alternative key, macOS first fires a key event for
the primary key. Then if it is not handled, it fires an event for the
alternative key. For example, we see these two events in a row when we
press cmd and =/+:

    NSEvent: type=KeyDown flags=0x100108 chars="=" keyCode=25
    NSEvent: type=KeyDown flags=0x100108 chars="+" keyCode=24

For dead key processing, we don't handle these events right away. By the
time we get to doCommandBySelector, when we call [NSApp currentEvent],
we see the following events:

    NSEvent: type=KeyDown flags=0x100108 chars="=" keyCode=24
    NSEvent: type=AppDefined flags=0

The AppDefined event is internally posted by our event loop. So it seems
we cannot rely on currentEvent being the key-down event we are looking
for.

Instead, we can store the key-down event that we last saw.
This commit is contained in:
Timothy Flynn 2025-11-27 08:12:02 -05:00 committed by Tim Ledbetter
parent 934817d45e
commit bf75f52ce0
Notes: github-actions[bot] 2025-11-27 13:52:51 +00:00

View file

@ -62,6 +62,9 @@ struct HideCursor {
// event ourselves to prevent indefinitely repeating the event.
@property (nonatomic, strong) NSEvent* event_being_redispatched;
// To handle key events after dead key processing, we need to hold onto the originating key-down event.
@property (nonatomic, strong) NSEvent* current_key_down_event;
@end
@implementation LadybirdWebView
@ -842,6 +845,17 @@ struct HideCursor {
};
}
- (void)handleCurrentKeyDownEvent
{
if (!self.current_key_down_event)
return;
auto key_event = Ladybird::ns_event_to_key_event(Web::KeyEvent::Type::KeyDown, self.current_key_down_event);
m_web_view_bridge->enqueue_input_event(move(key_event));
self.current_key_down_event = nil;
}
- (void)selectDropdownAction:(NSMenuItem*)menuItem
{
NSNumber* data = [menuItem representedObject];
@ -1072,6 +1086,7 @@ struct HideCursor {
return;
}
self.current_key_down_event = event;
[self interpretKeyEvents:@[ event ]];
}
@ -1138,20 +1153,12 @@ struct HideCursor {
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
{
auto* event = [NSApp currentEvent];
if (event && event.type == NSEventTypeKeyDown) {
auto key_event = Ladybird::ns_event_to_key_event(Web::KeyEvent::Type::KeyDown, event);
m_web_view_bridge->enqueue_input_event(move(key_event));
}
[self handleCurrentKeyDownEvent];
}
- (void)doCommandBySelector:(SEL)selector
{
auto* event = [NSApp currentEvent];
if (event && event.type == NSEventTypeKeyDown) {
auto key_event = Ladybird::ns_event_to_key_event(Web::KeyEvent::Type::KeyDown, event);
m_web_view_bridge->enqueue_input_event(move(key_event));
}
[self handleCurrentKeyDownEvent];
}
- (BOOL)hasMarkedText