[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

@ -2,7 +2,7 @@
* 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::{CompositionEvent, KeyboardEvent};
use keyboard_types::{Code, CompositionEvent, Key, KeyState, Location, Modifiers};
use log::error;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize};
@ -53,7 +53,7 @@ impl InputEvent {
InputEvent::EditingAction(..) => None,
InputEvent::Gamepad(..) => None,
InputEvent::Ime(..) => None,
InputEvent::Keyboard(..) => None,
InputEvent::Keyboard(event) => event.webdriver_id,
InputEvent::MouseButton(event) => event.webdriver_id,
InputEvent::MouseMove(event) => event.webdriver_id,
InputEvent::Touch(..) => None,
@ -67,7 +67,9 @@ impl InputEvent {
InputEvent::EditingAction(..) => {},
InputEvent::Gamepad(..) => {},
InputEvent::Ime(..) => {},
InputEvent::Keyboard(..) => {},
InputEvent::Keyboard(ref mut event) => {
event.webdriver_id = webdriver_id;
},
InputEvent::MouseButton(ref mut event) => {
event.webdriver_id = webdriver_id;
},
@ -85,6 +87,51 @@ impl InputEvent {
}
}
/// Recreate KeyboardEvent from keyboard_types to pair it with webdriver_id,
/// which is used for webdriver action synchronization.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct KeyboardEvent {
pub event: ::keyboard_types::KeyboardEvent,
webdriver_id: Option<WebDriverMessageId>,
}
impl KeyboardEvent {
pub fn new(keyboard_event: ::keyboard_types::KeyboardEvent) -> Self {
Self {
event: keyboard_event,
webdriver_id: None,
}
}
pub fn new_without_event(
state: KeyState,
key: Key,
code: Code,
location: Location,
modifiers: Modifiers,
repeat: bool,
is_composing: bool,
) -> Self {
Self::new(::keyboard_types::KeyboardEvent {
state,
key,
code,
location,
modifiers,
repeat,
is_composing,
})
}
pub fn from_state_and_key(state: KeyState, key: Key) -> Self {
Self::new(::keyboard_types::KeyboardEvent {
state,
key,
..::keyboard_types::KeyboardEvent::default()
})
}
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MouseButtonEvent {
pub action: MouseButtonAction,

View file

@ -25,7 +25,6 @@ use crossbeam_channel::Sender;
use euclid::{Scale, Size2D};
use http::{HeaderMap, Method, StatusCode};
use ipc_channel::ipc::IpcSender;
pub use keyboard_types::{KeyboardEvent, Modifiers};
use log::warn;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;

View file

@ -42,7 +42,13 @@ pub enum WebDriverCommandMsg {
/// Act as if keys were pressed in the browsing context with the given ID.
SendKeys(BrowsingContextId, Vec<WebDriverInputEvent>),
/// Act as if keys were pressed or release in the browsing context with the given ID.
KeyboardAction(BrowsingContextId, KeyboardEvent),
KeyboardAction(
BrowsingContextId,
KeyboardEvent,
// Should never be None.
Option<WebDriverMessageId>,
IpcSender<WebDriverCommandResponse>,
),
/// Act as if the mouse was clicked in the browsing context with the given ID.
MouseButtonAction(
WebViewId,