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

feat/ allow webview2 (windows) to use optional user_data folder provided by the attributes. #120

Merged
merged 5 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 22 additions & 0 deletions examples/custom_user_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use std::path::PathBuf;
use wry::{Application, Attributes, Result};

fn main() -> Result<()> {
let mut app = Application::new()?;

let test_path = PathBuf::from(env!("OUT_DIR"));

println!("Webview storage path: {:#?}", test_path);

let attributes = Attributes {
url: Some("https://tauri.studio/".to_string()),
title: String::from("Hello World!"),
// Currently supported only on Windows
user_data_path: Some(test_path),
..Default::default()
};

app.add_window(attributes)?;
app.run();
Ok(())
}
13 changes: 12 additions & 1 deletion src/application/attributes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{Result, RpcRequest, RpcResponse, WindowProxy};

use std::{fs::read, path::Path};
use std::{
fs::read,
path::{Path, PathBuf},
};

/// The RPC handler to Communicate between the host Rust code and Javascript on webview.
///
Expand Down Expand Up @@ -191,6 +194,11 @@ pub struct Attributes {
///
/// The default is an empty vector.
pub initialization_scripts: Vec<String>,

/// Webview user data path.
///
/// The default is `None`.
pub user_data_path: Option<PathBuf>,
}

impl Attributes {
Expand Down Expand Up @@ -220,6 +228,7 @@ impl Attributes {
transparent: self.transparent,
url: self.url,
initialization_scripts: self.initialization_scripts,
user_data_path: self.user_data_path,
},
)
}
Expand Down Expand Up @@ -249,6 +258,7 @@ impl Default for Attributes {
skip_taskbar: false,
url: None,
initialization_scripts: vec![],
user_data_path: None,
}
}
}
Expand Down Expand Up @@ -278,4 +288,5 @@ pub(crate) struct InnerWebViewAttributes {
pub transparent: bool,
pub url: Option<String>,
pub initialization_scripts: Vec<String>,
pub user_data_path: Option<PathBuf>,
}
5 changes: 4 additions & 1 deletion src/application/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,10 @@ fn _create_webview(
) -> Result<WebView> {
let window_id = window.id();

let mut webview = WebViewBuilder::new(window)?.transparent(attributes.transparent);
let mut webview = WebViewBuilder::new(window)?
.transparent(attributes.transparent)
.user_data_path(attributes.user_data_path);

for js in attributes.initialization_scripts {
webview = webview.initialize_script(&js);
}
Expand Down
3 changes: 2 additions & 1 deletion src/webview/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
Error, FileDropHandler, Result, RpcHandler,
};

use std::rc::Rc;
use std::{path::PathBuf, rc::Rc};

use gdk::RGBA;
use gio::Cancellable;
Expand Down Expand Up @@ -33,6 +33,7 @@ impl WV for InnerWebView {
custom_protocol: Option<(String, F)>,
rpc_handler: Option<RpcHandler>,
file_drop_handler: Option<FileDropHandler>,
_user_data_path: Option<PathBuf>,
) -> Result<Self> {
// Webview widget
let manager = UserContentManager::new();
Expand Down
2 changes: 2 additions & 0 deletions src/webview/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use file_drop::{add_file_drop_methods, set_file_drop_handler};
use std::{
ffi::{c_void, CStr},
os::raw::c_char,
path::PathBuf,
ptr::null,
slice, str,
};
Expand Down Expand Up @@ -42,6 +43,7 @@ impl WV for InnerWebView {
custom_protocol: Option<(String, F)>,
rpc_handler: Option<RpcHandler>,
file_drop_handler: Option<FileDropHandler>,
_user_data_path: Option<PathBuf>,
) -> Result<Self> {
// Function for rpc handler
extern "C" fn did_receive(this: &Object, _: Sel, _: id, msg: id) {
Expand Down
27 changes: 25 additions & 2 deletions src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use win::*;

use crate::{Error, FileDropHandler, Result};

use std::sync::mpsc::{channel, Receiver, Sender};
use std::{
path::PathBuf,
sync::mpsc::{channel, Receiver, Sender},
};

use serde_json::Value;
use url::Url;
Expand Down Expand Up @@ -85,6 +88,7 @@ pub struct WebViewBuilder {
custom_protocol: Option<(String, Box<dyn Fn(&str) -> Result<Vec<u8>>>)>,
rpc_handler: Option<RpcHandler>,
file_drop_handler: Option<FileDropHandler>,
user_data_path: Option<PathBuf>,
}

impl WebViewBuilder {
Expand All @@ -102,6 +106,7 @@ impl WebViewBuilder {
custom_protocol: None,
rpc_handler: None,
file_drop_handler: None,
user_data_path: None,
})
}

Expand All @@ -120,6 +125,13 @@ impl WebViewBuilder {
self
}

/// Whether the WebView window should have a custom user data path. This is usefull in Windows
/// when a bundled application can't have the webview data inside `Program Files`.
pub fn user_data_path(mut self, user_data_path: Option<PathBuf>) -> Self {
self.user_data_path = user_data_path;
self
}

/// Create a [`Dispatcher`] to send evaluation scripts to the WebView. [`WebView`] is not thread
/// safe because it must be run on the main thread who creates it. [`Dispatcher`] can let you
/// send the scripts from other threads.
Expand Down Expand Up @@ -213,6 +225,7 @@ impl WebViewBuilder {
self.custom_protocol,
self.rpc_handler,
self.file_drop_handler,
self.user_data_path,
)?;
Ok(WebView {
window: self.window,
Expand Down Expand Up @@ -251,7 +264,16 @@ impl WebView {
pub fn new_with_configs(window: Window, transparent: bool) -> Result<Self> {
let picky_none: Option<(String, Box<dyn Fn(&str) -> Result<Vec<u8>>>)> = None;

let webview = InnerWebView::new(&window, vec![], None, transparent, picky_none, None, None)?;
let webview = InnerWebView::new(
&window,
vec![],
None,
transparent,
picky_none,
None,
None,
None,
)?;

let (tx, rx) = channel();

Expand Down Expand Up @@ -327,6 +349,7 @@ pub(crate) trait WV: Sized {
custom_protocol: Option<(String, F)>,
rpc_handler: Option<RpcHandler>,
file_drop_handler: Option<FileDropHandler>,
user_data_path: Option<PathBuf>,
) -> Result<Self>;

fn eval(&self, js: &str) -> Result<()>;
Expand Down
16 changes: 14 additions & 2 deletions src/webview/win/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{

use file_drop::FileDropController;

use std::{os::raw::c_void, rc::Rc};
use std::{os::raw::c_void, path::PathBuf, rc::Rc};

use once_cell::unsync::OnceCell;
use url::Url;
Expand Down Expand Up @@ -37,6 +37,7 @@ impl WV for InnerWebView {
custom_protocol: Option<(String, F)>,
rpc_handler: Option<RpcHandler>,
file_drop_handler: Option<FileDropHandler>,
user_data_path: Option<PathBuf>,
) -> Result<Self> {
let hwnd = window.hwnd() as HWND;

Expand All @@ -46,8 +47,19 @@ impl WV for InnerWebView {
let file_drop_controller: Rc<OnceCell<FileDropController>> = Rc::new(OnceCell::new());
let file_drop_controller_clone = file_drop_controller.clone();

let webview_builder: webview2::EnvironmentBuilder;
let user_data_path_provided: PathBuf;

if user_data_path.is_some() {
user_data_path_provided = user_data_path.unwrap();
webview_builder =
webview2::EnvironmentBuilder::new().with_user_data_folder(&user_data_path_provided);
} else {
webview_builder = webview2::EnvironmentBuilder::new();
}

// Webview controller
webview2::EnvironmentBuilder::new().build(move |env| {
webview_builder.build(move |env| {
let env = env?;
let env_ = env.clone();
env.create_controller(hwnd, move |controller| {
Expand Down