[WebDriver] Add synchronization for key action (#37403)

Implement action synchronization for key event. Previously only done for
pointer https://github.com/servo/servo/pull/36932 and wheel
https://github.com/servo/servo/pull/37260.

---------

Signed-off-by: PotatoCP <kenzieradityatirtarahardja18@gmail.com>
This commit is contained in:
Kenzie Raditya Tirtarahardja 2025-06-18 15:26:44 +08:00 committed by GitHub
parent f97cdb4d12
commit cdc8b45965
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 171 additions and 118 deletions

View file

@ -8,7 +8,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use euclid::Vector2D;
use keyboard_types::{Key, KeyboardEvent, Modifiers, ShortcutMatcher};
use keyboard_types::{Key, Modifiers, ShortcutMatcher};
use log::{error, info};
use servo::base::id::WebViewId;
use servo::config::{opts, pref};
@ -17,8 +17,8 @@ use servo::webrender_api::ScrollLocation;
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize};
use servo::{
AllowOrDenyRequest, AuthenticationRequest, FilterPattern, FormControl, GamepadHapticEffectType,
LoadStatus, PermissionRequest, Servo, ServoDelegate, ServoError, SimpleDialog, TouchEventType,
WebView, WebViewBuilder, WebViewDelegate,
KeyboardEvent, LoadStatus, PermissionRequest, Servo, ServoDelegate, ServoError, SimpleDialog,
TouchEventType, WebView, WebViewBuilder, WebViewDelegate,
};
use url::Url;
@ -314,7 +314,7 @@ impl RunningAppState {
/// Handle servoshell key bindings that may have been prevented by the page in the focused webview.
fn handle_overridable_key_bindings(&self, webview: ::servo::WebView, event: KeyboardEvent) {
let origin = webview.rect().min.ceil().to_i32();
ShortcutMatcher::from_event(event)
ShortcutMatcher::from_event(event.event)
.shortcut(CMD_OR_CONTROL, '=', || {
webview.set_zoom(1.1);
})

View file

@ -184,16 +184,16 @@ impl Window {
// no keyboard event is emitted. A dummy event is created in this case.
(KeyboardEvent::default(), None)
};
event.key = Key::Character(character.to_string());
event.event.key = Key::Character(character.to_string());
if event.state == KeyState::Down {
if event.event.state == KeyState::Down {
// Ensure that when we receive a keyup event from winit, we are able
// to infer that it's related to this character and set the event
// properties appropriately.
if let Some(key_code) = key_code {
self.keys_down
.borrow_mut()
.insert(key_code, event.key.clone());
.insert(key_code, event.event.key.clone());
}
}
@ -223,20 +223,24 @@ impl Window {
}
}
if keyboard_event.state == KeyState::Down && keyboard_event.key == Key::Unidentified {
if keyboard_event.event.state == KeyState::Down &&
keyboard_event.event.key == Key::Unidentified
{
// If pressed and probably printable, we expect a ReceivedCharacter event.
// Wait for that to be received and don't queue any event right now.
self.last_pressed
.set(Some((keyboard_event, Some(winit_event.logical_key))));
return;
} else if keyboard_event.state == KeyState::Up && keyboard_event.key == Key::Unidentified {
} else if keyboard_event.event.state == KeyState::Up &&
keyboard_event.event.key == Key::Unidentified
{
// If release and probably printable, this is following a ReceiverCharacter event.
if let Some(key) = self.keys_down.borrow_mut().remove(&winit_event.logical_key) {
keyboard_event.key = key;
keyboard_event.event.key = key;
}
}
if keyboard_event.key != Key::Unidentified {
if keyboard_event.event.key != Key::Unidentified {
self.last_pressed.set(None);
let xr_poses = self.xr_window_poses.borrow();
for xr_window_pose in &*xr_poses {
@ -284,7 +288,7 @@ impl Window {
};
let mut handled = true;
ShortcutMatcher::from_event(key_event.clone())
ShortcutMatcher::from_event(key_event.event.clone())
.shortcut(CMD_OR_CONTROL, 'R', || focused_webview.reload())
.shortcut(CMD_OR_CONTROL, 'W', || {
state.close_webview(focused_webview.id());
@ -828,14 +832,14 @@ impl servo::webxr::glwindow::GlWindow for XRWindow {
impl XRWindowPose {
fn handle_xr_translation(&self, input: &KeyboardEvent) {
if input.state != KeyState::Down {
if input.event.state != KeyState::Down {
return;
}
const NORMAL_TRANSLATE: f32 = 0.1;
const QUICK_TRANSLATE: f32 = 1.0;
let mut x = 0.0;
let mut z = 0.0;
match input.key {
match input.event.key {
Key::Character(ref k) => match &**k {
"w" => z = -NORMAL_TRANSLATE,
"W" => z = -QUICK_TRANSLATE,

View file

@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers};
use keyboard_types::{Code, Key, KeyState, Location, Modifiers};
use servo::KeyboardEvent;
use winit::event::{ElementState, KeyEvent};
use winit::keyboard::{
Key as WinitKey, KeyCode, KeyLocation as WinitKeyLocation, ModifiersState, NamedKey,
@ -583,13 +584,13 @@ fn keyboard_modifiers_from_winit_modifiers(mods: ModifiersState) -> Modifiers {
}
pub fn keyboard_event_from_winit(key_event: &KeyEvent, state: ModifiersState) -> KeyboardEvent {
KeyboardEvent {
state: KeyState::from_winit_key_event(key_event),
key: Key::from_winit_key_event(key_event),
code: Code::from_winit_key_event(key_event),
location: Location::from_winit_key_event(key_event),
modifiers: keyboard_modifiers_from_winit_modifiers(state),
repeat: false,
is_composing: false,
}
KeyboardEvent::new_without_event(
KeyState::from_winit_key_event(key_event),
Key::from_winit_key_event(key_event),
Code::from_winit_key_event(key_event),
Location::from_winit_key_event(key_event),
keyboard_modifiers_from_winit_modifiers(state),
false,
false,
)
}

View file

@ -626,22 +626,14 @@ impl RunningAppState {
}
pub fn key_down(&self, key: Key) {
let key_event = KeyboardEvent {
state: KeyState::Down,
key,
..KeyboardEvent::default()
};
let key_event = KeyboardEvent::from_state_and_key(KeyState::Down, key);
self.active_webview()
.notify_input_event(InputEvent::Keyboard(key_event));
self.perform_updates();
}
pub fn key_up(&self, key: Key) {
let key_event = KeyboardEvent {
state: KeyState::Up,
key,
..KeyboardEvent::default()
};
let key_event = KeyboardEvent::from_state_and_key(KeyState::Up, key);
self.active_webview()
.notify_input_event(InputEvent::Keyboard(key_event));
self.perform_updates();
@ -653,22 +645,20 @@ impl RunningAppState {
return;
}
let active_webview = self.active_webview();
active_webview.notify_input_event(InputEvent::Keyboard(KeyboardEvent {
state: KeyState::Down,
key: Key::Process,
..KeyboardEvent::default()
}));
active_webview.notify_input_event(InputEvent::Keyboard(KeyboardEvent::from_state_and_key(
KeyState::Down,
Key::Process,
)));
active_webview.notify_input_event(InputEvent::Ime(ImeEvent::Composition(
CompositionEvent {
state: CompositionState::End,
data: text,
},
)));
active_webview.notify_input_event(InputEvent::Keyboard(KeyboardEvent {
state: KeyState::Up,
key: Key::Process,
..KeyboardEvent::default()
}));
active_webview.notify_input_event(InputEvent::Keyboard(KeyboardEvent::from_state_and_key(
KeyState::Up,
Key::Process,
)));
self.perform_updates();
}