Skip to content

Commit 0d9a031

Browse files
committed
Merge pull request nwjs#2722 from mrfabbri/fix-2523
Add Window.setVisibleOnAllWorkspaces API
2 parents f29cd19 + 07e5576 commit 0d9a031

File tree

14 files changed

+159
-0
lines changed

14 files changed

+159
-0
lines changed

src/api/window/window.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ void Window::Call(const std::string& method,
255255
bool show;
256256
if (arguments.GetBoolean(0, &show))
257257
shell_->window()->SetShowInTaskbar(show);
258+
} else if (method == "SetVisibleOnAllWorkspaces") {
259+
bool all_workspaces;
260+
if (arguments.GetBoolean(0, &all_workspaces))
261+
shell_->window()->SetVisibleOnAllWorkspaces(all_workspaces);
258262
} else if (method == "MoveTo") {
259263
int x, y;
260264
if (arguments.GetInteger(0, &x) &&

src/api/window/window.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1919
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2020

21+
// OS X and Linux only, Windows does not have a concept of workspaces
22+
var canSetVisibleOnAllWorkspaces = /(darwin|linux)/.test(require('os').platform());
23+
2124
exports.Window = {
2225
get: function(other) {
2326
// Return other window.
@@ -66,5 +69,8 @@ exports.Window = {
6669
var routing_id = nw.createShell(url, options);
6770

6871
return new global.Window(routing_id, true, id);
72+
},
73+
canSetVisibleOnAllWorkspaces: function() {
74+
return canSetVisibleOnAllWorkspaces;
6975
}
7076
};

src/api/window_bindings.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,10 @@ Window.prototype.setShowInTaskbar = function(flag) {
412412
CallObjectMethod(this, 'SetShowInTaskbar', [ flag ]);
413413
}
414414

415+
Window.prototype.setVisibleOnAllWorkspaces = function(flag) {
416+
CallObjectMethod(this, 'SetVisibleOnAllWorkspaces', [ Boolean(flag) ]);
417+
}
418+
415419
Window.prototype.requestAttention = function(flash) {
416420
if (typeof flash == 'boolean') {
417421
// boolean true is redirected as -1 value

src/browser/native_window.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ void NativeWindow::InitFromManifest(base::DictionaryValue* manifest) {
130130
!showInTaskbar) {
131131
SetShowInTaskbar(false);
132132
}
133+
bool all_workspaces;
134+
if (manifest->GetBoolean(switches::kmVisibleOnAllWorkspaces, &all_workspaces)
135+
&& all_workspaces) {
136+
SetVisibleOnAllWorkspaces(true);
137+
}
133138
bool fullscreen;
134139
if (manifest->GetBoolean(switches::kmFullscreen, &fullscreen) && fullscreen) {
135140
SetFullscreen(true);

src/browser/native_window.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class NativeWindow {
9696
virtual void SetResizable(bool resizable) = 0;
9797
virtual void SetAlwaysOnTop(bool top) = 0;
9898
virtual void SetShowInTaskbar(bool show = true) = 0;
99+
virtual void SetVisibleOnAllWorkspaces(bool all_workspaces) = 0;
99100
virtual void SetPosition(const std::string& position) = 0;
100101
virtual void SetPosition(const gfx::Point& position) = 0;
101102
virtual gfx::Point GetPosition() = 0;

src/browser/native_window_aura.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ NativeWindowAura::NativeWindowAura(const base::WeakPtr<content::Shell>& shell,
280280
toolbar_(NULL),
281281
web_view_(NULL),
282282
is_fullscreen_(false),
283+
is_visible_on_all_workspaces_(false),
283284
is_minimized_(false),
284285
is_maximized_(false),
285286
is_focus_(false),
@@ -293,6 +294,7 @@ NativeWindowAura::NativeWindowAura(const base::WeakPtr<content::Shell>& shell,
293294
manifest->GetBoolean("focus", &initial_focus_);
294295
manifest->GetBoolean("fullscreen", &is_fullscreen_);
295296
manifest->GetBoolean("resizable", &resizable_);
297+
manifest->GetBoolean("visible-on-all-workspaces", &is_visible_on_all_workspaces_);
296298

297299
window_ = new views::Widget;
298300
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
@@ -303,6 +305,7 @@ NativeWindowAura::NativeWindowAura(const base::WeakPtr<content::Shell>& shell,
303305
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
304306
if (is_fullscreen_)
305307
params.show_state = ui::SHOW_STATE_FULLSCREEN;
308+
params.visible_on_all_workspaces = is_visible_on_all_workspaces_;
306309
#if defined(OS_WIN)
307310
if (has_frame())
308311
window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_NATIVE);
@@ -565,6 +568,11 @@ void NativeWindowAura::SetAlwaysOnTop(bool top) {
565568
window_->SetAlwaysOnTop(top);
566569
}
567570

571+
void NativeWindowAura::SetVisibleOnAllWorkspaces(bool all_workspaces) {
572+
is_visible_on_all_workspaces_ = all_workspaces;
573+
window_->SetVisibleOnAllWorkspaces(all_workspaces);
574+
}
575+
568576
void NativeWindowAura::OnWidgetActivationChanged(views::Widget* widget, bool active) {
569577
if (active) {
570578
if (shell())

src/browser/native_window_aura.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class NativeWindowAura : public NativeWindow,
8686
virtual void SetResizable(bool resizable) OVERRIDE;
8787
virtual void SetAlwaysOnTop(bool top) OVERRIDE;
8888
virtual void SetShowInTaskbar(bool show = true) OVERRIDE;
89+
virtual void SetVisibleOnAllWorkspaces(bool all_workspaces) OVERRIDE;
8990
virtual void SetPosition(const std::string& position) OVERRIDE;
9091
virtual void SetPosition(const gfx::Point& position) OVERRIDE;
9192
virtual gfx::Point GetPosition() OVERRIDE;
@@ -181,6 +182,7 @@ class NativeWindowAura : public NativeWindow,
181182
views::WebView* web_view_;
182183
views::Widget* window_;
183184
bool is_fullscreen_;
185+
bool is_visible_on_all_workspaces_;
184186

185187
// Flags used to prevent sending extra events.
186188
bool is_minimized_;

src/browser/native_window_mac.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class NativeWindowCocoa : public NativeWindow {
6060
virtual void SetResizable(bool resizable) OVERRIDE;
6161
virtual void SetAlwaysOnTop(bool top) OVERRIDE;
6262
virtual void SetShowInTaskbar(bool show = true) OVERRIDE;
63+
virtual void SetVisibleOnAllWorkspaces(bool all_workspaces) OVERRIDE;
6364
virtual void SetPosition(const std::string& position) OVERRIDE;
6465
virtual void SetPosition(const gfx::Point& position) OVERRIDE;
6566
virtual gfx::Point GetPosition() OVERRIDE;

src/browser/native_window_mac.mm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,16 @@ - (void)drawRect:(NSRect)dirtyRect {
665665
[window() setLevel:(top ? NSFloatingWindowLevel : NSNormalWindowLevel)];
666666
}
667667

668+
void NativeWindowCocoa::SetVisibleOnAllWorkspaces(bool all_workspaces) {
669+
NSUInteger collectionBehavior = [window() collectionBehavior];
670+
if (all_workspaces) {
671+
collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
672+
} else {
673+
collectionBehavior &= ~NSWindowCollectionBehaviorCanJoinAllSpaces;
674+
}
675+
[window() setCollectionBehavior:collectionBehavior];
676+
}
677+
668678
void NativeWindowCocoa::SetShowInTaskbar(bool show) {
669679
ProcessSerialNumber psn = { 0, kCurrentProcess };
670680
if (!show) {

src/common/shell_switches.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ const char kmKiosk[] = "kiosk";
8585
// Make windows stays on the top of all other windows.
8686
const char kmAlwaysOnTop[] = "always-on-top";
8787

88+
// Make window visible on all workspaces.
89+
const char kmVisibleOnAllWorkspaces[] = "visible-on-all-workspaces";
90+
8891
// Whether we should support WebGL.
8992
const char kmWebgl[] = "webgl";
9093

src/common/shell_switches.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ extern const char kmFullscreen[];
5353
extern const char kmShowInTaskbar[];
5454
extern const char kmKiosk[];
5555
extern const char kmAlwaysOnTop[];
56+
extern const char kmVisibleOnAllWorkspaces[];
5657
extern const char kmInitialFocus[];
5758
extern const char kmTransparent[];
5859
extern const char kmDisableTransparency[];
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<html>
2+
<head>
3+
<title> Always on Visible Workspace Test - window #1 </title>
4+
</head>
5+
<body style="background-color:rgba(0,0,0,0);">
6+
<div id="test-contents">
7+
<h3>Window #1</h3>
8+
<p>This window is <span id="workspaces_status">visible only on this workspace</span></p>
9+
<div>
10+
<a href="" id="visible-on-all-workspaces">Visible on all workspaces</a>
11+
<p>Makes the window visible on all workspaces simultaneously.</p>
12+
</div>
13+
<div>
14+
<a href="" id="only-on-this-desktop">Only on this workspace</a>
15+
<p>Makes the window visible only on this workspace.</p>
16+
</div>
17+
<p id="output"></p>
18+
</div>
19+
<script>
20+
21+
if (Window.canSetVisibleOnAllWorkspaces()) {
22+
testSetVisibleOnAllWorkspaces();
23+
} else {
24+
notSupported();
25+
}
26+
27+
function testSetVisibleOnAllWorkspaces() {
28+
var gui = require('nw.gui');
29+
var win = gui.Window.get();
30+
31+
function setVisibleOnAllWorkspaces(all_workspaces){
32+
win.setVisibleOnAllWorkspaces(all_workspaces);
33+
34+
updateStatusText(all_workspaces);
35+
36+
document.getElementById("output").innerHTML +=
37+
'called Window.setVisibleOnAllWorkspaces(' + all_workspaces + ');<br/>\n';
38+
}
39+
40+
function updateStatusText(all_workspaces) {
41+
var statusEl = document.getElementById('workspaces_status');
42+
var statusText = all_workspaces ? 'visible on all workspaces' : 'visible only on this workspace';
43+
statusEl.innerText = statusText;
44+
}
45+
46+
updateStatusText(gui.App.manifest.window['visible-on-all-workspaces']);
47+
48+
document.getElementById('visible-on-all-workspaces').onclick = function (e) { setVisibleOnAllWorkspaces(true); e.preventDefault(); };
49+
document.getElementById('only-on-this-desktop').onclick = function (e) { setVisibleOnAllWorkspaces(false); e.preventDefault(); };
50+
51+
gui.Window.open('./index2.html', {
52+
position: 'center',
53+
x: win.x+20,
54+
y: win.y+20
55+
});
56+
}
57+
58+
function notSupported() {
59+
document.getElementById('test-contents').innerHTML =
60+
"Test not supported on this platform";
61+
}
62+
63+
</script>
64+
</body>
65+
</html>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<html>
2+
<head>
3+
<title> Always on Visible Workspace Test - window #2 </title>
4+
</head>
5+
<body style="background-color:rgba(0,0,0,0);">
6+
<h3>Window #2</h3>
7+
<p>This window is <span id="workspaces_status">visible only on this workspace</span></p>
8+
<div>
9+
<a href="" id="visible-on-all-workspaces">Visible on all workspaces</a>
10+
<p>Makes the window visible on all workspaces simultaneously.</p>
11+
</div>
12+
<div>
13+
<a href="" id="only-on-this-desktop">Only on this workspace</a>
14+
<p>Makes the window visible only on this workspace.</p>
15+
</div>
16+
<p id="output"></p>
17+
<script>
18+
var gui = require('nw.gui');
19+
var win = gui.Window.get();
20+
21+
function setVisibleOnAllWorkspaces(all_workspaces){
22+
win.setVisibleOnAllWorkspaces(all_workspaces);
23+
24+
updateStatusText(all_workspaces);
25+
26+
document.getElementById("output").innerHTML +=
27+
'called Window.setVisibleOnAllWorkspaces(' + all_workspaces + ');<br/>\n';
28+
}
29+
30+
function updateStatusText(all_workspaces) {
31+
var statusEl = document.getElementById('workspaces_status');
32+
var statusText = all_workspaces ? 'visible on all workspaces' : 'visible only on this workspace';
33+
statusEl.innerText = statusText;
34+
}
35+
36+
document.getElementById('visible-on-all-workspaces').onclick = function (e) { setVisibleOnAllWorkspaces(true); e.preventDefault(); };
37+
document.getElementById('only-on-this-desktop').onclick = function (e) { setVisibleOnAllWorkspaces(false); e.preventDefault(); };
38+
39+
</script>
40+
</body>
41+
</html>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "nw-always-on-visible-workspace-test",
3+
"main": "index.html",
4+
"window": {
5+
"visible-on-all-workspaces": true
6+
},
7+
"dependencies": {}
8+
}

0 commit comments

Comments
 (0)