Skip to content

Commit

Permalink
feat: implement devtools API, closes #287 (#486)
Browse files Browse the repository at this point in the history
* feat: implement `open_devtools` on Linux

* refactor: remove flag

* fix example

* feat: windows impl

* feat: macos impl

* chore: add change file

* chore: do not attempt to open devtools on iOS

[skip ci]

* Add devtool feature flag

* Add devtool config

* Update change file

* Update devtool trigger condition

Co-authored-by: Yu-Wei Wu <[email protected]>
  • Loading branch information
lucasfernog and Yu-Wei Wu authored Feb 7, 2022
1 parent 7d4eeb7 commit d0f307b
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changes/open-devtools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": patch
---

Add `devtool` feature flag and configuration option.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ protocol = [ ]
dox = [ "tao/dox" ]
tray = [ "tao/tray" ]
ayatana = [ "tao/ayatana" ]
devtool = [ ]
transparent = [ ]
fullscreen = [ ]

Expand Down
7 changes: 4 additions & 3 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ fn main() -> wry::Result<()> {
.with_url("https://html5test.com")?
.build()?;

#[cfg(debug_assertions)]
webview.devtool();

event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;

Expand All @@ -29,9 +32,7 @@ fn main() -> wry::Result<()> {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
_ => {
dbg!(webview.window().inner_size());
}
_ => (),
}
});
}
14 changes: 6 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,16 @@
//! to install `libappindicator` package. Enabled by default.
//! - `ayatana`: Enable this if you wish to use more update `libayatana-appindicator` since
//! `libappindicator` is no longer maintained.
//! - `devtool`: Enable devtool on **macOS** requires calling private functions. While it's still
//! enabled in **debug** build on mac, it will require this feature flag to actually enable it in
//! **release** build. Avoid this in release build if your app needs to publish to App Store.
//! - `transparent`: Transparent background on **macOS** requires calling private functions.
//! Disable this if you are avoiding them.
//! - `fullscreen`: Fullscreen video and other medias on **macOS** requires calling private functions.
//! Disable this if you are avoiding them.
//! Avoid this in release build if your app needs to publish to App Store.
//! - `fullscreen`: Fullscreen video and other media on **macOS** requires calling private functions.
//! Avoid this in release build if your app needs to publish to App Store.
//! - `dox`: Enables this in `package.metadata.docs.rs` section to skip linking some **Linux**
//! libraries and prevent from building documentation on doc.rs fails.
//!
//! ## Debug build
//!
//! Debug profile enables tools like inspector for development or debug usage. Note this will call
//! private APIs on macOS.
//!
//! [tao]: https://crates.io/crates/tao
//! [`EventLoop`]: crate::application::event_loop::EventLoop
//! [`Window`]: crate::application::window::Window
Expand Down
29 changes: 29 additions & 0 deletions src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ pub struct WebViewAttributes {
/// macOS doesn't provide such method and is always enabled by default. But you still need to add menu
/// item accelerators to use shortcuts.
pub clipboard: bool,

/// Enable web insepctor which is usually called dev tool.
///
/// Note this only enables dev tool to the webview. To open it, you can call
/// [`WebView::devtool`], or right click the page and open it from the context menu.
///
/// # Warning
/// This will call private functions on **macOS**. It's still enabled if set in **debug** build on mac,
/// but requires `devtool` feature flag to actually enable it in **release** build.
pub devtool: bool,
}

impl Default for WebViewAttributes {
Expand All @@ -130,6 +140,7 @@ impl Default for WebViewAttributes {
ipc_handler: None,
file_drop_handler: None,
clipboard: false,
devtool: false,
}
}
}
Expand Down Expand Up @@ -272,6 +283,19 @@ impl<'a> WebViewBuilder<'a> {
self
}

/// Enable web insepctor which is usually called dev tool.
///
/// Note this only enables dev tool to the webview. To open it, you can call
/// [`WebView::devtool`], or right click the page and open it from the context menu.
///
/// # Warning
/// This will call private functions on **macOS**. It's still enabled if set in **debug** build on mac,
/// but requires `devtool` feature flag to actually enable it in **release** build.
pub fn with_dev_tool(mut self, devtool: bool) -> Self {
self.webview.devtool = devtool;
self
}

/// Consume the builder and create the [`WebView`].
///
/// Platform-specific behavior:
Expand Down Expand Up @@ -374,6 +398,11 @@ impl WebView {
self.webview.focus();
}

/// Open the web insepctor which is usually called dev tool.
pub fn devtool(&self) {
self.webview.devtool();
}

pub fn inner_size(&self) -> PhysicalSize<u32> {
#[cfg(target_os = "macos")]
{
Expand Down
16 changes: 10 additions & 6 deletions src/webview/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,9 @@ impl InnerWebView {
// Set user agent
settings.set_user_agent(attributes.user_agent.as_deref());

debug_assert_eq!(
{
settings.set_enable_developer_extras(true);
},
()
);
if attributes.devtool {
settings.set_enable_developer_extras(true);
}
}

// Transparent
Expand Down Expand Up @@ -314,6 +311,13 @@ impl InnerWebView {
pub fn focus(&self) {
self.webview.grab_focus();
}

/// Open the web insepctor which is usually called dev tool.
pub fn devtool(&self) {
if let Some(inspector) = WebViewExt::inspector(&*self.webview) {
inspector.show();
}
}
}

pub fn platform_webview_version() -> Result<String> {
Expand Down
11 changes: 10 additions & 1 deletion src/webview/webview2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ impl InnerWebView {
settings
.SetAreDevToolsEnabled(false)
.map_err(webview2_com::Error::WindowsError)?;
debug_assert_eq!(settings.SetAreDevToolsEnabled(true), Ok(()));
if attributes.devtool {
settings.SetAreDevToolsEnabled(true);
}

let mut rect = RECT::default();
GetClientRect(hwnd, &mut rect);
Expand Down Expand Up @@ -572,6 +574,13 @@ window.addEventListener('mousemove', (e) => window.chrome.webview.postMessage('_
.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
};
}

/// Open the web insepctor which is usually called dev tool.
pub fn devtool(&self) {
let _ = unsafe {
self.webview.OpenDevToolsWindow();
};
}
}

pub fn platform_webview_version() -> Result<String> {
Expand Down
39 changes: 26 additions & 13 deletions src/webview/wkwebview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,18 +250,16 @@ impl InnerWebView {
_ => class!(WryWebView),
};
let webview: id = msg_send![cls, alloc];
let preference: id = msg_send![config, preferences];
let yes: id = msg_send![class!(NSNumber), numberWithBool:1];

debug_assert_eq!(
{
// Equivalent Obj-C:
// [[config preferences] setValue:@YES forKey:@"developerExtrasEnabled"];
let dev = NSString::new("developerExtrasEnabled");
let _: id = msg_send![preference, setValue:yes forKey:dev];
},
()
);
let _preference: id = msg_send![config, preferences];
let _yes: id = msg_send![class!(NSNumber), numberWithBool:1];

#[cfg(any(debug_assertions, feature = "devtool"))]
if attributes.devtool {
// Equivalent Obj-C:
// [[config preferences] setValue:@YES forKey:@"developerExtrasEnabled"];
let dev = NSString::new("developerExtrasEnabled");
let _: id = msg_send![_preference, setValue:_yes forKey:dev];
}

#[cfg(feature = "transparent")]
if attributes.transparent {
Expand All @@ -274,7 +272,7 @@ impl InnerWebView {
#[cfg(feature = "fullscreen")]
// Equivalent Obj-C:
// [preference setValue:@YES forKey:@"fullScreenEnabled"];
let _: id = msg_send![preference, setValue:yes forKey:NSString::new("fullScreenEnabled")];
let _: id = msg_send![_preference, setValue:_yes forKey:NSString::new("fullScreenEnabled")];

// Initialize webview with zero point
let zero = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(0., 0.));
Expand Down Expand Up @@ -456,6 +454,21 @@ r#"Object.defineProperty(window, 'ipc', {

pub fn focus(&self) {}

/// Open the web insepctor which is usually called dev tool.
///
/// ## Platform-specific
///
/// - **iOS:** Not implemented.
pub fn devtool(&self) {
#[cfg(target_os = "macos")]
#[cfg(any(debug_assertions, feature = "devtool"))]
unsafe {
// taken from <https://github.com/WebKit/WebKit/blob/784f93cb80a386c29186c510bba910b67ce3adc1/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm#L1939>
let tool: id = msg_send![self.webview, _inspector];
let _: id = msg_send![tool, show];
}
}

#[cfg(target_os = "macos")]
pub fn inner_size(&self, scale_factor: f64) -> PhysicalSize<u32> {
let view_frame = unsafe { NSView::frame(self.webview) };
Expand Down

0 comments on commit d0f307b

Please sign in to comment.