From aac6aa6c70b929352374370681549923df975112 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 3 Sep 2025 22:53:12 -0400 Subject: [PATCH] servoshell: Add button to toggle experimental web platform features. (#39125) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it easier to experiment with the impact of experimental features when browsing around in servoshell. The toggle is global and causes all webviews to reload with the new preference values. Testing: Manually tested; no UI testing for servoshell. Not enabled: Screenshot 2025-09-03 at 9 34 30 PM Enabled: Screenshot 2025-09-03 at 9 34 36 PM Signed-off-by: Josh Matthews --- components/servo/lib.rs | 7 +++++++ ports/servoshell/desktop/app.rs | 7 +++++++ ports/servoshell/desktop/minibrowser.rs | 24 +++++++++++++++++++++++- ports/servoshell/prefs.rs | 9 ++++++++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 653caba39f7..aaa59bf2d8e 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -98,6 +98,7 @@ use profile_traits::mem::MemoryReportResult; use profile_traits::{mem, time}; use script::{JSEngineSetup, ServiceWorkerManager}; use servo_config::opts::Opts; +pub use servo_config::prefs::PrefValue; use servo_config::prefs::Preferences; use servo_config::{opts, pref, prefs}; use servo_delegate::DefaultServoDelegate; @@ -1083,6 +1084,12 @@ impl Servo { .send(EmbedderToConstellationMessage::WebDriverCommand(command)); } } + + pub fn set_preference(&self, name: &str, value: PrefValue) { + let mut preferences = prefs::get().clone(); + preferences.set_value(name, value); + prefs::set(preferences); + } } fn create_embedder_channel( diff --git a/ports/servoshell/desktop/app.rs b/ports/servoshell/desktop/app.rs index 06621f69143..c449e993978 100644 --- a/ports/servoshell/desktop/app.rs +++ b/ports/servoshell/desktop/app.rs @@ -119,6 +119,7 @@ impl App { event_loop, proxy, self.initial_url.clone(), + &self.servoshell_preferences, )); Rc::new(window) }, @@ -321,6 +322,12 @@ impl App { focused_webview.reload(); } }, + MinibrowserEvent::ReloadAll => { + minibrowser.update_location_dirty(false); + for (_, webview) in state.webviews() { + webview.reload(); + } + }, MinibrowserEvent::NewWebView => { minibrowser.update_location_dirty(false); state.create_and_focus_toplevel_webview(Url::parse("servo:newtab").unwrap()); diff --git a/ports/servoshell/desktop/minibrowser.rs b/ports/servoshell/desktop/minibrowser.rs index 4f62b9e6e7e..1b737f09141 100644 --- a/ports/servoshell/desktop/minibrowser.rs +++ b/ports/servoshell/desktop/minibrowser.rs @@ -22,7 +22,9 @@ use servo::base::id::WebViewId; use servo::servo_geometry::DeviceIndependentPixel; use servo::servo_url::ServoUrl; use servo::webrender_api::units::DevicePixel; -use servo::{Image, LoadStatus, OffscreenRenderingContext, PixelFormat, RenderingContext, WebView}; +use servo::{ + Image, LoadStatus, OffscreenRenderingContext, PixelFormat, PrefValue, RenderingContext, WebView, +}; use winit::event::{ElementState, MouseButton, WindowEvent}; use winit::event_loop::ActiveEventLoop; use winit::window::Window; @@ -33,6 +35,7 @@ use super::events_loop::EventLoopProxy; use super::geometry::winit_position_to_euclid_point; use super::headed_window::Window as ServoWindow; use crate::desktop::window_trait::WindowPortsMethods; +use crate::prefs::{EXPERIMENTAL_PREFS, ServoShellPreferences}; pub struct Minibrowser { rendering_context: Rc, @@ -55,6 +58,9 @@ pub struct Minibrowser { /// /// These need to be cached across egui draw calls. favicon_textures: HashMap, + + /// Whether the user has enabled experimental preferences. + experimental_prefs_enabled: bool, } pub enum MinibrowserEvent { @@ -63,6 +69,7 @@ pub enum MinibrowserEvent { Back, Forward, Reload, + ReloadAll, NewWebView, CloseWebView(WebViewId), } @@ -88,6 +95,7 @@ impl Minibrowser { event_loop: &ActiveEventLoop, event_loop_proxy: EventLoopProxy, initial_url: ServoUrl, + preferences: &ServoShellPreferences, ) -> Self { let rendering_context = window.offscreen_rendering_context(); // Adapted from https://github.com/emilk/egui/blob/9478e50d012c5138551c38cbee16b07bc1fcf283/crates/egui_glow/examples/pure_glow.rs @@ -118,6 +126,7 @@ impl Minibrowser { load_status: LoadStatus::Complete, status_text: None, favicon_textures: Default::default(), + experimental_prefs_enabled: preferences.experimental_prefs_enabled, } } @@ -336,6 +345,19 @@ impl Minibrowser { ui.available_size(), egui::Layout::right_to_left(egui::Align::Center), |ui| { + let prefs_toggle = ui + .toggle_value(&mut self.experimental_prefs_enabled, "☢") + .on_hover_text("Enable experimental prefs"); + if prefs_toggle.clicked() { + let enable = self.experimental_prefs_enabled; + for pref in EXPERIMENTAL_PREFS { + state + .servo() + .set_preference(pref, PrefValue::Bool(enable)); + } + event_queue.borrow_mut().push(MinibrowserEvent::ReloadAll); + } + let location_id = egui::Id::new("location_input"); let location_field = ui.add_sized( ui.available_size(), diff --git a/ports/servoshell/prefs.rs b/ports/servoshell/prefs.rs index 4311562074c..bc3c2a84eae 100644 --- a/ports/servoshell/prefs.rs +++ b/ports/servoshell/prefs.rs @@ -88,6 +88,9 @@ pub(crate) struct ServoShellPreferences { /// Log also to a file #[cfg(target_env = "ohos")] pub log_to_file: bool, + + /// Whether the CLI option to enable experimental prefs was present at startup. + pub experimental_prefs_enabled: bool, } impl Default for ServoShellPreferences { @@ -111,6 +114,7 @@ impl Default for ServoShellPreferences { log_filter: None, #[cfg(target_env = "ohos")] log_to_file: false, + experimental_prefs_enabled: false, } } } @@ -605,7 +609,9 @@ pub(crate) fn parse_command_line_arguments(args: Vec) -> ArgumentParsing }) .collect(); - if opt_match.opt_present("enable-experimental-web-platform-features") { + let experimental_prefs_enabled = + opt_match.opt_present("enable-experimental-web-platform-features"); + if experimental_prefs_enabled { for pref in EXPERIMENTAL_PREFS { preferences.set_value(pref, PrefValue::Bool(true)); } @@ -677,6 +683,7 @@ pub(crate) fn parse_command_line_arguments(args: Vec) -> ArgumentParsing log_filter, #[cfg(target_env = "ohos")] log_to_file, + experimental_prefs_enabled, ..Default::default() };