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::time::Duration;
use base::generic_channel;
use base::id::WebViewId;
use bitflags::bitflags;
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
.send(EmbedderMsg::GetSelectedBluetoothDevice(
webview_id,

View file

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

View file

@ -18,6 +18,7 @@ use std::net::{Shutdown, TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::thread;
use base::generic_channel;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
use crossbeam_channel::{Receiver, Sender, unbounded};
use devtools_traits::{
@ -26,7 +27,7 @@ use devtools_traits::{
ScriptToDevtoolsControlMsg, SourceInfo, WorkerId,
};
use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy};
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::ipc::IpcSender;
use log::{trace, warn};
use resource::{ResourceArrayType, ResourceAvailable};
use serde::Serialize;
@ -651,7 +652,8 @@ fn allow_devtools_client(stream: &mut TcpStream, embedder: &EmbedderProxy, token
};
// 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));
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::{Arc, Mutex, RwLock, Weak};
use base::generic_channel;
use base::id::WebViewId;
use embedder_traits::{EmbedderMsg, EmbedderProxy, FilterPattern};
use headers::{ContentLength, ContentRange, ContentType, HeaderMap, HeaderMapExt, Range};
use http::header::{self, HeaderValue};
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::ipc::IpcSender;
use log::warn;
use mime::{self, Mime};
use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError};
@ -583,7 +584,8 @@ impl FileManagerStore {
multiple_files: bool,
embedder_proxy: EmbedderProxy,
) -> 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(
webview_id,
patterns,

View file

@ -9,6 +9,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
use async_recursion::async_recursion;
use base::cross_process_instant::CrossProcessInstant;
use base::generic_channel;
use base::id::{BrowsingContextId, HistoryStateId, PipelineId};
use crossbeam_channel::Sender;
use devtools_traits::{
@ -138,7 +139,7 @@ impl HttpState {
}
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(
webview_id,
request.url(),

View file

@ -2,9 +2,9 @@
* 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 base::generic_channel;
use content_security_policy::Destination;
use embedder_traits::{EmbedderMsg, EmbedderProxy, WebResourceRequest, WebResourceResponseMsg};
use ipc_channel::ipc;
use log::error;
use net_traits::NetworkError;
use net_traits::http_status::HttpStatus;
@ -29,7 +29,7 @@ impl RequestInterceptor {
response: &mut Option<Response>,
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 web_resource_request = WebResourceRequest {
method: request.method.clone(),

View file

@ -12,9 +12,9 @@ use std::str::FromStr;
use std::sync::{LazyLock, Mutex};
use std::time::Duration;
use base::Epoch;
use base::cross_process_instant::CrossProcessInstant;
use base::id::WebViewId;
use base::{Epoch, generic_channel};
use canvas_traits::canvas::CanvasId;
use canvas_traits::webgl::{WebGLContextId, WebGLMsg};
use chrono::Local;
@ -32,7 +32,6 @@ use euclid::default::{Rect, Size2D};
use fnv::FnvHashMap;
use html5ever::{LocalName, Namespace, QualName, local_name, ns};
use hyper_serde::Serde;
use ipc_channel::ipc;
use js::rust::{HandleObject, HandleValue, MutableHandleValue};
use layout_api::{PendingRestyle, ReflowGoal, ReflowPhasesRun, RestyleReason, TrustedNodeAddress};
use metrics::{InteractiveFlag, InteractiveWindow, ProgressiveWebMetrics};
@ -1929,7 +1928,7 @@ impl Document {
.ReturnValue()
.is_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);
self.send_to_embedder(msg);
can_unload = port.recv().unwrap() == AllowOrDeny::Allow;

View file

@ -9,6 +9,7 @@ use std::mem;
use std::rc::Rc;
use std::time::{Duration, Instant};
use base::generic_channel;
use constellation_traits::ScriptToConstellationMessage;
use embedder_traits::{
Cursor, EditingActionEvent, EmbedderMsg, GamepadEvent as EmbedderGamepadEvent,
@ -689,7 +690,8 @@ impl DocumentEventHandler {
// Step 4. If result is true, then show the UA context menu
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.webview_id(),
sender,

View file

@ -11,6 +11,7 @@ use std::ptr::NonNull;
use std::str::FromStr;
use std::{f64, ptr};
use base::generic_channel;
use dom_struct::dom_struct;
use embedder_traits::{
EmbedderMsg, FilterPattern, FormControl as EmbedderFormControl, InputMethodType, RgbColor,
@ -18,7 +19,6 @@ use embedder_traits::{
use encoding_rs::Encoding;
use euclid::{Point2D, Rect, Size2D};
use html5ever::{LocalName, Prefix, local_name, ns};
use ipc_channel::ipc;
use js::jsapi::{
ClippedTime, DateGetMsecSinceEpoch, Handle, JS_ClearPendingException, JSObject, NewDateObject,
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,
// in the way it normally would when the user interacts with the control.
if self.input_type() == InputType::Color {
let (ipc_sender, ipc_receiver) =
ipc::channel::<Option<RgbColor>>().expect("Failed to create IPC channel!");
let (ipc_sender, ipc_receiver) = generic_channel::channel::<Option<RgbColor>>()
.expect("Failed to create IPC channel!");
let document = self.owner_document();
let rect = self.upcast::<Node>().border_box().unwrap_or_default();
let rect = Rect::new(

View file

@ -10,12 +10,11 @@ use embedder_traits::{EmbedderMsg, FormControl as EmbedderFormControl};
use embedder_traits::{SelectElementOption, SelectElementOptionOrOptgroup};
use euclid::{Point2D, Rect, Size2D};
use html5ever::{LocalName, Prefix, local_name};
use ipc_channel::ipc;
use js::rust::HandleObject;
use style::attr::AttrValue;
use stylo_dom::ElementState;
use webrender_api::units::DeviceIntRect;
use base::generic_channel;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::event::{EventBubbles, EventCancelable, EventComposed};
use crate::dom::bindings::codegen::GenericBindings::HTMLOptGroupElementBinding::HTMLOptGroupElement_Binding::HTMLOptGroupElementMethods;
@ -340,7 +339,8 @@ impl HTMLSelectElement {
}
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
let mut index = 0;

View file

@ -4,9 +4,9 @@
use std::rc::Rc;
use base::generic_channel;
use dom_struct::dom_struct;
use embedder_traits::{self, AllowOrDeny, EmbedderMsg, PermissionFeature};
use ipc_channel::ipc;
use js::conversions::ConversionResult;
use js::jsapi::JSObject;
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");
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(
webview_id,
name.convert(),

View file

@ -2,9 +2,9 @@
* 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 base::generic_channel;
use dom_struct::dom_struct;
use embedder_traits::{EmbedderMsg, ScreenMetrics};
use ipc_channel::ipc;
use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods;
use crate::dom::bindings::num::Finite;
@ -33,7 +33,7 @@ impl Screen {
/// Retrives [`ScreenMetrics`] from the embedder.
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.webview_id(),

View file

@ -17,6 +17,7 @@ use std::time::{Duration, Instant};
use app_units::Au;
use backtrace::Backtrace;
use base::cross_process_instant::CrossProcessInstant;
use base::generic_channel;
use base::generic_channel::GenericSender;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
use base64::Engine;
@ -67,7 +68,7 @@ use net_traits::image_cache::{
};
use net_traits::storage_thread::StorageType;
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::time::ProfilerChan as TimeProfilerChan;
use script_bindings::conversions::SafeToJSValConvertible;
@ -862,7 +863,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
stderr.flush().unwrap();
}
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 {
message: s.to_string(),
response_sender: sender,
@ -879,7 +880,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://html.spec.whatwg.org/multipage/#dom-confirm
fn Confirm(&self, s: DOMString) -> bool {
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 {
message: s.to_string(),
response_sender: sender,
@ -899,7 +900,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://html.spec.whatwg.org/multipage/#dom-prompt
fn Prompt(&self, message: DOMString, default: DOMString) -> Option<DOMString> {
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 {
message: message.to_string(),
default: default.to_string(),
@ -2137,7 +2138,7 @@ impl Window {
}
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));

View file

@ -2,6 +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 base::generic_channel;
use crossbeam_channel::{Receiver, Sender, TryRecvError, unbounded};
use log::warn;
@ -15,7 +16,7 @@ pub(crate) struct 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)) {
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
* 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 base::generic_channel;
use embedder_traits::Notification;
use crate::Servo;
@ -16,7 +16,7 @@ pub enum ServoError {
/// to start.
DevtoolsFailedToStart,
/// Failed to send response to delegate request.
ResponseFailedToSend(bincode::Error),
ResponseFailedToSend(generic_channel::SendError),
}
pub trait ServoDelegate {

View file

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

View file

@ -21,6 +21,7 @@ use std::ops::Range;
use std::path::PathBuf;
use std::sync::Arc;
use base::generic_channel::GenericSender;
use base::id::{PipelineId, WebViewId};
use crossbeam_channel::Sender;
use euclid::{Point2D, Scale, Size2D};
@ -147,20 +148,20 @@ pub enum SimpleDialog {
/// TODO: Include details about the document origin.
Alert {
message: String,
response_sender: IpcSender<AlertResponse>,
response_sender: GenericSender<AlertResponse>,
},
/// [`confirm()`](https://html.spec.whatwg.org/multipage/#dom-confirm).
/// TODO: Include details about the document origin.
Confirm {
message: String,
response_sender: IpcSender<ConfirmResponse>,
response_sender: GenericSender<ConfirmResponse>,
},
/// [`prompt()`](https://html.spec.whatwg.org/multipage/#dom-prompt).
/// TODO: Include details about the document origin.
Prompt {
message: String,
default: String,
response_sender: IpcSender<PromptResponse>,
response_sender: GenericSender<PromptResponse>,
},
}
@ -426,19 +427,22 @@ pub enum EmbedderMsg {
WebViewId,
ServoUrl,
bool, /* for proxy */
IpcSender<Option<AuthenticationResponse>>,
GenericSender<Option<AuthenticationResponse>>,
),
/// Show a context menu to the user
ShowContextMenu(
WebViewId,
IpcSender<ContextMenuResult>,
GenericSender<ContextMenuResult>,
Option<String>,
Vec<String>,
),
/// Whether or not to allow a pipeline to load a url.
AllowNavigationRequest(WebViewId, PipelineId, ServoUrl),
/// 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.
WebViewClosed(WebViewId),
/// A webview potentially gained focus for keyboard events, as initiated
@ -448,7 +452,7 @@ pub enum EmbedderMsg {
/// All webviews lost focus for keyboard events.
WebViewBlurred,
/// Wether or not to unload a document
AllowUnload(WebViewId, IpcSender<AllowOrDeny>),
AllowUnload(WebViewId, GenericSender<AllowOrDeny>),
/// Sends an unconsumed key event back to the embedder.
Keyboard(WebViewId, KeyboardEvent),
/// Inform embedder to clear the clipboard
@ -466,9 +470,9 @@ pub enum EmbedderMsg {
/// A history traversal operation completed.
HistoryTraversalComplete(WebViewId, TraversalId),
/// Get the device independent window rectangle.
GetWindowRect(WebViewId, IpcSender<DeviceIndependentIntRect>),
GetWindowRect(WebViewId, GenericSender<DeviceIndependentIntRect>),
/// Get the device independent screen size and available size.
GetScreenMetrics(WebViewId, IpcSender<ScreenMetrics>),
GetScreenMetrics(WebViewId, GenericSender<ScreenMetrics>),
/// Entered or exited fullscreen.
NotifyFullscreenStateChanged(WebViewId, bool),
/// The [`LoadStatus`] of the Given `WebView` has changed.
@ -476,21 +480,21 @@ pub enum EmbedderMsg {
WebResourceRequested(
Option<WebViewId>,
WebResourceRequest,
IpcSender<WebResourceResponseMsg>,
GenericSender<WebResourceResponseMsg>,
),
/// A pipeline panicked. First string is the reason, second one is the backtrace.
Panic(WebViewId, String, Option<String>),
/// 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.
SelectFiles(
WebViewId,
Vec<FilterPattern>,
bool,
IpcSender<Option<Vec<PathBuf>>>,
GenericSender<Option<Vec<PathBuf>>>,
),
/// 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.
/// 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.
@ -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.
OnDevtoolsStarted(Result<u16, ()>, String),
/// 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.
PlayGamepadHapticEffect(WebViewId, usize, GamepadHapticEffectType, IpcSender<bool>),
/// Request to stop a haptic effect on a connected gamepad.
@ -546,10 +550,10 @@ pub enum FormControl {
SelectElement(
Vec<SelectElementOptionOrOptgroup>,
Option<usize>,
IpcSender<Option<usize>>,
GenericSender<Option<usize>>,
),
/// 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;

View file

@ -704,7 +704,7 @@ impl WebViewDelegate for RunningAppState {
&self,
webview: servo::WebView,
devices: Vec<String>,
response_sender: IpcSender<Option<String>>,
response_sender: GenericSender<Option<String>>,
) {
self.add_dialog(
webview,
@ -717,7 +717,7 @@ impl WebViewDelegate for RunningAppState {
webview: servo::WebView,
filter_pattern: Vec<FilterPattern>,
allow_select_mutiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>,
response_sender: GenericSender<Option<Vec<PathBuf>>>,
) {
let file_dialog =
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 euclid::Length;
use log::warn;
use servo::ipc_channel::ipc::IpcSender;
use servo::base::generic_channel::GenericSender;
use servo::servo_geometry::DeviceIndependentPixel;
use servo::{
AlertResponse, AuthenticationRequest, ColorPicker, ConfirmResponse, FilterPattern,
@ -22,7 +22,7 @@ pub enum Dialog {
File {
dialog: EguiFileDialog,
multiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>,
response_sender: GenericSender<Option<Vec<PathBuf>>>,
},
#[allow(clippy::enum_variant_names, reason = "spec terminology")]
SimpleDialog(SimpleDialog),
@ -38,7 +38,7 @@ pub enum Dialog {
SelectDevice {
devices: Vec<String>,
selected_device_index: usize,
response_sender: IpcSender<Option<String>>,
response_sender: GenericSender<Option<String>>,
},
SelectElement {
maybe_prompt: Option<SelectElement>,
@ -54,7 +54,7 @@ pub enum Dialog {
impl Dialog {
pub fn new_file_dialog(
multiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>,
response_sender: GenericSender<Option<Vec<PathBuf>>>,
patterns: Vec<FilterPattern>,
) -> Self {
let mut dialog = EguiFileDialog::new();
@ -106,7 +106,7 @@ impl Dialog {
pub fn new_device_selection_dialog(
devices: Vec<String>,
response_sender: IpcSender<Option<String>>,
response_sender: GenericSender<Option<String>>,
) -> Self {
Dialog::SelectDevice {
devices,

View file

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