Repository: tauri-apps/wry (language: rust)

Issue:
MacOS: window.print() margins and dialog options differ
**Describe the bug**
When printing using the window.print() method in the context of MacOS, page margins as well as dialog options differ from Safari. Margins are significantly larger and paper size and orientation options are absent.

**Steps To Reproduce**
Initialise Tauri Vanilla app, call window.print() method.

**Expected behavior**
Default margins and all options available.

**Screenshots**
![image](https://user-images.githubusercontent.com/5355771/193288074-114be90f-511c-49dd-8328-abe74b73cde8.png)
![image](https://user-images.githubusercontent.com/5355771/193288130-b3deadf5-143e-4342-a348-9944e385eaeb.png)


**Platform and Versions (please complete the following information):**
OS: macOS 12.6
Rustc: 1.57

**Would you assign yourself to resolve this bug?**
- [ ] Yes
- [x] No

**Additional context**
The @page rule is not implemented with Safari. Setting the printable area to "position: fixed;" and "top: 0; right: 0; left: 0;" does not influence the margins. Using negative inset will result in cutting the content off.




Discussion / hints:
Here's the discord convo about this because it goes further than that. The print dialog is also different from the Safari one and doesn't make it possible to change the margins: https://discord.com/channels/616186924390023171/731495028677148753/1025386181720023050

Fix patch:
diff --git a/.changes/macos_default_print_margins.md b/.changes/macos_default_print_margins.md
new file mode 100644
index 000000000..ba5fd2723
--- /dev/null
+++ b/.changes/macos_default_print_margins.md
@@ -0,0 +1,5 @@
+---
+"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..e2ed47988
--- /dev/null
+++ b/.changes/macos_print_margin_options.md
@@ -0,0 +1,5 @@
+---
+"wry": minor
+---
+
+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
diff --git a/src/lib.rs b/src/lib.rs
index 49634791c..244e514ec 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::{PrintMargin, PrintOptions};
 
 #[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..50ba5fbdb 100644
--- a/src/wkwebview/mod.rs
+++ b/src/wkwebview/mod.rs
@@ -32,7 +32,9 @@ use std::{
   sync::{Arc, Mutex},
 };
 
+use core_graphics::base::CGFloat;
 use core_graphics::geometry::{CGPoint, CGRect, CGSize};
+
 use objc::{
   declare::ClassDecl,
   runtime::{Class, Object, Sel, BOOL},
@@ -79,6 +81,19 @@ const NS_JSON_WRITING_FRAGMENTS_ALLOWED: u64 = 4;
 static COUNTER: Counter = Counter::new();
 static WEBVIEW_IDS: Lazy<Mutex<HashSet<u32>>> = Lazy::new(Default::default);
 
+#[derive(Debug, Default, Copy, Clone)]
+pub struct PrintMargin {
+  pub top: f32,
+  pub right: f32,
+  pub bottom: f32,
+  pub left: f32,
+}
+
+#[derive(Debug, Default, Clone)]
+pub struct PrintOptions {
+  pub margins: PrintMargin,
+}
+
 pub(crate) struct InnerWebView {
   pub webview: id,
   pub manager: id,
@@ -1122,6 +1137,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 +1152,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


Test patch: