Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the first created webview for webkit2gtk automation callbacks #383

Merged
merged 2 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/webcontext-first-webview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": patch
---

On Linux, automation callbacks now use the first created webview as the return value
5 changes: 0 additions & 5 deletions .changes/webdriver-auto-closure.md

This file was deleted.

45 changes: 25 additions & 20 deletions src/webview/web_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,13 @@ pub mod unix {
webview_uri_loader: Rc<WebviewUriLoader>,
registered_protocols: HashSet<String>,
automation: bool,
app_info: Option<ApplicationInfo>,
}

impl WebContextImpl {
pub fn new(data: &super::WebContextData) -> Self {
use webkit2gtk::traits::*;

let mut context_builder = WebContextBuilder::new();
if let Some(data_directory) = data.data_directory() {
let data_manager = WebsiteDataManagerBuilder::new()
Expand Down Expand Up @@ -172,32 +174,13 @@ pub mod unix {
.expect("invalid wry version patch"),
);

context.connect_automation_started(move |ctx, auto| {
let webview = {
let mut webview = webkit2gtk::WebViewBuilder::new();
webview = webview.web_context(ctx);
webview = webview.is_controlled_by_automation(true);
webview.build()
};
auto.set_application_info(&app_info);

// We do **NOT** support arbitrarily creating new webviews.
// To support this in the future, we would need a way to specify the
// default WindowBuilder to use to create the window it will use, and
// possibly "default" webview attributes. Difficulty comes in for controlling
// the owned Window that would need to be used.
//
// NOTE: We use a fake webview just created above to give back, although the testing
// suites that call it do not seem to use it.
auto.connect_create_web_view(None, move |_| webview.clone());
});

Self {
context,
automation,
manager: UserContentManager::new(),
registered_protocols: Default::default(),
webview_uri_loader: Rc::default(),
app_info: Some(app_info),
}
}

Expand Down Expand Up @@ -247,6 +230,8 @@ pub mod unix {
///
/// **Note:** `libwebkit2gtk` only allows 1 automation context at a time.
fn allows_automation(&self) -> bool;

fn register_automation(&mut self, webview: WebView);
}

impl WebContextExt for super::WebContext {
Expand Down Expand Up @@ -292,6 +277,26 @@ pub mod unix {
fn allows_automation(&self) -> bool {
self.os.automation
}

fn register_automation(&mut self, webview: WebView) {
use webkit2gtk::traits::*;

if let (true, Some(app_info)) = (self.os.automation, self.os.app_info.take()) {
self.os.context.connect_automation_started(move |_, auto| {
let webview = webview.clone();
auto.set_application_info(&app_info);

// We do **NOT** support arbitrarily creating new webviews.
// To support this in the future, we would need a way to specify the
// default WindowBuilder to use to create the window it will use, and
// possibly "default" webview attributes. Difficulty comes in for controlling
// the owned Window that would need to be used.
//
// Instead, we just pass the first created webview.
auto.connect_create_web_view(None, move |_| webview.clone());
});
}
}
}

fn actually_register_uri_scheme<F>(
Expand Down
7 changes: 5 additions & 2 deletions src/webview/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,16 @@ impl InnerWebView {
}
};

let manager = web_context.manager();
let webview = {
let mut webview = WebViewBuilder::new();
webview = webview.user_content_manager(manager);
webview = webview.user_content_manager(web_context.manager());
webview = webview.web_context(web_context.context());
webview = webview.is_controlled_by_automation(web_context.allows_automation());
webview.build()
};

web_context.register_automation(webview.clone());

// Message handler
let webview = Rc::new(webview);
let wv = Rc::clone(&webview);
Expand All @@ -76,6 +77,8 @@ impl InnerWebView {
hasher.finish().to_string()
};

let manager = web_context.manager();

// Connect before registering as recommended by the docs
manager.connect_script_message_received(None, move |_m, msg| {
if let (Some(js), Some(context)) = (msg.value(), msg.global_context()) {
Expand Down