From 949c031c6f5be8a9eec511eede050172e843df6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Sun, 12 May 2024 19:25:37 +0200 Subject: [PATCH 1/8] feat: add MacOS print options Currently, when printing on a MacOS, it defaults to a quite big margin, which does not reflect the side of it when printing on the web. The current code just creates a new NSPrintInfo from the default, which for some reason has a large margin. This changes so that the default margin is 0 and add the option to change it when printing the webview on MacOs. This is not a field that can be changed by the user on the appkit modal, so it has to be defined before the modal is open. Other options could be added on top of these ones, but for this initial commit/PR decided to go with adding the margins since it seems to be the one with bigger discrepancy compared to the web version. References: - https://developer.apple.com/documentation/appkit/nsprintinfo --- examples/print.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 ++++ src/wkwebview/mod.rs | 34 ++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 examples/print.rs diff --git a/examples/print.rs b/examples/print.rs new file mode 100644 index 000000000..2ef316fa8 --- /dev/null +++ b/examples/print.rs @@ -0,0 +1,93 @@ +// Copyright 2020-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use tao::{ + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoopBuilder}, + window::WindowBuilder, +}; +use wry::http::Request; +use wry::WebViewBuilder; + +enum UserEvent { + Print, +} + +fn main() -> wry::Result<()> { + let event_loop = EventLoopBuilder::::with_user_event().build(); + let proxy = event_loop.create_proxy(); + let window = WindowBuilder::new().build(&event_loop).unwrap(); + + #[cfg(any( + target_os = "windows", + target_os = "macos", + target_os = "ios", + target_os = "android" + ))] + let builder = WebViewBuilder::new(&window); + + #[cfg(not(any( + target_os = "windows", + target_os = "macos", + target_os = "ios", + target_os = "android" + )))] + let builder = { + use tao::platform::unix::WindowExtUnix; + use wry::WebViewBuilderExtUnix; + let vbox = window.default_vbox().unwrap(); + WebViewBuilder::new_gtk(vbox) + }; + + let ipc_handler = move |req: Request| { + let body = req.body(); + match body.as_str() { + "print" => { + let _ = proxy.send_event(UserEvent::Print); + } + _ => {} + } + }; + + let webview = builder + .with_html( + r#" + + "#, + ) + .with_ipc_handler(ipc_handler) + .build()?; + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + + match event { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => *control_flow = ControlFlow::Exit, + Event::UserEvent(UserEvent::Print) => { + #[cfg(target_os = "macos")] + { + use wry::{PrintOptions, WebViewExtMacOS}; + + let print_options = PrintOptions { + margins: wry::PrintMargin { + top: 20.0, + right: 0.0, + bottom: 0.0, + left: 20.0, + }, + }; + + webview.print_with_options(&print_options).unwrap(); + } + + #[cfg(not(target_os = "macos"))] + webview.print().unwrap(); + } + _ => {} + } + }); +} diff --git a/src/lib.rs b/src/lib.rs index 49634791c..42c514b18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -232,6 +232,8 @@ use webkitgtk::*; pub(crate) mod wkwebview; #[cfg(any(target_os = "macos", target_os = "ios"))] use wkwebview::*; +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub use wkwebview::{PrintOptions, PrintMargin}; #[cfg(target_os = "windows")] pub(crate) mod webview2; @@ -1598,6 +1600,8 @@ pub trait WebViewExtMacOS { fn ns_window(&self) -> cocoa::base::id; /// Attaches this webview to the given NSWindow and removes it from the current one. fn reparent(&self, window: cocoa::base::id) -> Result<()>; + // Prints with extra options + fn print_with_options(&self, options: &PrintOptions) -> Result<()>; } #[cfg(target_os = "macos")] @@ -1620,6 +1624,10 @@ impl WebViewExtMacOS for WebView { fn reparent(&self, window: cocoa::base::id) -> Result<()> { self.webview.reparent(window) } + + fn print_with_options(&self, options: &PrintOptions) -> Result<()> { + self.webview.print_with_options(options) + } } /// Additional methods on `WebView` that are specific to iOS. diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 31a434728..6aad1caa8 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -33,6 +33,8 @@ use std::{ }; use core_graphics::geometry::{CGPoint, CGRect, CGSize}; +use core_graphics::base::CGFloat; + use objc::{ declare::ClassDecl, runtime::{Class, Object, Sel, BOOL}, @@ -79,6 +81,30 @@ const NS_JSON_WRITING_FRAGMENTS_ALLOWED: u64 = 4; static COUNTER: Counter = Counter::new(); static WEBVIEW_IDS: Lazy>> = Lazy::new(Default::default); +#[derive(Debug)] +pub struct PrintMargin { + pub top: f32, + pub right: f32, + pub bottom: f32, + pub left: f32, +} + +impl Default for PrintMargin { + fn default() -> Self { + PrintMargin { + top: 0.0, + right: 0.0, + bottom: 0.0, + left: 0.0, + } + } +} + +#[derive(Debug, Default)] +pub struct PrintOptions { + pub margins: PrintMargin, +} + pub(crate) struct InnerWebView { pub webview: id, pub manager: id, @@ -1122,6 +1148,10 @@ r#"Object.defineProperty(window, 'ipc', { } pub fn print(&self) -> crate::Result<()> { + self.print_with_options(&PrintOptions::default()) + } + + pub fn print_with_options(&self, options: &PrintOptions) -> crate::Result<()> { // Safety: objc runtime calls are unsafe #[cfg(target_os = "macos")] unsafe { @@ -1133,6 +1163,10 @@ r#"Object.defineProperty(window, 'ipc', { // Create a shared print info let print_info: id = msg_send![class!(NSPrintInfo), sharedPrintInfo]; let print_info: id = msg_send![print_info, init]; + let () = msg_send![print_info, setTopMargin:CGFloat::from(options.margins.top)]; + let () = msg_send![print_info, setRightMargin:CGFloat::from(options.margins.right)]; + let () = msg_send![print_info, setBottomMargin:CGFloat::from(options.margins.bottom)]; + let () = msg_send![print_info, setLeftMargin:CGFloat::from(options.margins.left)]; // Create new print operation from the webview content let print_operation: id = msg_send![self.webview, printOperationWithPrintInfo: print_info]; // Allow the modal to detach from the current thread and be non-blocker From a18a76f64cd3c3959578d1917728209db60d2e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Mon, 13 May 2024 07:48:10 +0200 Subject: [PATCH 2/8] lint: apply cargo fmt --- examples/print.rs | 22 +++++++++++----------- src/lib.rs | 8 ++++---- src/wkwebview/mod.rs | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/print.rs b/examples/print.rs index 2ef316fa8..c2d6c0d0e 100644 --- a/examples/print.rs +++ b/examples/print.rs @@ -70,18 +70,18 @@ fn main() -> wry::Result<()> { Event::UserEvent(UserEvent::Print) => { #[cfg(target_os = "macos")] { - use wry::{PrintOptions, WebViewExtMacOS}; - - let print_options = PrintOptions { - margins: wry::PrintMargin { - top: 20.0, - right: 0.0, - bottom: 0.0, - left: 20.0, - }, - }; + use wry::{PrintOptions, WebViewExtMacOS}; - webview.print_with_options(&print_options).unwrap(); + let print_options = PrintOptions { + margins: wry::PrintMargin { + top: 20.0, + right: 0.0, + bottom: 0.0, + left: 20.0, + }, + }; + + webview.print_with_options(&print_options).unwrap(); } #[cfg(not(target_os = "macos"))] diff --git a/src/lib.rs b/src/lib.rs index 42c514b18..244e514ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -233,7 +233,7 @@ pub(crate) mod wkwebview; #[cfg(any(target_os = "macos", target_os = "ios"))] use wkwebview::*; #[cfg(any(target_os = "macos", target_os = "ios"))] -pub use wkwebview::{PrintOptions, PrintMargin}; +pub use wkwebview::{PrintMargin, PrintOptions}; #[cfg(target_os = "windows")] pub(crate) mod webview2; @@ -1624,10 +1624,10 @@ impl WebViewExtMacOS for WebView { fn reparent(&self, window: cocoa::base::id) -> Result<()> { self.webview.reparent(window) } - + fn print_with_options(&self, options: &PrintOptions) -> Result<()> { - self.webview.print_with_options(options) - } + self.webview.print_with_options(options) + } } /// Additional methods on `WebView` that are specific to iOS. diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 6aad1caa8..da8dd9883 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -32,8 +32,8 @@ use std::{ sync::{Arc, Mutex}, }; -use core_graphics::geometry::{CGPoint, CGRect, CGSize}; use core_graphics::base::CGFloat; +use core_graphics::geometry::{CGPoint, CGRect, CGSize}; use objc::{ declare::ClassDecl, @@ -86,7 +86,7 @@ pub struct PrintMargin { pub top: f32, pub right: f32, pub bottom: f32, - pub left: f32, + pub left: f32, } impl Default for PrintMargin { From b6bf4bfbad84e75cca9031b69e4e692de8708b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Mon, 13 May 2024 07:54:42 +0200 Subject: [PATCH 3/8] docs: add changelog --- .changes/macos_print_options.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changes/macos_print_options.md diff --git a/.changes/macos_print_options.md b/.changes/macos_print_options.md new file mode 100644 index 000000000..f88c442f2 --- /dev/null +++ b/.changes/macos_print_options.md @@ -0,0 +1,8 @@ +--- +"wry": minor +--- + +Default the margin when printing on MacOS to 0 so it is closer to the behavior +of when printing on the web. It also add a new function to WebViewExtMacOS +called print_with_options which allows the user to modify the margins that +will be sent down to the AppKit print operation (NSPrintInfo). \ No newline at end of file From 921d297ecf288bfbfdeb2d09c338cd845fa0bc6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Tue, 14 May 2024 08:11:35 +0200 Subject: [PATCH 4/8] refactor: remove print example --- examples/print.rs | 93 ----------------------------------------------- 1 file changed, 93 deletions(-) delete mode 100644 examples/print.rs diff --git a/examples/print.rs b/examples/print.rs deleted file mode 100644 index c2d6c0d0e..000000000 --- a/examples/print.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2020-2024 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use tao::{ - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoopBuilder}, - window::WindowBuilder, -}; -use wry::http::Request; -use wry::WebViewBuilder; - -enum UserEvent { - Print, -} - -fn main() -> wry::Result<()> { - let event_loop = EventLoopBuilder::::with_user_event().build(); - let proxy = event_loop.create_proxy(); - let window = WindowBuilder::new().build(&event_loop).unwrap(); - - #[cfg(any( - target_os = "windows", - target_os = "macos", - target_os = "ios", - target_os = "android" - ))] - let builder = WebViewBuilder::new(&window); - - #[cfg(not(any( - target_os = "windows", - target_os = "macos", - target_os = "ios", - target_os = "android" - )))] - let builder = { - use tao::platform::unix::WindowExtUnix; - use wry::WebViewBuilderExtUnix; - let vbox = window.default_vbox().unwrap(); - WebViewBuilder::new_gtk(vbox) - }; - - let ipc_handler = move |req: Request| { - let body = req.body(); - match body.as_str() { - "print" => { - let _ = proxy.send_event(UserEvent::Print); - } - _ => {} - } - }; - - let webview = builder - .with_html( - r#" - - "#, - ) - .with_ipc_handler(ipc_handler) - .build()?; - - event_loop.run(move |event, _, control_flow| { - *control_flow = ControlFlow::Wait; - - match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => *control_flow = ControlFlow::Exit, - Event::UserEvent(UserEvent::Print) => { - #[cfg(target_os = "macos")] - { - use wry::{PrintOptions, WebViewExtMacOS}; - - let print_options = PrintOptions { - margins: wry::PrintMargin { - top: 20.0, - right: 0.0, - bottom: 0.0, - left: 20.0, - }, - }; - - webview.print_with_options(&print_options).unwrap(); - } - - #[cfg(not(target_os = "macos"))] - webview.print().unwrap(); - } - _ => {} - } - }); -} From 2a08ba857c5221c1c198f49c6762c9be27d65d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Tue, 14 May 2024 08:21:24 +0200 Subject: [PATCH 5/8] refactor: split changelog into different files --- .changes/macos_default_print_margins.md | 6 ++++++ .changes/macos_print_margin_options.md | 6 ++++++ .changes/macos_print_options.md | 8 -------- 3 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 .changes/macos_default_print_margins.md create mode 100644 .changes/macos_print_margin_options.md delete mode 100644 .changes/macos_print_options.md diff --git a/.changes/macos_default_print_margins.md b/.changes/macos_default_print_margins.md new file mode 100644 index 000000000..dc376f824 --- /dev/null +++ b/.changes/macos_default_print_margins.md @@ -0,0 +1,6 @@ +--- +"wry": minor +--- + +Default the margin when printing on MacOS to 0 so it is closer to the behavior +of when printing on the web. \ No newline at end of file diff --git a/.changes/macos_print_margin_options.md b/.changes/macos_print_margin_options.md new file mode 100644 index 000000000..3fd7250e5 --- /dev/null +++ b/.changes/macos_print_margin_options.md @@ -0,0 +1,6 @@ +--- +"wry": minor +--- + +Add a new function to WebViewExtMacOS called print_with_options which +allows the user to modify the margins that will be sent down to the AppKit print operation (NSPrintInfo). \ No newline at end of file diff --git a/.changes/macos_print_options.md b/.changes/macos_print_options.md deleted file mode 100644 index f88c442f2..000000000 --- a/.changes/macos_print_options.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"wry": minor ---- - -Default the margin when printing on MacOS to 0 so it is closer to the behavior -of when printing on the web. It also add a new function to WebViewExtMacOS -called print_with_options which allows the user to modify the margins that -will be sent down to the AppKit print operation (NSPrintInfo). \ No newline at end of file From ca1ac37fc3ef8d4c4b31fe89dc0c22c56caed710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Tue, 14 May 2024 08:22:46 +0200 Subject: [PATCH 6/8] refactor: derive Default, Clone and Copy for PrintMargin --- src/wkwebview/mod.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index da8dd9883..3c6b73ef3 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -81,7 +81,7 @@ const NS_JSON_WRITING_FRAGMENTS_ALLOWED: u64 = 4; static COUNTER: Counter = Counter::new(); static WEBVIEW_IDS: Lazy>> = Lazy::new(Default::default); -#[derive(Debug)] +#[derive(Debug, Default, Copy, Clone)] pub struct PrintMargin { pub top: f32, pub right: f32, @@ -89,17 +89,6 @@ pub struct PrintMargin { pub left: f32, } -impl Default for PrintMargin { - fn default() -> Self { - PrintMargin { - top: 0.0, - right: 0.0, - bottom: 0.0, - left: 0.0, - } - } -} - #[derive(Debug, Default)] pub struct PrintOptions { pub margins: PrintMargin, From 3868f6522fb6d7f8ba07b644470e642a4e34b447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Augusto=20C=C3=A9sar?= Date: Tue, 14 May 2024 08:25:46 +0200 Subject: [PATCH 7/8] refactor: derive Clone for PrintOptions --- src/wkwebview/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 3c6b73ef3..50ba5fbdb 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -89,7 +89,7 @@ pub struct PrintMargin { pub left: f32, } -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct PrintOptions { pub margins: PrintMargin, } From f4342d042d4505d3a77150257fa6b963505951ba Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 14 May 2024 17:49:24 +0300 Subject: [PATCH 8/8] Apply suggestions from code review --- .changes/macos_default_print_margins.md | 3 +-- .changes/macos_print_margin_options.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.changes/macos_default_print_margins.md b/.changes/macos_default_print_margins.md index dc376f824..ba5fd2723 100644 --- a/.changes/macos_default_print_margins.md +++ b/.changes/macos_default_print_margins.md @@ -2,5 +2,4 @@ "wry": minor --- -Default the margin when printing on MacOS to 0 so it is closer to the behavior -of when printing on the web. \ No newline at end of file +Default the margin when printing on MacOS to 0 so it is closer to the behavior of when printing on the web. \ No newline at end of file diff --git a/.changes/macos_print_margin_options.md b/.changes/macos_print_margin_options.md index 3fd7250e5..e2ed47988 100644 --- a/.changes/macos_print_margin_options.md +++ b/.changes/macos_print_margin_options.md @@ -2,5 +2,4 @@ "wry": minor --- -Add a new function to WebViewExtMacOS called print_with_options which -allows the user to modify the margins that will be sent down to the AppKit print operation (NSPrintInfo). \ No newline at end of file +Add `WebViewExtMacOS::print_with_options` which allows to modify the margins that will be used on the print dialog. \ No newline at end of file