Browse Source

Implements #2734 “New API to configure BrowserWindow title bar on Mac”

New API supported on Yosemite 10.10 and newer.
jaanus 9 years ago
parent
commit
5d8f1dd404

+ 25 - 0
atom/browser/native_window_mac.mm

@@ -357,6 +357,17 @@ NativeWindowMac::NativeWindowMac(
     styleMask |= NSTexturedBackgroundWindowMask;
   }
 
+  std::string titleBarStyle = "default";
+  options.Get(switches::kTitleBarStyle, &titleBarStyle);
+
+  if (base::mac::IsOSYosemiteOrLater()) {
+    // New title bar styles are available in Yosemite or newer
+    if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
+      styleMask |= NSFullSizeContentViewWindowMask;
+      styleMask |= NSUnifiedTitleAndToolbarWindowMask;
+    }
+  }
+
   window_.reset([[AtomNSWindow alloc]
       initWithContentRect:cocoa_bounds
                 styleMask:styleMask
@@ -382,6 +393,20 @@ NativeWindowMac::NativeWindowMac(
   // We will manage window's lifetime ourselves.
   [window_ setReleasedWhenClosed:NO];
 
+  // Configure title bar look on Yosemite or newer
+  if (base::mac::IsOSYosemiteOrLater()) {
+    if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
+      [window_ setTitlebarAppearsTransparent:YES];
+      [window_ setTitleVisibility:NSWindowTitleHidden];
+      if (titleBarStyle == "hidden-inset") {
+        NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"];
+        toolbar.showsBaselineSeparator = NO;
+        [window_ setToolbar:toolbar];
+        [toolbar release];
+      }
+    }
+  }
+
   // On OS X the initial window size doesn't include window frame.
   bool use_content_size = false;
   options.Get(switches::kUseContentSize, &use_content_size);

+ 3 - 0
atom/common/options_switches.cc

@@ -42,6 +42,9 @@ const char kAcceptFirstMouse[] = "accept-first-mouse";
 // Whether window size should include window frame.
 const char kUseContentSize[] = "use-content-size";
 
+// The requested title bar style for the window
+const char kTitleBarStyle[] = "title-bar-style";
+
 // The WebPreferences.
 const char kWebPreferences[] = "web-preferences";
 

+ 1 - 0
atom/common/options_switches.h

@@ -30,6 +30,7 @@ extern const char kAlwaysOnTop[];
 extern const char kNodeIntegration[];
 extern const char kAcceptFirstMouse[];
 extern const char kUseContentSize[];
+extern const char kTitleBarStyle[];
 extern const char kWebPreferences[];
 extern const char kZoomFactor[];
 extern const char kAutoHideMenuBar[];

+ 10 - 0
docs/api/browser-window.md

@@ -70,6 +70,16 @@ Properties `width` and `height` are required.
   Linux.
 * `standard-window` Boolean - Uses the OS X's standard window instead of the
   textured window. Defaults to `true`.
+* `title-bar-style` String, OS X - specifies the style of window title bar.
+  This option is supported on OS X 10.10 Yosemite and newer. There are three
+  possible values:
+  * `default` or not specified results in the standard gray opaque Mac title
+  bar.
+  * `hidden` results in a hidden title bar and a full size content window, yet
+  the title bar still has the standard window controls ("traffic lights") in
+  the top left.
+  * `hidden-inset` results in a hidden title bar with an alternative look
+  where the traffic light buttons are slightly more inset from the window edge.
 * `web-preferences` Object - Settings of web page's features, properties:
   * `node-integration` Boolean - Whether node integration is enabled. Default
     is `true`.

+ 14 - 0
docs/api/frameless-window.md

@@ -13,6 +13,20 @@ var BrowserWindow = require('browser-window');
 var win = new BrowserWindow({ width: 800, height: 600, frame: false });
 ```
 
+### Alternatives on Mac
+
+On Mac OS X 10.10 Yosemite and newer, there's an alternative way to specify
+a chromeless window. Instead of setting `frame` to `false` which disables
+both the titlebar and window controls, you may want to have the title bar
+hidden and your content extend to the full window size, yet still preserve
+the window controls ("traffic lights") for standard window actions.
+You can do so by specifying the new `title-bar-style` option:
+
+```javascript
+var BrowserWindow = require('browser-window');
+var win = new BrowserWindow({ width: 800, height: 600, 'title-bar-style': 'hidden' });
+```
+
 ## Transparent window
 
 By setting the `transparent` option to `true`, you can also make the frameless

+ 17 - 0
spec/api-browser-window-spec.coffee

@@ -4,6 +4,7 @@ path   = require 'path'
 remote = require 'remote'
 http   = require 'http'
 url    = require 'url'
+os     = require 'os'
 
 BrowserWindow = remote.require 'browser-window'
 
@@ -160,6 +161,22 @@ describe 'browser-window module', ->
       assert.equal size[0], 400
       assert.equal size[1], 400
 
+  describe '"title-bar-style" option', ->
+    return if process.platform isnt 'darwin'
+    return if parseInt(os.release().split('.')[0]) < 14 # only run these tests on Yosemite or newer
+
+    it 'creates browser window with hidden title bar', ->
+      w.destroy()
+      w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': 'hidden')
+      contentSize = w.getContentSize()
+      assert.equal contentSize[1], 400
+
+    it 'creates browser window with hidden inset title bar', ->
+      w.destroy()
+      w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': 'hidden-inset')
+      contentSize = w.getContentSize()
+      assert.equal contentSize[1], 400
+
   describe '"enable-larger-than-screen" option', ->
     return if process.platform is 'linux'