Skip to content

Commit

Permalink
feat/ allow webview2 (windows) to use optional user_data folder provi…
Browse files Browse the repository at this point in the history
…ded by the attributes. (#120)

* WIP: Allow webview2 to use optional user_data folder.

Actually only supported on Windows.
Attention the folder need to exist or webview will failed to run.

* Use `./target/webview_data` as sample directory for `user_data_path` example.

* Use canonicalized path as we require an absolute path for the webview

* Make sure to create the directory before we can canonicalize

* fmt
  • Loading branch information
lemarier authored Mar 17, 2021
1 parent 7d1f009 commit 8dd58ee
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 7 deletions.
27 changes: 27 additions & 0 deletions examples/custom_user_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::{fs, path::PathBuf};
use wry::{Application, Attributes, Result};

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

// Use a sample directory at the root of the project
let mut test_path = PathBuf::from("./target/webview_data");
// The directory need to exist or the Webview will panic
fs::create_dir_all(&test_path)?;
// We need an absoulte path for the webview
test_path = fs::canonicalize(&test_path)?;
// The directory need to exist or the Webview will panic
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

0 comments on commit 8dd58ee

Please sign in to comment.