Skip to content

Commit

Permalink
Add Window.SetVisibleOnAllWorkspaces API
Browse files Browse the repository at this point in the history
For platforms that support multiple workspaces (currently Mac and Linux), this allows node-webkit windows to be visible on all workspaces simultaneously.

- Add `SetVisibleOnAllWorkspaces` method to the `Window` API object.
- Add implementation for Mac OS X.
- Add implementation for Aura (Linux).
- Add configuration support via boolean `'window'` subfield `'visible-on-all-workspaces'` in manifest file (see https://github.com/rogerwang/node-webkit/wiki/Manifest-format#window-subfields ).
- Add manual test for `SetVisibleOnAllWorkspaces` method to the `Window` API object.

see nwjs#2523
  • Loading branch information
mrfabbri committed Nov 28, 2014
1 parent 75b7950 commit 06c52ce
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/api/window/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ void Window::Call(const std::string& method,
bool show;
if (arguments.GetBoolean(0, &show))
shell_->window()->SetShowInTaskbar(show);
} else if (method == "SetVisibleOnAllWorkspaces") {
bool all_workspaces;
if (arguments.GetBoolean(0, &all_workspaces))
shell_->window()->SetVisibleOnAllWorkspaces(all_workspaces);
} else if (method == "MoveTo") {
int x, y;
if (arguments.GetInteger(0, &x) &&
Expand Down
4 changes: 4 additions & 0 deletions src/api/window_bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@ Window.prototype.setShowInTaskbar = function(flag) {
CallObjectMethod(this, 'SetShowInTaskbar', [ flag ]);
}

Window.prototype.setVisibleOnAllWorkspaces = function(flag) {
CallObjectMethod(this, 'SetVisibleOnAllWorkspaces', [ Boolean(flag) ]);
}

Window.prototype.requestAttention = function(flash) {
if (typeof flash == 'boolean') {
// boolean true is redirected as -1 value
Expand Down
5 changes: 5 additions & 0 deletions src/browser/native_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ void NativeWindow::InitFromManifest(base::DictionaryValue* manifest) {
!showInTaskbar) {
SetShowInTaskbar(false);
}
bool all_workspaces;
if (manifest->GetBoolean(switches::kmVisibleOnAllWorkspaces, &all_workspaces)
&& all_workspaces) {
SetVisibleOnAllWorkspaces(true);
}
bool fullscreen;
if (manifest->GetBoolean(switches::kmFullscreen, &fullscreen) && fullscreen) {
SetFullscreen(true);
Expand Down
1 change: 1 addition & 0 deletions src/browser/native_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class NativeWindow {
virtual void SetResizable(bool resizable) = 0;
virtual void SetAlwaysOnTop(bool top) = 0;
virtual void SetShowInTaskbar(bool show = true) = 0;
virtual void SetVisibleOnAllWorkspaces(bool all_workspaces) = 0;
virtual void SetPosition(const std::string& position) = 0;
virtual void SetPosition(const gfx::Point& position) = 0;
virtual gfx::Point GetPosition() = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/browser/native_window_aura.cc
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,10 @@ void NativeWindowAura::SetAlwaysOnTop(bool top) {
window_->SetAlwaysOnTop(top);
}

void NativeWindowAura::SetVisibleOnAllWorkspaces(bool all_workspaces) {
window_->SetVisibleOnAllWorkspaces(all_workspaces);
}

void NativeWindowAura::OnWidgetActivationChanged(views::Widget* widget, bool active) {
if (active) {
if (shell())
Expand Down
1 change: 1 addition & 0 deletions src/browser/native_window_aura.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class NativeWindowAura : public NativeWindow,
virtual void SetResizable(bool resizable) OVERRIDE;
virtual void SetAlwaysOnTop(bool top) OVERRIDE;
virtual void SetShowInTaskbar(bool show = true) OVERRIDE;
virtual void SetVisibleOnAllWorkspaces(bool all_workspaces) OVERRIDE;
virtual void SetPosition(const std::string& position) OVERRIDE;
virtual void SetPosition(const gfx::Point& position) OVERRIDE;
virtual gfx::Point GetPosition() OVERRIDE;
Expand Down
1 change: 1 addition & 0 deletions src/browser/native_window_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class NativeWindowCocoa : public NativeWindow {
virtual void SetResizable(bool resizable) OVERRIDE;
virtual void SetAlwaysOnTop(bool top) OVERRIDE;
virtual void SetShowInTaskbar(bool show = true) OVERRIDE;
virtual void SetVisibleOnAllWorkspaces(bool all_workspaces) OVERRIDE;
virtual void SetPosition(const std::string& position) OVERRIDE;
virtual void SetPosition(const gfx::Point& position) OVERRIDE;
virtual gfx::Point GetPosition() OVERRIDE;
Expand Down
10 changes: 10 additions & 0 deletions src/browser/native_window_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,16 @@ - (void)drawRect:(NSRect)dirtyRect {
[window() setLevel:(top ? NSFloatingWindowLevel : NSNormalWindowLevel)];
}

void NativeWindowCocoa::SetVisibleOnAllWorkspaces(bool all_workspaces) {
NSUInteger collectionBehavior = [window() collectionBehavior];
if (all_workspaces) {
collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
} else {
collectionBehavior &= ~NSWindowCollectionBehaviorCanJoinAllSpaces;
}
[window() setCollectionBehavior:collectionBehavior];
}

void NativeWindowCocoa::SetShowInTaskbar(bool show) {
ProcessSerialNumber psn = { 0, kCurrentProcess };
if (!show) {
Expand Down
3 changes: 3 additions & 0 deletions src/common/shell_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ const char kmKiosk[] = "kiosk";
// Make windows stays on the top of all other windows.
const char kmAlwaysOnTop[] = "always-on-top";

// Make window visible on all workspaces.
const char kmVisibleOnAllWorkspaces[] = "visible-on-all-workspaces";

// Whether we should support WebGL.
const char kmWebgl[] = "webgl";

Expand Down
1 change: 1 addition & 0 deletions src/common/shell_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern const char kmFullscreen[];
extern const char kmShowInTaskbar[];
extern const char kmKiosk[];
extern const char kmAlwaysOnTop[];
extern const char kmVisibleOnAllWorkspaces[];
extern const char kmInitialFocus[];
extern const char kmTransparent[];
extern const char kmDisableTransparency[];
Expand Down
66 changes: 66 additions & 0 deletions tests/manual_tests/always_on_visible_workspace/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<html>
<head>
<title> Always on Visible Workspace Test - window #1 </title>
</head>
<body style="background-color:rgba(0,0,0,0);">
<div id="test-contents">
<h3>Window #1</h3>
<p>This window is <span id="workspaces_status">visible on all workspaces</span></p>
<div>
<a href="" id="visible-on-all-workspaces">Visible on all workspaces</a>
<p>Makes the window visible on all workspaces simultaneously.</p>
</div>
<div>
<a href="" id="only-on-this-desktop">Only on this workspace</a>
<p>Makes the window visible only on this workspace.</p>
</div>
<p id="output"></p>
</div>
<script>

var os = require('os');
if (/(darwin|linux)/.test(os.platform())) {
testSetVisibleOnAllWorkspaces();
} else {
notSupported();
}

function testSetVisibleOnAllWorkspaces() {
var gui = require('nw.gui');
var win = gui.Window.get();

function setVisibleOnAllWorkspaces(all_workspaces){
win.setVisibleOnAllWorkspaces(all_workspaces);

updateStatusText(all_workspaces);

document.getElementById("output").innerHTML +=
'called Window.setVisibleOnAllWorkspaces(' + all_workspaces + ');<br/>\n';
}

function updateStatusText(all_workspaces) {
var statusEl = document.getElementById('workspaces_status');
var statusText = all_workspaces ? 'visible on all workspaces' : 'visible only on this workspace';
statusEl.innerText = statusText;
}

updateStatusText(gui.App.manifest.window['visible-on-all-workspaces']);

document.getElementById('visible-on-all-workspaces').onclick = function (e) { setVisibleOnAllWorkspaces(true); e.preventDefault(); };
document.getElementById('only-on-this-desktop').onclick = function (e) { setVisibleOnAllWorkspaces(false); e.preventDefault(); };

gui.Window.open('./index2.html', {
position: 'center',
x: win.x+20,
y: win.y+20
});
}

function notSupported() {
document.getElementById('test-contents').innerHTML =
"Test not supported on this platform";
}

</script>
</body>
</html>
41 changes: 41 additions & 0 deletions tests/manual_tests/always_on_visible_workspace/index2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<html>
<head>
<title> Always on Visible Workspace Test - window #2 </title>
</head>
<body style="background-color:rgba(0,0,0,0);">
<h3>Window #2</h3>
<p>This window is <span id="workspaces_status">visible on all workspaces</span></p>
<div>
<a href="" id="visible-on-all-workspaces">Visible on all workspaces</a>
<p>Makes the window visible on all workspaces simultaneously.</p>
</div>
<div>
<a href="" id="only-on-this-desktop">Only on this workspace</a>
<p>Makes the window visible only on this workspace.</p>
</div>
<p id="output"></p>
<script>
var gui = require('nw.gui');
var win = gui.Window.get();

function setVisibleOnAllWorkspaces(all_workspaces){
win.setVisibleOnAllWorkspaces(all_workspaces);

updateStatusText(all_workspaces);

document.getElementById("output").innerHTML +=
'called Window.setVisibleOnAllWorkspaces(' + all_workspaces + ');<br/>\n';
}

function updateStatusText(all_workspaces) {
var statusEl = document.getElementById('workspaces_status');
var statusText = all_workspaces ? 'visible on all workspaces' : 'visible only on this workspace';
statusEl.innerText = statusText;
}

document.getElementById('visible-on-all-workspaces').onclick = function (e) { setVisibleOnAllWorkspaces(true); e.preventDefault(); };
document.getElementById('only-on-this-desktop').onclick = function (e) { setVisibleOnAllWorkspaces(false); e.preventDefault(); };

</script>
</body>
</html>
8 changes: 8 additions & 0 deletions tests/manual_tests/always_on_visible_workspace/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "nw-always-on-visible-workspace-test",
"main": "index.html",
"window": {
"always-on-visible-workspace": true
},
"dependencies": {}
}

0 comments on commit 06c52ce

Please sign in to comment.