Merge pull request #8487 from leethomas/feature/osx-relative-window-levels

Feature/macOS relative window levels
This commit is contained in:
Kevin Sawicki 2017-01-30 15:34:24 -08:00 committed by GitHub
commit dc1c11a841
8 changed files with 49 additions and 8 deletions

View file

@ -512,8 +512,17 @@ bool Window::IsClosable() {
void Window::SetAlwaysOnTop(bool top, mate::Arguments* args) { void Window::SetAlwaysOnTop(bool top, mate::Arguments* args) {
std::string level = "floating"; std::string level = "floating";
int relativeLevel = 0;
std::string error;
args->GetNext(&level); args->GetNext(&level);
window_->SetAlwaysOnTop(top, level); args->GetNext(&relativeLevel);
window_->SetAlwaysOnTop(top, level, relativeLevel, &error);
if (!error.empty()) {
args->ThrowError(error);
}
} }
bool Window::IsAlwaysOnTop() { bool Window::IsAlwaysOnTop() {

View file

@ -119,7 +119,9 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetClosable(bool closable) = 0; virtual void SetClosable(bool closable) = 0;
virtual bool IsClosable() = 0; virtual bool IsClosable() = 0;
virtual void SetAlwaysOnTop(bool top, virtual void SetAlwaysOnTop(bool top,
const std::string& level = "floating") = 0; const std::string& level = "floating",
int relativeLevel = 0,
std::string* error = nullptr) = 0;
virtual bool IsAlwaysOnTop() = 0; virtual bool IsAlwaysOnTop() = 0;
virtual void Center() = 0; virtual void Center() = 0;
virtual void SetTitle(const std::string& title) = 0; virtual void SetTitle(const std::string& title) = 0;

View file

@ -67,7 +67,8 @@ class NativeWindowMac : public NativeWindow,
bool IsFullScreenable() override; bool IsFullScreenable() override;
void SetClosable(bool closable) override; void SetClosable(bool closable) override;
bool IsClosable() override; bool IsClosable() override;
void SetAlwaysOnTop(bool top, const std::string& level) override; void SetAlwaysOnTop(bool top, const std::string& level,
int relativeLevel, std::string* error) override;
bool IsAlwaysOnTop() override; bool IsAlwaysOnTop() override;
void Center() override; void Center() override;
void SetTitle(const std::string& title) override; void SetTitle(const std::string& title) override;

View file

@ -1056,8 +1056,12 @@ bool NativeWindowMac::IsClosable() {
return [window_ styleMask] & NSClosableWindowMask; return [window_ styleMask] & NSClosableWindowMask;
} }
void NativeWindowMac::SetAlwaysOnTop(bool top, const std::string& level) { void NativeWindowMac::SetAlwaysOnTop(bool top, const std::string& level,
int relativeLevel, std::string* error) {
int windowLevel = NSNormalWindowLevel; int windowLevel = NSNormalWindowLevel;
CGWindowLevel maxWindowLevel = CGWindowLevelForKey(kCGMaximumWindowLevelKey);
CGWindowLevel minWindowLevel = CGWindowLevelForKey(kCGMinimumWindowLevelKey);
if (top) { if (top) {
if (level == "floating") { if (level == "floating") {
windowLevel = NSFloatingWindowLevel; windowLevel = NSFloatingWindowLevel;
@ -1078,7 +1082,15 @@ void NativeWindowMac::SetAlwaysOnTop(bool top, const std::string& level) {
windowLevel = NSDockWindowLevel; windowLevel = NSDockWindowLevel;
} }
} }
[window_ setLevel:windowLevel];
NSInteger newLevel = windowLevel + relativeLevel;
if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {
[window_ setLevel:newLevel];
} else {
*error = std::string([[NSString stringWithFormat:
@"relativeLevel must be between %d and %d", minWindowLevel,
maxWindowLevel] UTF8String]);
}
} }
bool NativeWindowMac::IsAlwaysOnTop() { bool NativeWindowMac::IsAlwaysOnTop() {

View file

@ -682,7 +682,8 @@ bool NativeWindowViews::IsClosable() {
#endif #endif
} }
void NativeWindowViews::SetAlwaysOnTop(bool top, const std::string& level) { void NativeWindowViews::SetAlwaysOnTop(bool top, const std::string& level,
int relativeLevel, std::string* error) {
window_->SetAlwaysOnTop(top); window_->SetAlwaysOnTop(top);
} }

View file

@ -86,7 +86,8 @@ class NativeWindowViews : public NativeWindow,
bool IsFullScreenable() override; bool IsFullScreenable() override;
void SetClosable(bool closable) override; void SetClosable(bool closable) override;
bool IsClosable() override; bool IsClosable() override;
void SetAlwaysOnTop(bool top, const std::string& level) override; void SetAlwaysOnTop(bool top, const std::string& level,
int relativeLevel, std::string* error) override;
bool IsAlwaysOnTop() override; bool IsAlwaysOnTop() override;
void Center() override; void Center() override;
void SetTitle(const std::string& title) override; void SetTitle(const std::string& title) override;

View file

@ -846,13 +846,16 @@ Returns `Boolean` - Whether the window can be manually closed by user.
On Linux always returns `true`. On Linux always returns `true`.
#### `win.setAlwaysOnTop(flag[, level])` #### `win.setAlwaysOnTop(flag[, level][, relativeLevel])`
* `flag` Boolean * `flag` Boolean
* `level` String (optional) _macOS_ - Values include `normal`, `floating`, * `level` String (optional) _macOS_ - Values include `normal`, `floating`,
`torn-off-menu`, `modal-panel`, `main-menu`, `status`, `pop-up-menu`, `torn-off-menu`, `modal-panel`, `main-menu`, `status`, `pop-up-menu`,
`screen-saver`, and ~~`dock`~~ (Deprecated). The default is `floating`. See the `screen-saver`, and ~~`dock`~~ (Deprecated). The default is `floating`. See the
[macOS docs][window-levels] for more details. [macOS docs][window-levels] for more details.
* `relativeLevel` Integer (optional) _macOS_ - The number of layers higher to set
this window relative to the given `level`. The default is `0`. Note that Apple
discourages setting levels higher than 1 above `screen-saver`.
Sets whether the window should show always on top of other windows. After Sets whether the window should show always on top of other windows. After
setting this, the window is still a normal window, not a toolbox window which setting this, the window is still a normal window, not a toolbox window which

View file

@ -524,6 +524,18 @@ describe('BrowserWindow module', function () {
w.setAlwaysOnTop(true) w.setAlwaysOnTop(true)
assert.equal(w.isAlwaysOnTop(), true) assert.equal(w.isAlwaysOnTop(), true)
}) })
it('raises an error when relativeLevel is out of bounds', function () {
if (process.platform !== 'darwin') return
assert.throws(function () {
w.setAlwaysOnTop(true, '', -2147483644)
})
assert.throws(function () {
w.setAlwaysOnTop(true, '', 2147483632)
})
})
}) })
describe('BrowserWindow.setAutoHideCursor(autoHide)', () => { describe('BrowserWindow.setAutoHideCursor(autoHide)', () => {