summary history branches tags files
commit:e7e5ae4731cfa413cd670de45a5458bc58b9111b
author:Trevor Bentley
committer:GitHub
date:Wed Sep 30 22:33:12 2020 +0200
parents:d017e56db9ea857e7f971659f41d484cc9a57b9e, dd0816fedc8025c92f975adceed233b1aedabfa3
Merge pull request #24 from LoganDark/hidpi

HiDPI helper method
diff --git a/src/lib.rs b/src/lib.rs
line changes: +2/-0
index 49622df..cbd0825
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -221,6 +221,8 @@ impl Trampoline {
     /// Docs in OS X build.
     pub fn plist_keys(&mut self, _pairs: &Vec<(&str,&str)>) -> &mut Self { self }
     /// Docs in OS X build.
+    pub fn retina(&mut self, _doit: bool) -> &mut Self { self }
+    /// Docs in OS X build.
     pub fn plist_raw_string(&mut self, _s: String) -> &mut Self { self }
     /// Docs in OS X build.
     pub fn resource(&mut self, _file: &str) -> &mut Self { self }

diff --git a/src/osx.rs b/src/osx.rs
line changes: +61/-0
index cf77594..7bddbaa
--- a/src/osx.rs
+++ b/src/osx.rs
@@ -208,6 +208,7 @@ pub struct Trampoline {
     keys: Vec<(String,String)>,
     plist_raw_strings: Vec<String>,
     resources: Vec<String>,
+    hidpi: bool,
 }
 
 impl Trampoline {
@@ -245,6 +246,7 @@ impl Trampoline {
             exe: exe.to_string(),
             ident: ident.to_string(),
             version: "1.0.0".to_string(),
+            hidpi: true,
             ..
             Default::default()
         }
@@ -330,6 +332,59 @@ impl Trampoline {
         }
         self
     }
+    /// Sets whether fruitbasket should add properties to the generated plist
+    /// to tell macOS that this application supports high resolution displays.
+    ///
+    /// This option is true by default. A bit of backstory follows.
+    ///
+    /// ---
+    ///
+    /// macOS, by default, runs apps in a low-resolution mode if they are
+    /// in a bundle that does not specify that it supports Retina displays. This
+    /// causes them to look blurry on Retina displays, not crisp like the rest
+    /// of macOS.
+    ///
+    /// You may not have noticed this behavior when running GUI applications as
+    /// bare binaries, where it does not apply (macOS does not run binaries in
+    /// low-resolution mode). However, the Trampoline is different because it
+    /// automatically bundles the binary, which opens up the application to this
+    /// kind of legacy behavior.
+    ///
+    /// Historically, it was done for backwards compatibility, because when the
+    /// Retina screen came out in 2012, not all applications supported it.
+    /// Indeed, some programs even today don't support it either, which is why
+    /// this behavior remains. However, most GUI facilities like Qt, GTK and
+    /// libui support Retina just fine, and don't need macOS to sandbox them
+    /// into this low resolution mode. (libui doesn't even need to do anything
+    /// special; they use AppKit directly, which has always supported Retina.)
+    ///
+    /// Applications that wish to indicate that they *do* support Retina
+    /// displays have to specify two properties in their Info.plist:
+    /// - Set `NSPrincipalClass` to something. (`"NSApplication"` is a useful
+    ///   default, but it's unknown what the significance of this property is.
+    ///   fruitbasket uses `"NSApplication"`.)
+    /// - Set `NSHighResolutionCapable` to `True`.
+    ///
+    /// After this is done, macOS will run the app at full resolution and trust
+    /// it to scale its UI to match the scale factor of the resolution being
+    /// used. On most displays, it is 2 by default, but macOS supports both
+    /// larger and also non-integer scale factors.
+    ///
+    /// Sometimes you have to do this manually, such as when you are rendering
+    /// into a framebuffer, and sometimes you don't, like when you are using a
+    /// GUI toolkit. Usually, programmers can expect their libraries to support
+    /// this natively and that is why this option is enabled by default.
+    ///
+    /// Older versions of fruitbasket did not apply these changes by default,
+    /// which meant in the best case the developer had to look online for a
+    /// solution, and in the worst case apps built using fruitbasket ran in
+    /// low resolution (ouch!). It is my hope that this new default will help
+    /// both new and experienced developers alike, even though it is a somewhat
+    /// simple change.
+    pub fn retina(&mut self, doit: bool) -> &mut Self {
+        self.hidpi = doit;
+        self
+    }
     /// Add a 'raw', preformatted string to Info.plist
     ///
     /// Pastes a raw, unedited string into the Info.plist file.  This is
@@ -476,6 +531,12 @@ impl Trampoline {
             write!(&mut f, "  CFBundleIconFile = \"{}\";\n", self.icon)?;
             write!(&mut f, "  CFBundleVersion = \"{}\";\n", self.version)?;
 
+            // HiDPI fields
+            if self.hidpi {
+                write!(&mut f, "  NSPrincipalClass = \"NSApplication\";\n")?;
+                write!(&mut f, "  NSHighResolutionCapable = True;\n")?;
+            }
+
             // User-supplied fields
             for &(ref key, ref val) in &self.keys {
                 if !FORBIDDEN_PLIST.contains(&key.as_str()) {