Skip to content

Commit ce592a5

Browse files
trop[bot]codebytere
authored andcommitted
feat: allow setting window shape (backport: 3-0-x) (electron#14445)
* feat: allow setting window shape This binds Widget::SetShape, an API that already exists in Chromium (for Windows and Linux). It's a more reliable method of having some parts of your window be "click-through" than the current `setIgnoreMouseEvents` API, which messes around with the `WS_EX_LAYERED` window style on Windows, causing strange bugs and incompatibility with hardware acceleration. * update docs
1 parent 12087b7 commit ce592a5

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

atom/browser/api/atom_api_top_level_window.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,10 @@ double TopLevelWindow::GetOpacity() {
571571
return window_->GetOpacity();
572572
}
573573

574+
void TopLevelWindow::SetShape(const std::vector<gfx::Rect>& rects) {
575+
window_->widget()->SetShape(std::make_unique<std::vector<gfx::Rect>>(rects));
576+
}
577+
574578
void TopLevelWindow::SetRepresentedFilename(const std::string& filename) {
575579
window_->SetRepresentedFilename(filename);
576580
}
@@ -993,6 +997,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
993997
.SetMethod("hasShadow", &TopLevelWindow::HasShadow)
994998
.SetMethod("setOpacity", &TopLevelWindow::SetOpacity)
995999
.SetMethod("getOpacity", &TopLevelWindow::GetOpacity)
1000+
.SetMethod("setShape", &TopLevelWindow::SetShape)
9961001
.SetMethod("setRepresentedFilename",
9971002
&TopLevelWindow::SetRepresentedFilename)
9981003
.SetMethod("getRepresentedFilename",

atom/browser/api/atom_api_top_level_window.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
146146
bool HasShadow();
147147
void SetOpacity(const double opacity);
148148
double GetOpacity();
149+
void SetShape(const std::vector<gfx::Rect>& rects);
149150
void SetRepresentedFilename(const std::string& filename);
150151
std::string GetRepresentedFilename();
151152
void SetDocumentEdited(bool edited);

docs/api/browser-window.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,17 @@ Sets the opacity of the window. On Linux does nothing.
12641264

12651265
Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque)
12661266

1267+
#### `win.setShape(rects)` _Windows_ _Linux_ _Experimental_
1268+
1269+
* `rects` [Rectangle[]](structures/rectangle.md) - Sets a shape on the window.
1270+
Passing an empty list reverts the window to being rectangular.
1271+
1272+
Setting a window shape determines the area within the window where the system
1273+
permits drawing and user interaction. Outside of the given region, no pixels
1274+
will be drawn and no mouse events will be registered. Mouse events outside of
1275+
the region will not be received by that window, but will fall through to
1276+
whatever is behind the window.
1277+
12671278
#### `win.setThumbarButtons(buttons)` _Windows_
12681279

12691280
* `buttons` [ThumbarButton[]](structures/thumbar-button.md)

spec/api-browser-window-spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,17 @@ describe('BrowserWindow module', () => {
893893
})
894894
})
895895

896+
describe('BrowserWindow.setShape(rects)', () => {
897+
it('allows setting shape', () => {
898+
assert.doesNotThrow(() => {
899+
w.setShape([])
900+
w.setShape([{x: 0, y: 0, width: 100, height: 100}])
901+
w.setShape([{x: 0, y: 0, width: 100, height: 100}, {x: 0, y: 200, width: 1000, height: 100}])
902+
w.setShape([])
903+
})
904+
})
905+
})
906+
896907
describe('"useContentSize" option', () => {
897908
it('make window created with content size when used', () => {
898909
w.destroy()

0 commit comments

Comments
 (0)