mirror of
https://github.com/servo/servo.git
synced 2025-09-25 14:20:08 +01:00
servoshell: Move touch event simulation to servoshell (#39352)
This change removes the `DebugOption` (`-Z`) for touch event simulation and moves the implementation of the feature to servoshell. The resaoning for this is: - This is really a servoshell feature and can be implemented on top of the API. This moves more code out of the already too-complicated renderer. - I would like to consolidate `DebugOptions` into a `ServoLogOptions` to collect all options for configuring Servo logging. This requires moving away all of the non-logging options. - Eventually touch event simulation will be able to reuse the fling implementation from servoshell as we are actually simulating touch events sent to the `WebView`. Testing: This changes a conditional feature that's used for manual debugging. It is difficult to write tests for this as there are no servoshell tests that verify input handling. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
70d54e86bd
commit
b73538a676
7 changed files with 142 additions and 116 deletions
|
@ -117,9 +117,6 @@ pub struct ServoRenderer {
|
||||||
/// Some XR devices want to run on the main thread.
|
/// Some XR devices want to run on the main thread.
|
||||||
webxr_main_thread: webxr::MainThreadRegistry,
|
webxr_main_thread: webxr::MainThreadRegistry,
|
||||||
|
|
||||||
/// True to translate mouse input into touch events.
|
|
||||||
pub(crate) convert_mouse_to_touch: bool,
|
|
||||||
|
|
||||||
/// The last position in the rendered view that the mouse moved over. This becomes `None`
|
/// The last position in the rendered view that the mouse moved over. This becomes `None`
|
||||||
/// when the mouse leaves the rendered view.
|
/// when the mouse leaves the rendered view.
|
||||||
pub(crate) last_mouse_move_position: Option<DevicePoint>,
|
pub(crate) last_mouse_move_position: Option<DevicePoint>,
|
||||||
|
@ -306,7 +303,7 @@ impl ServoRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IOCompositor {
|
impl IOCompositor {
|
||||||
pub fn new(state: InitialCompositorState, convert_mouse_to_touch: bool) -> Self {
|
pub fn new(state: InitialCompositorState) -> Self {
|
||||||
let registration = state.mem_profiler_chan.prepare_memory_reporting(
|
let registration = state.mem_profiler_chan.prepare_memory_reporting(
|
||||||
"compositor".into(),
|
"compositor".into(),
|
||||||
state.sender.clone(),
|
state.sender.clone(),
|
||||||
|
@ -327,7 +324,6 @@ impl IOCompositor {
|
||||||
webrender_gl: state.webrender_gl,
|
webrender_gl: state.webrender_gl,
|
||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
webxr_main_thread: state.webxr_main_thread,
|
webxr_main_thread: state.webxr_main_thread,
|
||||||
convert_mouse_to_touch,
|
|
||||||
last_mouse_move_position: None,
|
last_mouse_move_position: None,
|
||||||
frame_delayer: Default::default(),
|
frame_delayer: Default::default(),
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -283,10 +283,6 @@ impl TouchHandler {
|
||||||
debug_assert!(old.is_some(), "Sequence already removed?");
|
debug_assert!(old.is_some(), "Sequence already removed?");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_get_current_touch_sequence(&self) -> Option<&TouchSequenceInfo> {
|
|
||||||
self.touch_sequence_map.get(&self.current_sequence_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_current_touch_sequence_mut(&mut self) -> &mut TouchSequenceInfo {
|
pub fn get_current_touch_sequence_mut(&mut self) -> &mut TouchSequenceInfo {
|
||||||
self.touch_sequence_map
|
self.touch_sequence_map
|
||||||
.get_mut(&self.current_sequence_id)
|
.get_mut(&self.current_sequence_id)
|
||||||
|
|
|
@ -16,7 +16,7 @@ use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType};
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
AnimationState, CompositorHitTestResult, InputEvent, MouseButton, MouseButtonAction,
|
AnimationState, CompositorHitTestResult, InputEvent, MouseButton, MouseButtonAction,
|
||||||
MouseButtonEvent, MouseMoveEvent, ScrollEvent as EmbedderScrollEvent, ShutdownState,
|
MouseButtonEvent, MouseMoveEvent, ScrollEvent as EmbedderScrollEvent, ShutdownState,
|
||||||
TouchEvent, TouchEventResult, TouchEventType, TouchId, ViewportDetails,
|
TouchEvent, TouchEventResult, TouchEventType, ViewportDetails,
|
||||||
};
|
};
|
||||||
use euclid::{Point2D, Scale, Vector2D};
|
use euclid::{Point2D, Scale, Vector2D};
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
|
@ -365,62 +365,6 @@ impl WebViewRenderer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.global.borrow().convert_mouse_to_touch {
|
|
||||||
match event {
|
|
||||||
InputEvent::MouseButton(event) => {
|
|
||||||
match (event.button, event.action) {
|
|
||||||
(MouseButton::Left, MouseButtonAction::Down) => self.on_touch_down(
|
|
||||||
TouchEvent::new(TouchEventType::Down, TouchId(0), event.point),
|
|
||||||
),
|
|
||||||
(MouseButton::Left, MouseButtonAction::Up) => self.on_touch_up(
|
|
||||||
TouchEvent::new(TouchEventType::Up, TouchId(0), event.point),
|
|
||||||
),
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
InputEvent::MouseMove(event) => {
|
|
||||||
if let Some(state) = self.touch_handler.try_get_current_touch_sequence() {
|
|
||||||
// We assume that the debug option `-Z convert-mouse-to-touch` will only
|
|
||||||
// be used on devices without native touch input, so we can directly
|
|
||||||
// reuse the touch handler for tracking the state of pressed buttons.
|
|
||||||
match state.state {
|
|
||||||
TouchSequenceState::Touching | TouchSequenceState::Panning { .. } => {
|
|
||||||
self.on_touch_move(TouchEvent::new(
|
|
||||||
TouchEventType::Move,
|
|
||||||
TouchId(0),
|
|
||||||
event.point,
|
|
||||||
));
|
|
||||||
},
|
|
||||||
TouchSequenceState::MultiTouch => {
|
|
||||||
// Multitouch simulation currently is not implemented.
|
|
||||||
// Since we only get one mouse move event, we would need to
|
|
||||||
// dispatch one mouse move event per currently pressed mouse button.
|
|
||||||
},
|
|
||||||
TouchSequenceState::Pinching => {
|
|
||||||
// We only have one mouse button, so Pinching should be impossible.
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
log::error!(
|
|
||||||
"Touch handler is in Pinching state, which should be unreachable with \
|
|
||||||
-Z convert-mouse-to-touch debug option."
|
|
||||||
);
|
|
||||||
},
|
|
||||||
TouchSequenceState::PendingFling { .. } |
|
|
||||||
TouchSequenceState::Flinging { .. } |
|
|
||||||
TouchSequenceState::PendingClick(_) |
|
|
||||||
TouchSequenceState::Finished => {
|
|
||||||
// Mouse movement without a button being pressed is not
|
|
||||||
// translated to touch events.
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// We don't want to (directly) dispatch mouse events when simulating touch input.
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.dispatch_input_event_with_hit_testing(event);
|
self.dispatch_input_event_with_hit_testing(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,9 +128,6 @@ pub struct DebugOptions {
|
||||||
/// Whether to show in stdout style sharing cache stats after a restyle.
|
/// Whether to show in stdout style sharing cache stats after a restyle.
|
||||||
pub dump_style_statistics: bool,
|
pub dump_style_statistics: bool,
|
||||||
|
|
||||||
/// Translate mouse input into touch events.
|
|
||||||
pub convert_mouse_to_touch: bool,
|
|
||||||
|
|
||||||
/// Log GC passes and their durations.
|
/// Log GC passes and their durations.
|
||||||
pub gc_profile: bool,
|
pub gc_profile: bool,
|
||||||
}
|
}
|
||||||
|
@ -140,7 +137,6 @@ impl DebugOptions {
|
||||||
for option in debug_string.split(',') {
|
for option in debug_string.split(',') {
|
||||||
match option {
|
match option {
|
||||||
"help" => self.help = true,
|
"help" => self.help = true,
|
||||||
"convert-mouse-to-touch" => self.convert_mouse_to_touch = true,
|
|
||||||
"disable-share-style-cache" => self.disable_share_style_cache = true,
|
"disable-share-style-cache" => self.disable_share_style_cache = true,
|
||||||
"dump-display-list" => self.dump_display_list = true,
|
"dump-display-list" => self.dump_display_list = true,
|
||||||
"dump-stacking-context-tree" => self.dump_stacking_context_tree = true,
|
"dump-stacking-context-tree" => self.dump_stacking_context_tree = true,
|
||||||
|
|
|
@ -463,25 +463,22 @@ impl Servo {
|
||||||
// The compositor coordinates with the client window to create the final
|
// The compositor coordinates with the client window to create the final
|
||||||
// rendered page and display it somewhere.
|
// rendered page and display it somewhere.
|
||||||
let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown));
|
let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown));
|
||||||
let compositor = IOCompositor::new(
|
let compositor = IOCompositor::new(InitialCompositorState {
|
||||||
InitialCompositorState {
|
sender: compositor_proxy,
|
||||||
sender: compositor_proxy,
|
receiver: compositor_receiver,
|
||||||
receiver: compositor_receiver,
|
constellation_chan: constellation_chan.clone(),
|
||||||
constellation_chan: constellation_chan.clone(),
|
time_profiler_chan,
|
||||||
time_profiler_chan,
|
mem_profiler_chan,
|
||||||
mem_profiler_chan,
|
webrender,
|
||||||
webrender,
|
webrender_document,
|
||||||
webrender_document,
|
webrender_api,
|
||||||
webrender_api,
|
rendering_context,
|
||||||
rendering_context,
|
webrender_gl,
|
||||||
webrender_gl,
|
#[cfg(feature = "webxr")]
|
||||||
#[cfg(feature = "webxr")]
|
webxr_main_thread,
|
||||||
webxr_main_thread,
|
shutdown_state: shutdown_state.clone(),
|
||||||
shutdown_state: shutdown_state.clone(),
|
event_loop_waker,
|
||||||
event_loop_waker,
|
});
|
||||||
},
|
|
||||||
opts.debug.convert_mouse_to_touch,
|
|
||||||
);
|
|
||||||
|
|
||||||
let constellation_proxy = ConstellationProxy::new(constellation_chan);
|
let constellation_proxy = ConstellationProxy::new(constellation_chan);
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -79,6 +79,9 @@ pub struct Window {
|
||||||
/// the target of egui rendering and also where Servo rendering results are finally
|
/// the target of egui rendering and also where Servo rendering results are finally
|
||||||
/// blitted.
|
/// blitted.
|
||||||
window_rendering_context: Rc<WindowRenderingContext>,
|
window_rendering_context: Rc<WindowRenderingContext>,
|
||||||
|
/// A helper that simulates touch events when the `--simulate-touch-events` flag
|
||||||
|
/// is enabled.
|
||||||
|
touch_event_simulator: Option<TouchEventSimulator>,
|
||||||
// Keep this as the last field of the struct to ensure that the rendering context is
|
// Keep this as the last field of the struct to ensure that the rendering context is
|
||||||
// dropped first.
|
// dropped first.
|
||||||
// (https://github.com/servo/servo/issues/36711)
|
// (https://github.com/servo/servo/issues/36711)
|
||||||
|
@ -179,6 +182,9 @@ impl Window {
|
||||||
modifiers_state: Cell::new(ModifiersState::empty()),
|
modifiers_state: Cell::new(ModifiersState::empty()),
|
||||||
toolbar_height: Cell::new(Default::default()),
|
toolbar_height: Cell::new(Default::default()),
|
||||||
window_rendering_context,
|
window_rendering_context,
|
||||||
|
touch_event_simulator: servoshell_preferences
|
||||||
|
.simulate_touch_events
|
||||||
|
.then(Default::default),
|
||||||
rendering_context,
|
rendering_context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +281,29 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to handle a click
|
/// Helper function to handle a click
|
||||||
fn handle_mouse(&self, webview: &WebView, button: MouseButton, action: ElementState) {
|
fn handle_mouse_button_event(
|
||||||
|
&self,
|
||||||
|
webview: &WebView,
|
||||||
|
button: MouseButton,
|
||||||
|
action: ElementState,
|
||||||
|
) {
|
||||||
|
// `point` can be outside viewport, such as at toolbar with negative y-coordinate.
|
||||||
|
let point = self.webview_relative_mouse_point.get();
|
||||||
|
if !webview.rect().contains(point) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self
|
||||||
|
.touch_event_simulator
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|touch_event_simulator| {
|
||||||
|
touch_event_simulator
|
||||||
|
.maybe_consume_move_button_event(webview, button, action, point)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mouse_button = match &button {
|
let mouse_button = match &button {
|
||||||
MouseButton::Left => ServoMouseButton::Left,
|
MouseButton::Left => ServoMouseButton::Left,
|
||||||
MouseButton::Right => ServoMouseButton::Right,
|
MouseButton::Right => ServoMouseButton::Right,
|
||||||
|
@ -285,11 +313,6 @@ impl Window {
|
||||||
MouseButton::Other(value) => ServoMouseButton::Other(*value),
|
MouseButton::Other(value) => ServoMouseButton::Other(*value),
|
||||||
};
|
};
|
||||||
|
|
||||||
let point = self.webview_relative_mouse_point.get();
|
|
||||||
// `point` can be outside viewport, such as at toolbar with negative y-coordinate.
|
|
||||||
if !webview.rect().contains(point) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let action = match action {
|
let action = match action {
|
||||||
ElementState::Pressed => MouseButtonAction::Down,
|
ElementState::Pressed => MouseButtonAction::Down,
|
||||||
ElementState::Released => MouseButtonAction::Up,
|
ElementState::Released => MouseButtonAction::Up,
|
||||||
|
@ -302,6 +325,36 @@ impl Window {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function to handle mouse move events.
|
||||||
|
fn handle_mouse_move_event(&self, webview: &WebView, position: PhysicalPosition<f64>) {
|
||||||
|
let mut point = winit_position_to_euclid_point(position).to_f32();
|
||||||
|
point.y -= (self.toolbar_height() * self.hidpi_scale_factor()).0;
|
||||||
|
|
||||||
|
let previous_point = self.webview_relative_mouse_point.get();
|
||||||
|
self.webview_relative_mouse_point.set(point);
|
||||||
|
|
||||||
|
if !webview.rect().contains(point) {
|
||||||
|
if webview.rect().contains(previous_point) {
|
||||||
|
webview.notify_input_event(InputEvent::MouseLeftViewport(
|
||||||
|
MouseLeftViewportEvent::default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self
|
||||||
|
.touch_event_simulator
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|touch_event_simulator| {
|
||||||
|
touch_event_simulator.maybe_consume_mouse_move_event(webview, point)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
webview.notify_input_event(InputEvent::MouseMove(MouseMoveEvent::new(point)));
|
||||||
|
}
|
||||||
|
|
||||||
/// Handle key events before sending them to Servo.
|
/// Handle key events before sending them to Servo.
|
||||||
fn handle_intercepted_key_bindings(
|
fn handle_intercepted_key_bindings(
|
||||||
&self,
|
&self,
|
||||||
|
@ -623,22 +676,10 @@ impl WindowPortsMethods for Window {
|
||||||
WindowEvent::KeyboardInput { event, .. } => self.handle_keyboard_input(state, event),
|
WindowEvent::KeyboardInput { event, .. } => self.handle_keyboard_input(state, event),
|
||||||
WindowEvent::ModifiersChanged(modifiers) => self.modifiers_state.set(modifiers.state()),
|
WindowEvent::ModifiersChanged(modifiers) => self.modifiers_state.set(modifiers.state()),
|
||||||
WindowEvent::MouseInput { state, button, .. } => {
|
WindowEvent::MouseInput { state, button, .. } => {
|
||||||
self.handle_mouse(&webview, button, state);
|
self.handle_mouse_button_event(&webview, button, state);
|
||||||
},
|
},
|
||||||
WindowEvent::CursorMoved { position, .. } => {
|
WindowEvent::CursorMoved { position, .. } => {
|
||||||
let mut point = winit_position_to_euclid_point(position).to_f32();
|
self.handle_mouse_move_event(&webview, position);
|
||||||
point.y -= (self.toolbar_height() * self.hidpi_scale_factor()).0;
|
|
||||||
|
|
||||||
let previous_point = self.webview_relative_mouse_point.get();
|
|
||||||
if webview.rect().contains(point) {
|
|
||||||
webview.notify_input_event(InputEvent::MouseMove(MouseMoveEvent::new(point)));
|
|
||||||
} else if webview.rect().contains(previous_point) {
|
|
||||||
webview.notify_input_event(InputEvent::MouseLeftViewport(
|
|
||||||
MouseLeftViewportEvent::default(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.webview_relative_mouse_point.set(point);
|
|
||||||
},
|
},
|
||||||
WindowEvent::CursorLeft { .. } => {
|
WindowEvent::CursorLeft { .. } => {
|
||||||
if webview
|
if webview
|
||||||
|
@ -967,3 +1008,57 @@ impl XRWindowPose {
|
||||||
self.xr_rotation.set(rotation);
|
self.xr_rotation.set(rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct TouchEventSimulator {
|
||||||
|
pub left_mouse_button_down: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TouchEventSimulator {
|
||||||
|
fn maybe_consume_move_button_event(
|
||||||
|
&self,
|
||||||
|
webview: &WebView,
|
||||||
|
button: MouseButton,
|
||||||
|
action: ElementState,
|
||||||
|
point: Point2D<f32, DevicePixel>,
|
||||||
|
) -> bool {
|
||||||
|
if button != MouseButton::Left {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == ElementState::Pressed && !self.left_mouse_button_down.get() {
|
||||||
|
webview.notify_input_event(InputEvent::Touch(TouchEvent::new(
|
||||||
|
TouchEventType::Down,
|
||||||
|
TouchId(0),
|
||||||
|
point,
|
||||||
|
)));
|
||||||
|
self.left_mouse_button_down.set(true);
|
||||||
|
} else if action == ElementState::Released {
|
||||||
|
webview.notify_input_event(InputEvent::Touch(TouchEvent::new(
|
||||||
|
TouchEventType::Up,
|
||||||
|
TouchId(0),
|
||||||
|
point,
|
||||||
|
)));
|
||||||
|
self.left_mouse_button_down.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_consume_mouse_move_event(
|
||||||
|
&self,
|
||||||
|
webview: &WebView,
|
||||||
|
point: Point2D<f32, DevicePixel>,
|
||||||
|
) -> bool {
|
||||||
|
if !self.left_mouse_button_down.get() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
webview.notify_input_event(InputEvent::Touch(TouchEvent::new(
|
||||||
|
TouchEventType::Move,
|
||||||
|
TouchId(0),
|
||||||
|
point,
|
||||||
|
)));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ pub(crate) struct ServoShellPreferences {
|
||||||
/// An override for the screen resolution. This is useful for testing behavior on different screen sizes,
|
/// An override for the screen resolution. This is useful for testing behavior on different screen sizes,
|
||||||
/// such as the screen of a mobile device.
|
/// such as the screen of a mobile device.
|
||||||
pub screen_size_override: Option<Size2D<u32, DeviceIndependentPixel>>,
|
pub screen_size_override: Option<Size2D<u32, DeviceIndependentPixel>>,
|
||||||
|
/// Whether or not to simulate touch events using mouse events.
|
||||||
|
pub simulate_touch_events: bool,
|
||||||
/// If not-None, the path to a file to output the default WebView's rendered output
|
/// If not-None, the path to a file to output the default WebView's rendered output
|
||||||
/// after waiting for a stable image, this implies `Self::exit_after_load`.
|
/// after waiting for a stable image, this implies `Self::exit_after_load`.
|
||||||
pub output_image_path: Option<String>,
|
pub output_image_path: Option<String>,
|
||||||
|
@ -82,15 +84,12 @@ pub(crate) struct ServoShellPreferences {
|
||||||
/// `None` to disable WebDriver or `Some` with a port number to start a server to listen to
|
/// `None` to disable WebDriver or `Some` with a port number to start a server to listen to
|
||||||
/// remote WebDriver commands.
|
/// remote WebDriver commands.
|
||||||
pub webdriver_port: Option<u16>,
|
pub webdriver_port: Option<u16>,
|
||||||
|
|
||||||
/// Whether the CLI option to enable experimental prefs was present at startup.
|
/// Whether the CLI option to enable experimental prefs was present at startup.
|
||||||
pub experimental_prefs_enabled: bool,
|
pub experimental_prefs_enabled: bool,
|
||||||
|
|
||||||
/// Log filter given in the `log_filter` spec as a String, if any.
|
/// Log filter given in the `log_filter` spec as a String, if any.
|
||||||
/// If a filter is passed, the logger should adjust accordingly.
|
/// If a filter is passed, the logger should adjust accordingly.
|
||||||
#[cfg(target_env = "ohos")]
|
#[cfg(target_env = "ohos")]
|
||||||
pub log_filter: Option<String>,
|
pub log_filter: Option<String>,
|
||||||
|
|
||||||
/// Log also to a file
|
/// Log also to a file
|
||||||
#[cfg(target_env = "ohos")]
|
#[cfg(target_env = "ohos")]
|
||||||
pub log_to_file: bool,
|
pub log_to_file: bool,
|
||||||
|
@ -106,6 +105,7 @@ impl Default for ServoShellPreferences {
|
||||||
initial_window_size: Size2D::new(1024, 740),
|
initial_window_size: Size2D::new(1024, 740),
|
||||||
no_native_titlebar: true,
|
no_native_titlebar: true,
|
||||||
screen_size_override: None,
|
screen_size_override: None,
|
||||||
|
simulate_touch_events: false,
|
||||||
searchpage: "https://duckduckgo.com/html/?q=%s".into(),
|
searchpage: "https://duckduckgo.com/html/?q=%s".into(),
|
||||||
tracing_filter: None,
|
tracing_filter: None,
|
||||||
url: None,
|
url: None,
|
||||||
|
@ -505,6 +505,11 @@ struct CmdArgs {
|
||||||
parse(parse_resolution_string), fallback(None))]
|
parse(parse_resolution_string), fallback(None))]
|
||||||
screen_size_override: Option<Size2D<u32, DeviceIndependentPixel>>,
|
screen_size_override: Option<Size2D<u32, DeviceIndependentPixel>>,
|
||||||
|
|
||||||
|
/// Use mouse events to simulate touch events. Left button presses will be converted to touch
|
||||||
|
/// and mouse movements while the left button is pressed will be converted to touch movements.
|
||||||
|
#[bpaf(long("simulate-touch-events"))]
|
||||||
|
simulate_touch_events: bool,
|
||||||
|
|
||||||
/// Define a custom filter for traces. Overrides `SERVO_TRACING` if set.
|
/// Define a custom filter for traces. Overrides `SERVO_TRACING` if set.
|
||||||
#[bpaf(long("tracing-filter"), argument("FILTER"))]
|
#[bpaf(long("tracing-filter"), argument("FILTER"))]
|
||||||
tracing_filter: Option<String>,
|
tracing_filter: Option<String>,
|
||||||
|
@ -663,6 +668,7 @@ pub(crate) fn parse_command_line_arguments(args: Vec<String>) -> ArgumentParsing
|
||||||
tracing_filter: cmd_args.tracing_filter,
|
tracing_filter: cmd_args.tracing_filter,
|
||||||
initial_window_size: cmd_args.window_size.unwrap_or(default_window_size),
|
initial_window_size: cmd_args.window_size.unwrap_or(default_window_size),
|
||||||
screen_size_override: cmd_args.screen_size_override,
|
screen_size_override: cmd_args.screen_size_override,
|
||||||
|
simulate_touch_events: cmd_args.simulate_touch_events,
|
||||||
webdriver_port: cmd_args.webdriver_port,
|
webdriver_port: cmd_args.webdriver_port,
|
||||||
output_image_path: cmd_args.output.map(|p| p.to_string_lossy().into_owned()),
|
output_image_path: cmd_args.output.map(|p| p.to_string_lossy().into_owned()),
|
||||||
exit_after_stable_image: cmd_args.exit,
|
exit_after_stable_image: cmd_args.exit,
|
||||||
|
@ -728,10 +734,6 @@ fn print_debug_options_usage(app: &str) {
|
||||||
"Usage: {} debug option,[options,...]\n\twhere options include\n\nOptions:",
|
"Usage: {} debug option,[options,...]\n\twhere options include\n\nOptions:",
|
||||||
app
|
app
|
||||||
);
|
);
|
||||||
print_option(
|
|
||||||
"convert-mouse-to-touch",
|
|
||||||
"Send touch events instead of mouse events",
|
|
||||||
);
|
|
||||||
print_option(
|
print_option(
|
||||||
"disable-share-style-cache",
|
"disable-share-style-cache",
|
||||||
"Disable the style sharing cache.",
|
"Disable the style sharing cache.",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue