EmbedderMsg: port reply channels to GenericChannel (#39018)

This change ports all `EmbedderMsg` reply channels that don't use the
`ROUTER` to GenericChannel.
The remaining reply channels that use the router are blocked until
#38973 is merged.
This is a breaking change in the API between libservo and embedders.

Future work: A lot of the reply channels in this PR look like they
conceptually should be oneshot ipc channels. It might make sense to
provide a `OneshotGenericChannel` abstraction that encodes this.

Testing: No functional changes - covered by existing tests. None of the
channels changed here uses the Router
Part of #38912

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
Jonathan Schwender 2025-08-29 14:44:21 +02:00 committed by GitHub
parent 89e1357c75
commit 66d9f957e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 107 additions and 95 deletions

View file

@ -19,6 +19,7 @@ use std::string::String;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use base::generic_channel;
use base::id::WebViewId; use base::id::WebViewId;
use bitflags::bitflags; use bitflags::bitflags;
use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted};
@ -409,7 +410,8 @@ impl BluetoothManager {
]); ]);
} }
let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (ipc_sender, ipc_receiver) =
generic_channel::channel().expect("Failed to create IPC channel!");
self.embedder_proxy self.embedder_proxy
.send(EmbedderMsg::GetSelectedBluetoothDevice( .send(EmbedderMsg::GetSelectedBluetoothDevice(
webview_id, webview_id,

View file

@ -3347,13 +3347,10 @@ where
response_sender, response_sender,
} = load_info; } = load_info;
let (webview_id_sender, webview_id_receiver) = match ipc::channel() { let Some((webview_id_sender, webview_id_receiver)) = generic_channel::channel() else {
Ok(result) => result, warn!("Failed to create channel");
Err(error) => {
warn!("Failed to create channel: {error:?}");
let _ = response_sender.send(None); let _ = response_sender.send(None);
return; return;
},
}; };
self.embedder_proxy.send(EmbedderMsg::AllowOpeningWebView( self.embedder_proxy.send(EmbedderMsg::AllowOpeningWebView(
opener_webview_id, opener_webview_id,

View file

@ -18,6 +18,7 @@ use std::net::{Shutdown, TcpListener, TcpStream};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use base::generic_channel;
use base::id::{BrowsingContextId, PipelineId, WebViewId}; use base::id::{BrowsingContextId, PipelineId, WebViewId};
use crossbeam_channel::{Receiver, Sender, unbounded}; use crossbeam_channel::{Receiver, Sender, unbounded};
use devtools_traits::{ use devtools_traits::{
@ -26,7 +27,7 @@ use devtools_traits::{
ScriptToDevtoolsControlMsg, SourceInfo, WorkerId, ScriptToDevtoolsControlMsg, SourceInfo, WorkerId,
}; };
use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy}; use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy};
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::IpcSender;
use log::{trace, warn}; use log::{trace, warn};
use resource::{ResourceArrayType, ResourceAvailable}; use resource::{ResourceArrayType, ResourceAvailable};
use serde::Serialize; use serde::Serialize;
@ -651,7 +652,8 @@ fn allow_devtools_client(stream: &mut TcpStream, embedder: &EmbedderProxy, token
}; };
// No token found. Prompt user // No token found. Prompt user
let (request_sender, request_receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (request_sender, request_receiver) =
generic_channel::channel().expect("Failed to create IPC channel!");
embedder.send(EmbedderMsg::RequestDevtoolsConnection(request_sender)); embedder.send(EmbedderMsg::RequestDevtoolsConnection(request_sender));
request_receiver.recv().unwrap() == AllowOrDeny::Allow request_receiver.recv().unwrap() == AllowOrDeny::Allow
} }

View file

@ -10,11 +10,12 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, RwLock, Weak}; use std::sync::{Arc, Mutex, RwLock, Weak};
use base::generic_channel;
use base::id::WebViewId; use base::id::WebViewId;
use embedder_traits::{EmbedderMsg, EmbedderProxy, FilterPattern}; use embedder_traits::{EmbedderMsg, EmbedderProxy, FilterPattern};
use headers::{ContentLength, ContentRange, ContentType, HeaderMap, HeaderMapExt, Range}; use headers::{ContentLength, ContentRange, ContentType, HeaderMap, HeaderMapExt, Range};
use http::header::{self, HeaderValue}; use http::header::{self, HeaderValue};
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::IpcSender;
use log::warn; use log::warn;
use mime::{self, Mime}; use mime::{self, Mime};
use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError};
@ -583,7 +584,8 @@ impl FileManagerStore {
multiple_files: bool, multiple_files: bool,
embedder_proxy: EmbedderProxy, embedder_proxy: EmbedderProxy,
) -> Option<Vec<PathBuf>> { ) -> Option<Vec<PathBuf>> {
let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (ipc_sender, ipc_receiver) =
generic_channel::channel().expect("Failed to create IPC channel!");
embedder_proxy.send(EmbedderMsg::SelectFiles( embedder_proxy.send(EmbedderMsg::SelectFiles(
webview_id, webview_id,
patterns, patterns,

View file

@ -9,6 +9,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
use async_recursion::async_recursion; use async_recursion::async_recursion;
use base::cross_process_instant::CrossProcessInstant; use base::cross_process_instant::CrossProcessInstant;
use base::generic_channel;
use base::id::{BrowsingContextId, HistoryStateId, PipelineId}; use base::id::{BrowsingContextId, HistoryStateId, PipelineId};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use devtools_traits::{ use devtools_traits::{
@ -138,7 +139,7 @@ impl HttpState {
} }
let embedder_proxy = self.embedder_proxy.lock().unwrap(); let embedder_proxy = self.embedder_proxy.lock().unwrap();
let (ipc_sender, ipc_receiver) = ipc::channel().unwrap(); let (ipc_sender, ipc_receiver) = generic_channel::channel().unwrap();
embedder_proxy.send(EmbedderMsg::RequestAuthentication( embedder_proxy.send(EmbedderMsg::RequestAuthentication(
webview_id, webview_id,
request.url(), request.url(),

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base::generic_channel;
use content_security_policy::Destination; use content_security_policy::Destination;
use embedder_traits::{EmbedderMsg, EmbedderProxy, WebResourceRequest, WebResourceResponseMsg}; use embedder_traits::{EmbedderMsg, EmbedderProxy, WebResourceRequest, WebResourceResponseMsg};
use ipc_channel::ipc;
use log::error; use log::error;
use net_traits::NetworkError; use net_traits::NetworkError;
use net_traits::http_status::HttpStatus; use net_traits::http_status::HttpStatus;
@ -29,7 +29,7 @@ impl RequestInterceptor {
response: &mut Option<Response>, response: &mut Option<Response>,
context: &FetchContext, context: &FetchContext,
) { ) {
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = generic_channel::channel().unwrap();
let is_for_main_frame = matches!(request.destination, Destination::Document); let is_for_main_frame = matches!(request.destination, Destination::Document);
let web_resource_request = WebResourceRequest { let web_resource_request = WebResourceRequest {
method: request.method.clone(), method: request.method.clone(),

View file

@ -12,9 +12,9 @@ use std::str::FromStr;
use std::sync::{LazyLock, Mutex}; use std::sync::{LazyLock, Mutex};
use std::time::Duration; use std::time::Duration;
use base::Epoch;
use base::cross_process_instant::CrossProcessInstant; use base::cross_process_instant::CrossProcessInstant;
use base::id::WebViewId; use base::id::WebViewId;
use base::{Epoch, generic_channel};
use canvas_traits::canvas::CanvasId; use canvas_traits::canvas::CanvasId;
use canvas_traits::webgl::{WebGLContextId, WebGLMsg}; use canvas_traits::webgl::{WebGLContextId, WebGLMsg};
use chrono::Local; use chrono::Local;
@ -32,7 +32,6 @@ use euclid::default::{Rect, Size2D};
use fnv::FnvHashMap; use fnv::FnvHashMap;
use html5ever::{LocalName, Namespace, QualName, local_name, ns}; use html5ever::{LocalName, Namespace, QualName, local_name, ns};
use hyper_serde::Serde; use hyper_serde::Serde;
use ipc_channel::ipc;
use js::rust::{HandleObject, HandleValue, MutableHandleValue}; use js::rust::{HandleObject, HandleValue, MutableHandleValue};
use layout_api::{PendingRestyle, ReflowGoal, ReflowPhasesRun, RestyleReason, TrustedNodeAddress}; use layout_api::{PendingRestyle, ReflowGoal, ReflowPhasesRun, RestyleReason, TrustedNodeAddress};
use metrics::{InteractiveFlag, InteractiveWindow, ProgressiveWebMetrics}; use metrics::{InteractiveFlag, InteractiveWindow, ProgressiveWebMetrics};
@ -1929,7 +1928,7 @@ impl Document {
.ReturnValue() .ReturnValue()
.is_empty(); .is_empty();
if default_prevented || return_value_not_empty { if default_prevented || return_value_not_empty {
let (chan, port) = ipc::channel().expect("Failed to create IPC channel!"); let (chan, port) = generic_channel::channel().expect("Failed to create IPC channel!");
let msg = EmbedderMsg::AllowUnload(self.webview_id(), chan); let msg = EmbedderMsg::AllowUnload(self.webview_id(), chan);
self.send_to_embedder(msg); self.send_to_embedder(msg);
can_unload = port.recv().unwrap() == AllowOrDeny::Allow; can_unload = port.recv().unwrap() == AllowOrDeny::Allow;

View file

@ -9,6 +9,7 @@ use std::mem;
use std::rc::Rc; use std::rc::Rc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use base::generic_channel;
use constellation_traits::ScriptToConstellationMessage; use constellation_traits::ScriptToConstellationMessage;
use embedder_traits::{ use embedder_traits::{
Cursor, EditingActionEvent, EmbedderMsg, GamepadEvent as EmbedderGamepadEvent, Cursor, EditingActionEvent, EmbedderMsg, GamepadEvent as EmbedderGamepadEvent,
@ -689,7 +690,8 @@ impl DocumentEventHandler {
// Step 4. If result is true, then show the UA context menu // Step 4. If result is true, then show the UA context menu
if result { if result {
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel."); let (sender, receiver) =
generic_channel::channel().expect("Failed to create IPC channel.");
self.window.send_to_embedder(EmbedderMsg::ShowContextMenu( self.window.send_to_embedder(EmbedderMsg::ShowContextMenu(
self.window.webview_id(), self.window.webview_id(),
sender, sender,

View file

@ -11,6 +11,7 @@ use std::ptr::NonNull;
use std::str::FromStr; use std::str::FromStr;
use std::{f64, ptr}; use std::{f64, ptr};
use base::generic_channel;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use embedder_traits::{ use embedder_traits::{
EmbedderMsg, FilterPattern, FormControl as EmbedderFormControl, InputMethodType, RgbColor, EmbedderMsg, FilterPattern, FormControl as EmbedderFormControl, InputMethodType, RgbColor,
@ -18,7 +19,6 @@ use embedder_traits::{
use encoding_rs::Encoding; use encoding_rs::Encoding;
use euclid::{Point2D, Rect, Size2D}; use euclid::{Point2D, Rect, Size2D};
use html5ever::{LocalName, Prefix, local_name, ns}; use html5ever::{LocalName, Prefix, local_name, ns};
use ipc_channel::ipc;
use js::jsapi::{ use js::jsapi::{
ClippedTime, DateGetMsecSinceEpoch, Handle, JS_ClearPendingException, JSObject, NewDateObject, ClippedTime, DateGetMsecSinceEpoch, Handle, JS_ClearPendingException, JSObject, NewDateObject,
NewUCRegExpObject, ObjectIsDate, RegExpFlag_UnicodeSets, RegExpFlags, NewUCRegExpObject, ObjectIsDate, RegExpFlag_UnicodeSets, RegExpFlags,
@ -2786,8 +2786,8 @@ impl HTMLInputElement {
// Step 6. Otherwise, the user agent should show the relevant user interface for selecting a value for element, // Step 6. Otherwise, the user agent should show the relevant user interface for selecting a value for element,
// in the way it normally would when the user interacts with the control. // in the way it normally would when the user interacts with the control.
if self.input_type() == InputType::Color { if self.input_type() == InputType::Color {
let (ipc_sender, ipc_receiver) = let (ipc_sender, ipc_receiver) = generic_channel::channel::<Option<RgbColor>>()
ipc::channel::<Option<RgbColor>>().expect("Failed to create IPC channel!"); .expect("Failed to create IPC channel!");
let document = self.owner_document(); let document = self.owner_document();
let rect = self.upcast::<Node>().border_box().unwrap_or_default(); let rect = self.upcast::<Node>().border_box().unwrap_or_default();
let rect = Rect::new( let rect = Rect::new(

View file

@ -10,12 +10,11 @@ use embedder_traits::{EmbedderMsg, FormControl as EmbedderFormControl};
use embedder_traits::{SelectElementOption, SelectElementOptionOrOptgroup}; use embedder_traits::{SelectElementOption, SelectElementOptionOrOptgroup};
use euclid::{Point2D, Rect, Size2D}; use euclid::{Point2D, Rect, Size2D};
use html5ever::{LocalName, Prefix, local_name}; use html5ever::{LocalName, Prefix, local_name};
use ipc_channel::ipc;
use js::rust::HandleObject; use js::rust::HandleObject;
use style::attr::AttrValue; use style::attr::AttrValue;
use stylo_dom::ElementState; use stylo_dom::ElementState;
use webrender_api::units::DeviceIntRect; use webrender_api::units::DeviceIntRect;
use base::generic_channel;
use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::refcounted::Trusted;
use crate::dom::event::{EventBubbles, EventCancelable, EventComposed}; use crate::dom::event::{EventBubbles, EventCancelable, EventComposed};
use crate::dom::bindings::codegen::GenericBindings::HTMLOptGroupElementBinding::HTMLOptGroupElement_Binding::HTMLOptGroupElementMethods; use crate::dom::bindings::codegen::GenericBindings::HTMLOptGroupElementBinding::HTMLOptGroupElement_Binding::HTMLOptGroupElementMethods;
@ -340,7 +339,8 @@ impl HTMLSelectElement {
} }
pub(crate) fn show_menu(&self) -> Option<usize> { pub(crate) fn show_menu(&self) -> Option<usize> {
let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (ipc_sender, ipc_receiver) =
generic_channel::channel().expect("Failed to create IPC channel!");
// Collect list of optgroups and options // Collect list of optgroups and options
let mut index = 0; let mut index = 0;

View file

@ -4,9 +4,9 @@
use std::rc::Rc; use std::rc::Rc;
use base::generic_channel;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use embedder_traits::{self, AllowOrDeny, EmbedderMsg, PermissionFeature}; use embedder_traits::{self, AllowOrDeny, EmbedderMsg, PermissionFeature};
use ipc_channel::ipc;
use js::conversions::ConversionResult; use js::conversions::ConversionResult;
use js::jsapi::JSObject; use js::jsapi::JSObject;
use js::jsval::{ObjectValue, UndefinedValue}; use js::jsval::{ObjectValue, UndefinedValue};
@ -350,7 +350,7 @@ fn prompt_user_from_embedder(name: PermissionName, global_scope: &GlobalScope) -
warn!("Requesting permissions from non-webview-associated global scope"); warn!("Requesting permissions from non-webview-associated global scope");
return PermissionState::Denied; return PermissionState::Denied;
}; };
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel!");
global_scope.send_to_embedder(EmbedderMsg::PromptPermission( global_scope.send_to_embedder(EmbedderMsg::PromptPermission(
webview_id, webview_id,
name.convert(), name.convert(),

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base::generic_channel;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use embedder_traits::{EmbedderMsg, ScreenMetrics}; use embedder_traits::{EmbedderMsg, ScreenMetrics};
use ipc_channel::ipc;
use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods; use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods;
use crate::dom::bindings::num::Finite; use crate::dom::bindings::num::Finite;
@ -33,7 +33,7 @@ impl Screen {
/// Retrives [`ScreenMetrics`] from the embedder. /// Retrives [`ScreenMetrics`] from the embedder.
fn screen_metrics(&self) -> ScreenMetrics { fn screen_metrics(&self) -> ScreenMetrics {
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel!");
self.window.send_to_embedder(EmbedderMsg::GetScreenMetrics( self.window.send_to_embedder(EmbedderMsg::GetScreenMetrics(
self.window.webview_id(), self.window.webview_id(),

View file

@ -17,6 +17,7 @@ use std::time::{Duration, Instant};
use app_units::Au; use app_units::Au;
use backtrace::Backtrace; use backtrace::Backtrace;
use base::cross_process_instant::CrossProcessInstant; use base::cross_process_instant::CrossProcessInstant;
use base::generic_channel;
use base::generic_channel::GenericSender; use base::generic_channel::GenericSender;
use base::id::{BrowsingContextId, PipelineId, WebViewId}; use base::id::{BrowsingContextId, PipelineId, WebViewId};
use base64::Engine; use base64::Engine;
@ -67,7 +68,7 @@ use net_traits::image_cache::{
}; };
use net_traits::storage_thread::StorageType; use net_traits::storage_thread::StorageType;
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use profile_traits::ipc as ProfiledIpc; use profile_traits::generic_channel as ProfiledGenericChannel;
use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::mem::ProfilerChan as MemProfilerChan;
use profile_traits::time::ProfilerChan as TimeProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan;
use script_bindings::conversions::SafeToJSValConvertible; use script_bindings::conversions::SafeToJSValConvertible;
@ -862,7 +863,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
stderr.flush().unwrap(); stderr.flush().unwrap();
} }
let (sender, receiver) = let (sender, receiver) =
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); ProfiledGenericChannel::channel(self.global().time_profiler_chan().clone()).unwrap();
let dialog = SimpleDialog::Alert { let dialog = SimpleDialog::Alert {
message: s.to_string(), message: s.to_string(),
response_sender: sender, response_sender: sender,
@ -879,7 +880,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://html.spec.whatwg.org/multipage/#dom-confirm // https://html.spec.whatwg.org/multipage/#dom-confirm
fn Confirm(&self, s: DOMString) -> bool { fn Confirm(&self, s: DOMString) -> bool {
let (sender, receiver) = let (sender, receiver) =
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); ProfiledGenericChannel::channel(self.global().time_profiler_chan().clone()).unwrap();
let dialog = SimpleDialog::Confirm { let dialog = SimpleDialog::Confirm {
message: s.to_string(), message: s.to_string(),
response_sender: sender, response_sender: sender,
@ -899,7 +900,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://html.spec.whatwg.org/multipage/#dom-prompt // https://html.spec.whatwg.org/multipage/#dom-prompt
fn Prompt(&self, message: DOMString, default: DOMString) -> Option<DOMString> { fn Prompt(&self, message: DOMString, default: DOMString) -> Option<DOMString> {
let (sender, receiver) = let (sender, receiver) =
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); ProfiledGenericChannel::channel(self.global().time_profiler_chan().clone()).unwrap();
let dialog = SimpleDialog::Prompt { let dialog = SimpleDialog::Prompt {
message: message.to_string(), message: message.to_string(),
default: default.to_string(), default: default.to_string(),
@ -2137,7 +2138,7 @@ impl Window {
} }
fn client_window(&self) -> DeviceIndependentIntRect { fn client_window(&self) -> DeviceIndependentIntRect {
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel!");
self.send_to_embedder(EmbedderMsg::GetWindowRect(self.webview_id(), sender)); self.send_to_embedder(EmbedderMsg::GetWindowRect(self.webview_id(), sender));

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base::generic_channel;
use crossbeam_channel::{Receiver, Sender, TryRecvError, unbounded}; use crossbeam_channel::{Receiver, Sender, TryRecvError, unbounded};
use log::warn; use log::warn;
@ -15,7 +16,7 @@ pub(crate) struct ServoErrorSender {
} }
impl ServoErrorSender { impl ServoErrorSender {
pub(crate) fn raise_response_send_error(&self, error: bincode::Error) { pub(crate) fn raise_response_send_error(&self, error: generic_channel::SendError) {
if let Err(error) = self.sender.send(ServoError::ResponseFailedToSend(error)) { if let Err(error) = self.sender.send(ServoError::ResponseFailedToSend(error)) {
warn!("Failed to send Servo error: {error:?}"); warn!("Failed to send Servo error: {error:?}");
} }

View file

@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base::generic_channel;
use embedder_traits::Notification; use embedder_traits::Notification;
use crate::Servo; use crate::Servo;
@ -16,7 +16,7 @@ pub enum ServoError {
/// to start. /// to start.
DevtoolsFailedToStart, DevtoolsFailedToStart,
/// Failed to send response to delegate request. /// Failed to send response to delegate request.
ResponseFailedToSend(bincode::Error), ResponseFailedToSend(generic_channel::SendError),
} }
pub trait ServoDelegate { pub trait ServoDelegate {

View file

@ -4,6 +4,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use base::generic_channel::{GenericSender, SendResult};
use base::id::PipelineId; use base::id::PipelineId;
use constellation_traits::EmbedderToConstellationMessage; use constellation_traits::EmbedderToConstellationMessage;
use embedder_traits::{ use embedder_traits::{
@ -63,14 +64,14 @@ impl Drop for NavigationRequest {
/// Sends a response over an IPC channel, or a default response on [`Drop`] if no response was sent. /// Sends a response over an IPC channel, or a default response on [`Drop`] if no response was sent.
pub(crate) struct IpcResponder<T: Serialize> { pub(crate) struct IpcResponder<T: Serialize> {
response_sender: IpcSender<T>, response_sender: GenericSender<T>,
response_sent: bool, response_sent: bool,
/// Always present, except when taken by [`Drop`]. /// Always present, except when taken by [`Drop`].
default_response: Option<T>, default_response: Option<T>,
} }
impl<T: Serialize> IpcResponder<T> { impl<T: Serialize> IpcResponder<T> {
pub(crate) fn new(response_sender: IpcSender<T>, default_response: T) -> Self { pub(crate) fn new(response_sender: GenericSender<T>, default_response: T) -> Self {
Self { Self {
response_sender, response_sender,
response_sent: false, response_sent: false,
@ -78,13 +79,13 @@ impl<T: Serialize> IpcResponder<T> {
} }
} }
pub(crate) fn send(&mut self, response: T) -> bincode::Result<()> { pub(crate) fn send(&mut self, response: T) -> SendResult {
let result = self.response_sender.send(response); let result = self.response_sender.send(response);
self.response_sent = true; self.response_sent = true;
result result
} }
pub(crate) fn into_inner(self) -> IpcSender<T> { pub(crate) fn into_inner(self) -> GenericSender<T> {
self.response_sender.clone() self.response_sender.clone()
} }
} }
@ -129,7 +130,7 @@ pub struct AllowOrDenyRequest(IpcResponder<AllowOrDeny>, ServoErrorSender);
impl AllowOrDenyRequest { impl AllowOrDenyRequest {
pub(crate) fn new( pub(crate) fn new(
response_sender: IpcSender<AllowOrDeny>, response_sender: GenericSender<AllowOrDeny>,
default_response: AllowOrDeny, default_response: AllowOrDeny,
error_sender: ServoErrorSender, error_sender: ServoErrorSender,
) -> Self { ) -> Self {
@ -166,7 +167,7 @@ impl AuthenticationRequest {
pub(crate) fn new( pub(crate) fn new(
url: Url, url: Url,
for_proxy: bool, for_proxy: bool,
response_sender: IpcSender<Option<AuthenticationResponse>>, response_sender: GenericSender<Option<AuthenticationResponse>>,
error_sender: ServoErrorSender, error_sender: ServoErrorSender,
) -> Self { ) -> Self {
Self { Self {
@ -208,7 +209,7 @@ pub struct WebResourceLoad {
impl WebResourceLoad { impl WebResourceLoad {
pub(crate) fn new( pub(crate) fn new(
web_resource_request: WebResourceRequest, web_resource_request: WebResourceRequest,
response_sender: IpcSender<WebResourceResponseMsg>, response_sender: GenericSender<WebResourceResponseMsg>,
error_sender: ServoErrorSender, error_sender: ServoErrorSender,
) -> Self { ) -> Self {
Self { Self {
@ -244,7 +245,7 @@ impl WebResourceLoad {
/// this interception will automatically be finished when dropped. /// this interception will automatically be finished when dropped.
pub struct InterceptedWebResourceLoad { pub struct InterceptedWebResourceLoad {
pub request: WebResourceRequest, pub request: WebResourceRequest,
pub(crate) response_sender: IpcSender<WebResourceResponseMsg>, pub(crate) response_sender: GenericSender<WebResourceResponseMsg>,
pub(crate) finished: bool, pub(crate) finished: bool,
pub(crate) error_sender: ServoErrorSender, pub(crate) error_sender: ServoErrorSender,
} }
@ -316,7 +317,7 @@ impl SelectElement {
options: Vec<SelectElementOptionOrOptgroup>, options: Vec<SelectElementOptionOrOptgroup>,
selected_option: Option<usize>, selected_option: Option<usize>,
position: DeviceIntRect, position: DeviceIntRect,
ipc_sender: IpcSender<Option<usize>>, ipc_sender: GenericSender<Option<usize>>,
) -> Self { ) -> Self {
Self { Self {
options, options,
@ -369,7 +370,7 @@ impl ColorPicker {
pub(crate) fn new( pub(crate) fn new(
current_color: RgbColor, current_color: RgbColor,
position: DeviceIntRect, position: DeviceIntRect,
ipc_sender: IpcSender<Option<RgbColor>>, ipc_sender: GenericSender<Option<RgbColor>>,
error_sender: ServoErrorSender, error_sender: ServoErrorSender,
) -> Self { ) -> Self {
Self { Self {
@ -516,7 +517,7 @@ pub trait WebViewDelegate {
fn show_context_menu( fn show_context_menu(
&self, &self,
_webview: WebView, _webview: WebView,
result_sender: IpcSender<ContextMenuResult>, result_sender: GenericSender<ContextMenuResult>,
_: Option<String>, _: Option<String>,
_: Vec<String>, _: Vec<String>,
) { ) {
@ -529,7 +530,7 @@ pub trait WebViewDelegate {
&self, &self,
_webview: WebView, _webview: WebView,
_: Vec<String>, _: Vec<String>,
response_sender: IpcSender<Option<String>>, response_sender: GenericSender<Option<String>>,
) { ) {
let _ = response_sender.send(None); let _ = response_sender.send(None);
} }
@ -540,7 +541,7 @@ pub trait WebViewDelegate {
_webview: WebView, _webview: WebView,
_filter_pattern: Vec<FilterPattern>, _filter_pattern: Vec<FilterPattern>,
_allow_select_mutiple: bool, _allow_select_mutiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>, response_sender: GenericSender<Option<Vec<PathBuf>>>,
) { ) {
let _ = response_sender.send(None); let _ = response_sender.send(None);
} }
@ -596,14 +597,14 @@ impl WebViewDelegate for DefaultWebViewDelegate {}
#[test] #[test]
fn test_allow_deny_request() { fn test_allow_deny_request() {
use ipc_channel::ipc; use base::generic_channel;
use crate::ServoErrorChannel; use crate::ServoErrorChannel;
for default_response in [AllowOrDeny::Allow, AllowOrDeny::Deny] { for default_response in [AllowOrDeny::Allow, AllowOrDeny::Deny] {
// Explicit allow yields allow and nothing else // Explicit allow yields allow and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AllowOrDenyRequest::new(sender, default_response, errors.sender()); let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
request.allow(); request.allow();
assert_eq!(receiver.try_recv().ok(), Some(AllowOrDeny::Allow)); assert_eq!(receiver.try_recv().ok(), Some(AllowOrDeny::Allow));
@ -612,7 +613,7 @@ fn test_allow_deny_request() {
// Explicit deny yields deny and nothing else // Explicit deny yields deny and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AllowOrDenyRequest::new(sender, default_response, errors.sender()); let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
request.deny(); request.deny();
assert_eq!(receiver.try_recv().ok(), Some(AllowOrDeny::Deny)); assert_eq!(receiver.try_recv().ok(), Some(AllowOrDeny::Deny));
@ -621,7 +622,7 @@ fn test_allow_deny_request() {
// No response yields default response and nothing else // No response yields default response and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AllowOrDenyRequest::new(sender, default_response, errors.sender()); let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
drop(request); drop(request);
assert_eq!(receiver.try_recv().ok(), Some(default_response)); assert_eq!(receiver.try_recv().ok(), Some(default_response));
@ -630,7 +631,7 @@ fn test_allow_deny_request() {
// Explicit allow when receiver disconnected yields error // Explicit allow when receiver disconnected yields error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AllowOrDenyRequest::new(sender, default_response, errors.sender()); let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
drop(receiver); drop(receiver);
request.allow(); request.allow();
@ -638,7 +639,7 @@ fn test_allow_deny_request() {
// Explicit deny when receiver disconnected yields error // Explicit deny when receiver disconnected yields error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AllowOrDenyRequest::new(sender, default_response, errors.sender()); let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
drop(receiver); drop(receiver);
request.deny(); request.deny();
@ -646,7 +647,7 @@ fn test_allow_deny_request() {
// No response when receiver disconnected yields no error // No response when receiver disconnected yields no error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AllowOrDenyRequest::new(sender, default_response, errors.sender()); let request = AllowOrDenyRequest::new(sender, default_response, errors.sender());
drop(receiver); drop(receiver);
drop(request); drop(request);
@ -656,7 +657,7 @@ fn test_allow_deny_request() {
#[test] #[test]
fn test_authentication_request() { fn test_authentication_request() {
use ipc_channel::ipc; use base::generic_channel;
use crate::ServoErrorChannel; use crate::ServoErrorChannel;
@ -664,7 +665,7 @@ fn test_authentication_request() {
// Explicit response yields that response and nothing else // Explicit response yields that response and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender()); let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
request.authenticate("diffie".to_owned(), "hunter2".to_owned()); request.authenticate("diffie".to_owned(), "hunter2".to_owned());
assert_eq!( assert_eq!(
@ -679,7 +680,7 @@ fn test_authentication_request() {
// No response yields None response and nothing else // No response yields None response and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender()); let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
drop(request); drop(request);
assert_eq!(receiver.try_recv().ok(), Some(None)); assert_eq!(receiver.try_recv().ok(), Some(None));
@ -688,7 +689,7 @@ fn test_authentication_request() {
// Explicit response when receiver disconnected yields error // Explicit response when receiver disconnected yields error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender()); let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
drop(receiver); drop(receiver);
request.authenticate("diffie".to_owned(), "hunter2".to_owned()); request.authenticate("diffie".to_owned(), "hunter2".to_owned());
@ -696,7 +697,7 @@ fn test_authentication_request() {
// No response when receiver disconnected yields no error // No response when receiver disconnected yields no error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender()); let request = AuthenticationRequest::new(url.clone(), false, sender, errors.sender());
drop(receiver); drop(receiver);
drop(request); drop(request);
@ -705,8 +706,8 @@ fn test_authentication_request() {
#[test] #[test]
fn test_web_resource_load() { fn test_web_resource_load() {
use base::generic_channel;
use http::{HeaderMap, Method, StatusCode}; use http::{HeaderMap, Method, StatusCode};
use ipc_channel::ipc;
use crate::ServoErrorChannel; use crate::ServoErrorChannel;
@ -724,7 +725,7 @@ fn test_web_resource_load() {
// Explicit intercept with explicit cancel yields Start and Cancel and nothing else // Explicit intercept with explicit cancel yields Start and Cancel and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender()); let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
request.intercept(web_resource_response()).cancel(); request.intercept(web_resource_response()).cancel();
assert!(matches!( assert!(matches!(
@ -740,7 +741,7 @@ fn test_web_resource_load() {
// Explicit intercept with no further action yields Start and FinishLoad and nothing else // Explicit intercept with no further action yields Start and FinishLoad and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender()); let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
drop(request.intercept(web_resource_response())); drop(request.intercept(web_resource_response()));
assert!(matches!( assert!(matches!(
@ -756,7 +757,7 @@ fn test_web_resource_load() {
// No response yields DoNotIntercept and nothing else // No response yields DoNotIntercept and nothing else
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender()); let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
drop(request); drop(request);
assert!(matches!( assert!(matches!(
@ -768,7 +769,7 @@ fn test_web_resource_load() {
// Explicit intercept with explicit cancel when receiver disconnected yields error // Explicit intercept with explicit cancel when receiver disconnected yields error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender()); let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
drop(receiver); drop(receiver);
request.intercept(web_resource_response()).cancel(); request.intercept(web_resource_response()).cancel();
@ -776,7 +777,7 @@ fn test_web_resource_load() {
// Explicit intercept with no further action when receiver disconnected yields error // Explicit intercept with no further action when receiver disconnected yields error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender()); let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
drop(receiver); drop(receiver);
drop(request.intercept(web_resource_response())); drop(request.intercept(web_resource_response()));
@ -784,7 +785,7 @@ fn test_web_resource_load() {
// No response when receiver disconnected yields no error // No response when receiver disconnected yields no error
let errors = ServoErrorChannel::default(); let errors = ServoErrorChannel::default();
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel");
let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender()); let request = WebResourceLoad::new(web_resource_request(), sender, errors.sender());
drop(receiver); drop(receiver);
drop(request); drop(request);

View file

@ -21,6 +21,7 @@ use std::ops::Range;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use base::generic_channel::GenericSender;
use base::id::{PipelineId, WebViewId}; use base::id::{PipelineId, WebViewId};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use euclid::{Point2D, Scale, Size2D}; use euclid::{Point2D, Scale, Size2D};
@ -147,20 +148,20 @@ pub enum SimpleDialog {
/// TODO: Include details about the document origin. /// TODO: Include details about the document origin.
Alert { Alert {
message: String, message: String,
response_sender: IpcSender<AlertResponse>, response_sender: GenericSender<AlertResponse>,
}, },
/// [`confirm()`](https://html.spec.whatwg.org/multipage/#dom-confirm). /// [`confirm()`](https://html.spec.whatwg.org/multipage/#dom-confirm).
/// TODO: Include details about the document origin. /// TODO: Include details about the document origin.
Confirm { Confirm {
message: String, message: String,
response_sender: IpcSender<ConfirmResponse>, response_sender: GenericSender<ConfirmResponse>,
}, },
/// [`prompt()`](https://html.spec.whatwg.org/multipage/#dom-prompt). /// [`prompt()`](https://html.spec.whatwg.org/multipage/#dom-prompt).
/// TODO: Include details about the document origin. /// TODO: Include details about the document origin.
Prompt { Prompt {
message: String, message: String,
default: String, default: String,
response_sender: IpcSender<PromptResponse>, response_sender: GenericSender<PromptResponse>,
}, },
} }
@ -426,19 +427,22 @@ pub enum EmbedderMsg {
WebViewId, WebViewId,
ServoUrl, ServoUrl,
bool, /* for proxy */ bool, /* for proxy */
IpcSender<Option<AuthenticationResponse>>, GenericSender<Option<AuthenticationResponse>>,
), ),
/// Show a context menu to the user /// Show a context menu to the user
ShowContextMenu( ShowContextMenu(
WebViewId, WebViewId,
IpcSender<ContextMenuResult>, GenericSender<ContextMenuResult>,
Option<String>, Option<String>,
Vec<String>, Vec<String>,
), ),
/// Whether or not to allow a pipeline to load a url. /// Whether or not to allow a pipeline to load a url.
AllowNavigationRequest(WebViewId, PipelineId, ServoUrl), AllowNavigationRequest(WebViewId, PipelineId, ServoUrl),
/// Whether or not to allow script to open a new tab/browser /// Whether or not to allow script to open a new tab/browser
AllowOpeningWebView(WebViewId, IpcSender<Option<(WebViewId, ViewportDetails)>>), AllowOpeningWebView(
WebViewId,
GenericSender<Option<(WebViewId, ViewportDetails)>>,
),
/// A webview was destroyed. /// A webview was destroyed.
WebViewClosed(WebViewId), WebViewClosed(WebViewId),
/// A webview potentially gained focus for keyboard events, as initiated /// A webview potentially gained focus for keyboard events, as initiated
@ -448,7 +452,7 @@ pub enum EmbedderMsg {
/// All webviews lost focus for keyboard events. /// All webviews lost focus for keyboard events.
WebViewBlurred, WebViewBlurred,
/// Wether or not to unload a document /// Wether or not to unload a document
AllowUnload(WebViewId, IpcSender<AllowOrDeny>), AllowUnload(WebViewId, GenericSender<AllowOrDeny>),
/// Sends an unconsumed key event back to the embedder. /// Sends an unconsumed key event back to the embedder.
Keyboard(WebViewId, KeyboardEvent), Keyboard(WebViewId, KeyboardEvent),
/// Inform embedder to clear the clipboard /// Inform embedder to clear the clipboard
@ -466,9 +470,9 @@ pub enum EmbedderMsg {
/// A history traversal operation completed. /// A history traversal operation completed.
HistoryTraversalComplete(WebViewId, TraversalId), HistoryTraversalComplete(WebViewId, TraversalId),
/// Get the device independent window rectangle. /// Get the device independent window rectangle.
GetWindowRect(WebViewId, IpcSender<DeviceIndependentIntRect>), GetWindowRect(WebViewId, GenericSender<DeviceIndependentIntRect>),
/// Get the device independent screen size and available size. /// Get the device independent screen size and available size.
GetScreenMetrics(WebViewId, IpcSender<ScreenMetrics>), GetScreenMetrics(WebViewId, GenericSender<ScreenMetrics>),
/// Entered or exited fullscreen. /// Entered or exited fullscreen.
NotifyFullscreenStateChanged(WebViewId, bool), NotifyFullscreenStateChanged(WebViewId, bool),
/// The [`LoadStatus`] of the Given `WebView` has changed. /// The [`LoadStatus`] of the Given `WebView` has changed.
@ -476,21 +480,21 @@ pub enum EmbedderMsg {
WebResourceRequested( WebResourceRequested(
Option<WebViewId>, Option<WebViewId>,
WebResourceRequest, WebResourceRequest,
IpcSender<WebResourceResponseMsg>, GenericSender<WebResourceResponseMsg>,
), ),
/// A pipeline panicked. First string is the reason, second one is the backtrace. /// A pipeline panicked. First string is the reason, second one is the backtrace.
Panic(WebViewId, String, Option<String>), Panic(WebViewId, String, Option<String>),
/// Open dialog to select bluetooth device. /// Open dialog to select bluetooth device.
GetSelectedBluetoothDevice(WebViewId, Vec<String>, IpcSender<Option<String>>), GetSelectedBluetoothDevice(WebViewId, Vec<String>, GenericSender<Option<String>>),
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files. /// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
SelectFiles( SelectFiles(
WebViewId, WebViewId,
Vec<FilterPattern>, Vec<FilterPattern>,
bool, bool,
IpcSender<Option<Vec<PathBuf>>>, GenericSender<Option<Vec<PathBuf>>>,
), ),
/// Open interface to request permission specified by prompt. /// Open interface to request permission specified by prompt.
PromptPermission(WebViewId, PermissionFeature, IpcSender<AllowOrDeny>), PromptPermission(WebViewId, PermissionFeature, GenericSender<AllowOrDeny>),
/// Request to present an IME to the user when an editable element is focused. /// Request to present an IME to the user when an editable element is focused.
/// If the input is text, the second parameter defines the pre-existing string /// If the input is text, the second parameter defines the pre-existing string
/// text content and the zero-based index into the string locating the insertion point. /// text content and the zero-based index into the string locating the insertion point.
@ -512,7 +516,7 @@ pub enum EmbedderMsg {
/// Report the status of Devtools Server with a token that can be used to bypass the permission prompt. /// Report the status of Devtools Server with a token that can be used to bypass the permission prompt.
OnDevtoolsStarted(Result<u16, ()>, String), OnDevtoolsStarted(Result<u16, ()>, String),
/// Ask the user to allow a devtools client to connect. /// Ask the user to allow a devtools client to connect.
RequestDevtoolsConnection(IpcSender<AllowOrDeny>), RequestDevtoolsConnection(GenericSender<AllowOrDeny>),
/// Request to play a haptic effect on a connected gamepad. /// Request to play a haptic effect on a connected gamepad.
PlayGamepadHapticEffect(WebViewId, usize, GamepadHapticEffectType, IpcSender<bool>), PlayGamepadHapticEffect(WebViewId, usize, GamepadHapticEffectType, IpcSender<bool>),
/// Request to stop a haptic effect on a connected gamepad. /// Request to stop a haptic effect on a connected gamepad.
@ -546,10 +550,10 @@ pub enum FormControl {
SelectElement( SelectElement(
Vec<SelectElementOptionOrOptgroup>, Vec<SelectElementOptionOrOptgroup>,
Option<usize>, Option<usize>,
IpcSender<Option<usize>>, GenericSender<Option<usize>>,
), ),
/// Indicates that the user has activated a `<input type=color>` element. /// Indicates that the user has activated a `<input type=color>` element.
ColorPicker(RgbColor, IpcSender<Option<RgbColor>>), ColorPicker(RgbColor, GenericSender<Option<RgbColor>>),
} }
/// Filter for file selection; /// Filter for file selection;

View file

@ -704,7 +704,7 @@ impl WebViewDelegate for RunningAppState {
&self, &self,
webview: servo::WebView, webview: servo::WebView,
devices: Vec<String>, devices: Vec<String>,
response_sender: IpcSender<Option<String>>, response_sender: GenericSender<Option<String>>,
) { ) {
self.add_dialog( self.add_dialog(
webview, webview,
@ -717,7 +717,7 @@ impl WebViewDelegate for RunningAppState {
webview: servo::WebView, webview: servo::WebView,
filter_pattern: Vec<FilterPattern>, filter_pattern: Vec<FilterPattern>,
allow_select_mutiple: bool, allow_select_mutiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>, response_sender: GenericSender<Option<Vec<PathBuf>>>,
) { ) {
let file_dialog = let file_dialog =
Dialog::new_file_dialog(allow_select_mutiple, response_sender, filter_pattern); Dialog::new_file_dialog(allow_select_mutiple, response_sender, filter_pattern);

View file

@ -9,7 +9,7 @@ use egui::Modal;
use egui_file_dialog::{DialogState, FileDialog as EguiFileDialog}; use egui_file_dialog::{DialogState, FileDialog as EguiFileDialog};
use euclid::Length; use euclid::Length;
use log::warn; use log::warn;
use servo::ipc_channel::ipc::IpcSender; use servo::base::generic_channel::GenericSender;
use servo::servo_geometry::DeviceIndependentPixel; use servo::servo_geometry::DeviceIndependentPixel;
use servo::{ use servo::{
AlertResponse, AuthenticationRequest, ColorPicker, ConfirmResponse, FilterPattern, AlertResponse, AuthenticationRequest, ColorPicker, ConfirmResponse, FilterPattern,
@ -22,7 +22,7 @@ pub enum Dialog {
File { File {
dialog: EguiFileDialog, dialog: EguiFileDialog,
multiple: bool, multiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>, response_sender: GenericSender<Option<Vec<PathBuf>>>,
}, },
#[allow(clippy::enum_variant_names, reason = "spec terminology")] #[allow(clippy::enum_variant_names, reason = "spec terminology")]
SimpleDialog(SimpleDialog), SimpleDialog(SimpleDialog),
@ -38,7 +38,7 @@ pub enum Dialog {
SelectDevice { SelectDevice {
devices: Vec<String>, devices: Vec<String>,
selected_device_index: usize, selected_device_index: usize,
response_sender: IpcSender<Option<String>>, response_sender: GenericSender<Option<String>>,
}, },
SelectElement { SelectElement {
maybe_prompt: Option<SelectElement>, maybe_prompt: Option<SelectElement>,
@ -54,7 +54,7 @@ pub enum Dialog {
impl Dialog { impl Dialog {
pub fn new_file_dialog( pub fn new_file_dialog(
multiple: bool, multiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>, response_sender: GenericSender<Option<Vec<PathBuf>>>,
patterns: Vec<FilterPattern>, patterns: Vec<FilterPattern>,
) -> Self { ) -> Self {
let mut dialog = EguiFileDialog::new(); let mut dialog = EguiFileDialog::new();
@ -106,7 +106,7 @@ impl Dialog {
pub fn new_device_selection_dialog( pub fn new_device_selection_dialog(
devices: Vec<String>, devices: Vec<String>,
response_sender: IpcSender<Option<String>>, response_sender: GenericSender<Option<String>>,
) -> Self { ) -> Self {
Dialog::SelectDevice { Dialog::SelectDevice {
devices, devices,

View file

@ -8,9 +8,9 @@ use std::rc::Rc;
use crossbeam_channel::Receiver; use crossbeam_channel::Receiver;
use dpi::PhysicalSize; use dpi::PhysicalSize;
use embedder_traits::webdriver::WebDriverSenders; use embedder_traits::webdriver::WebDriverSenders;
use ipc_channel::ipc::IpcSender;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use raw_window_handle::{RawWindowHandle, WindowHandle}; use raw_window_handle::{RawWindowHandle, WindowHandle};
use servo::base::generic_channel::GenericSender;
use servo::base::id::WebViewId; use servo::base::id::WebViewId;
use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use servo::servo_geometry::DeviceIndependentPixel; use servo::servo_geometry::DeviceIndependentPixel;
@ -95,7 +95,7 @@ struct RunningAppStateInner {
/// Modified by EmbedderMsg::WebViewFocused and EmbedderMsg::WebViewBlurred. /// Modified by EmbedderMsg::WebViewFocused and EmbedderMsg::WebViewBlurred.
focused_webview_id: Option<WebViewId>, focused_webview_id: Option<WebViewId>,
context_menu_sender: Option<IpcSender<ContextMenuResult>>, context_menu_sender: Option<GenericSender<ContextMenuResult>>,
/// Whether or not the animation state has changed. This is used to trigger /// Whether or not the animation state has changed. This is used to trigger
/// host callbacks indicating that animation state has changed. /// host callbacks indicating that animation state has changed.
@ -265,7 +265,7 @@ impl WebViewDelegate for RunningAppState {
fn show_context_menu( fn show_context_menu(
&self, &self,
_webview: WebView, _webview: WebView,
result_sender: IpcSender<ContextMenuResult>, result_sender: GenericSender<ContextMenuResult>,
title: Option<String>, title: Option<String>,
items: Vec<String>, items: Vec<String>,
) { ) {