mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
29 Commits
v13.0.0-be
...
v13.0.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5c3ac3e7b | ||
|
|
824028a367 | ||
|
|
2b23b145d9 | ||
|
|
128106520a | ||
|
|
7e4a9ebc27 | ||
|
|
87d3530d1b | ||
|
|
bf9dfa8247 | ||
|
|
300e902066 | ||
|
|
fa0f9e83f5 | ||
|
|
d32aa032cd | ||
|
|
3fe41bb852 | ||
|
|
58b80c2c06 | ||
|
|
2ec3da29d3 | ||
|
|
499c1a5067 | ||
|
|
544ea7a0c8 | ||
|
|
eca4a5cf4c | ||
|
|
56fc2bce30 | ||
|
|
4eea01e9b0 | ||
|
|
232392ffa0 | ||
|
|
7816fd240f | ||
|
|
bcf2d0969c | ||
|
|
ed7f5f3a0b | ||
|
|
1937aff793 | ||
|
|
cf493b995c | ||
|
|
5bbc64b416 | ||
|
|
287c9eb8c0 | ||
|
|
f4d77d97e3 | ||
|
|
593af18528 | ||
|
|
df47f85646 |
@@ -2610,15 +2610,19 @@ workflows:
|
||||
- osx-publish-x64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- mas-publish-x64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- osx-publish-arm64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- mas-publish-arm64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
|
||||
lint:
|
||||
when: << pipeline.parameters.run-lint >>
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -68,4 +68,6 @@ ts-gen
|
||||
.depshash-target
|
||||
|
||||
# Used to accelerate builds after sync
|
||||
patches/mtime-cache.json
|
||||
patches/mtime-cache.json
|
||||
|
||||
spec/fixtures/logo.png
|
||||
@@ -1 +1 @@
|
||||
13.0.0-beta.15
|
||||
13.0.0-beta.20
|
||||
@@ -15,12 +15,6 @@ args = [cmd, "run",
|
||||
try:
|
||||
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(
|
||||
"NPM script '"
|
||||
+ sys.argv[2]
|
||||
+ "' failed with code '"
|
||||
+ str(e.returncode)
|
||||
+ "':\n"
|
||||
+ e.output
|
||||
)
|
||||
error_msg = "NPM script '{}' failed with code '{}':\n".format(sys.argv[2], e.returncode)
|
||||
print(error_msg + e.output.decode('ascii'))
|
||||
sys.exit(e.returncode)
|
||||
|
||||
@@ -41,14 +41,14 @@ ipcMain.handle('bootstrap', (event) => {
|
||||
return isTrustedSender(event.sender) ? electronPath : null;
|
||||
});
|
||||
|
||||
async function createWindow () {
|
||||
async function createWindow (backgroundColor?: string) {
|
||||
await app.whenReady();
|
||||
|
||||
const options: Electron.BrowserWindowConstructorOptions = {
|
||||
width: 960,
|
||||
height: 620,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: '#2f3241',
|
||||
backgroundColor,
|
||||
webPreferences: {
|
||||
preload: path.resolve(__dirname, 'preload.js'),
|
||||
contextIsolation: true,
|
||||
@@ -96,7 +96,7 @@ export const loadURL = async (appUrl: string) => {
|
||||
};
|
||||
|
||||
export const loadFile = async (appPath: string) => {
|
||||
mainWindow = await createWindow();
|
||||
mainWindow = await createWindow(appPath === 'index.html' ? '#2f3241' : undefined);
|
||||
mainWindow.loadFile(appPath);
|
||||
mainWindow.focus();
|
||||
};
|
||||
|
||||
@@ -126,6 +126,8 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
* [ipcMain](api/ipc-main.md)
|
||||
* [Menu](api/menu.md)
|
||||
* [MenuItem](api/menu-item.md)
|
||||
* [MessageChannelMain](api/message-channel-main.md)
|
||||
* [MessagePortMain](api/message-port-main.md)
|
||||
* [net](api/net.md)
|
||||
* [netLog](api/net-log.md)
|
||||
* [nativeTheme](api/native-theme.md)
|
||||
@@ -135,6 +137,7 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
* [protocol](api/protocol.md)
|
||||
* [screen](api/screen.md)
|
||||
* [session](api/session.md)
|
||||
* [ShareMenu](api/share-menu.md)
|
||||
* [systemPreferences](api/system-preferences.md)
|
||||
* [TouchBar](api/touch-bar.md)
|
||||
* [Tray](api/tray.md)
|
||||
|
||||
@@ -753,7 +753,8 @@ Overrides the current application's name.
|
||||
|
||||
### `app.getLocale()`
|
||||
|
||||
Returns `String` - The current application locale. Possible return values are documented [here](locales.md).
|
||||
Returns `String` - The current application locale, fetched using Chromium's `l10n_util` library.
|
||||
Possible return values are documented [here](https://source.chromium.org/chromium/chromium/src/+/master:ui/base/l10n/l10n_util.cc).
|
||||
|
||||
To set the locale, you'll want to use a command line switch at app startup, which may be found [here](https://github.com/electron/electron/blob/master/docs/api/command-line-switches.md).
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
## Class: BrowserView
|
||||
|
||||
> Create and control views.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
# BrowserView
|
||||
|
||||
A `BrowserView` can be used to embed additional web content into a
|
||||
[`BrowserWindow`](browser-window.md). It is like a child window, except that it is positioned
|
||||
relative to its owning window. It is meant to be an alternative to the
|
||||
`webview` tag.
|
||||
|
||||
## Class: BrowserView
|
||||
|
||||
> Create and control views.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -1301,7 +1301,7 @@ can be be used to listen to changes to tablet mode.
|
||||
|
||||
#### `win.getMediaSourceId()`
|
||||
|
||||
Returns `String` - Window id in the format of DesktopCapturerSource's id. For example "window:1234:0".
|
||||
Returns `String` - Window id in the format of DesktopCapturerSource's id. For example "window:1324:0".
|
||||
|
||||
More precisely the format is `window:id:other_id` where `id` is `HWND` on
|
||||
Windows, `CGWindowID` (`uint64_t`) on macOS and `Window` (`unsigned long`) on
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
# Locales
|
||||
|
||||
> Locale values returned by `app.getLocale()`.
|
||||
|
||||
Electron uses Chromium's `l10n_util` library to fetch the locale. Possible
|
||||
values are listed below:
|
||||
|
||||
| Language Code | Language Name |
|
||||
|---------------|---------------|
|
||||
| af | Afrikaans |
|
||||
| am | Amharic |
|
||||
| ar | Arabic |
|
||||
| az | Azerbaijani |
|
||||
| be | Belarusian |
|
||||
| bg | Bulgarian |
|
||||
| bh | Bihari |
|
||||
| bn | Bengali |
|
||||
| br | Breton |
|
||||
| bs | Bosnian |
|
||||
| ca | Catalan |
|
||||
| co | Corsican |
|
||||
| cs | Czech |
|
||||
| cy | Welsh |
|
||||
| da | Danish |
|
||||
| de | German |
|
||||
| de-AT | German (Austria) |
|
||||
| de-CH | German (Switzerland) |
|
||||
| de-DE | German (Germany) |
|
||||
| el | Greek |
|
||||
| en | English |
|
||||
| en-AU | English (Australia) |
|
||||
| en-CA | English (Canada) |
|
||||
| en-GB | English (UK) |
|
||||
| en-NZ | English (New Zealand) |
|
||||
| en-US | English (US) |
|
||||
| en-ZA | English (South Africa) |
|
||||
| eo | Esperanto |
|
||||
| es | Spanish |
|
||||
| es-419 | Spanish (Latin America) |
|
||||
| et | Estonian |
|
||||
| eu | Basque |
|
||||
| fa | Persian |
|
||||
| fi | Finnish |
|
||||
| fil | Filipino |
|
||||
| fo | Faroese |
|
||||
| fr | French |
|
||||
| fr-CA | French (Canada) |
|
||||
| fr-CH | French (Switzerland) |
|
||||
| fr-FR | French (France) |
|
||||
| fy | Frisian |
|
||||
| ga | Irish |
|
||||
| gd | Scots Gaelic |
|
||||
| gl | Galician |
|
||||
| gn | Guarani |
|
||||
| gu | Gujarati |
|
||||
| ha | Hausa |
|
||||
| haw | Hawaiian |
|
||||
| he | Hebrew |
|
||||
| hi | Hindi |
|
||||
| hr | Croatian |
|
||||
| hu | Hungarian |
|
||||
| hy | Armenian |
|
||||
| ia | Interlingua |
|
||||
| id | Indonesian |
|
||||
| is | Icelandic |
|
||||
| it | Italian |
|
||||
| it-CH | Italian (Switzerland) |
|
||||
| it-IT | Italian (Italy) |
|
||||
| ja | Japanese |
|
||||
| jw | Javanese |
|
||||
| ka | Georgian |
|
||||
| kk | Kazakh |
|
||||
| km | Cambodian |
|
||||
| kn | Kannada |
|
||||
| ko | Korean |
|
||||
| ku | Kurdish |
|
||||
| ky | Kyrgyz |
|
||||
| la | Latin |
|
||||
| ln | Lingala |
|
||||
| lo | Laothian |
|
||||
| lt | Lithuanian |
|
||||
| lv | Latvian |
|
||||
| mk | Macedonian |
|
||||
| ml | Malayalam |
|
||||
| mn | Mongolian |
|
||||
| mo | Moldavian |
|
||||
| mr | Marathi |
|
||||
| ms | Malay |
|
||||
| mt | Maltese |
|
||||
| nb | Norwegian (Bokmal) |
|
||||
| ne | Nepali |
|
||||
| nl | Dutch |
|
||||
| nn | Norwegian (Nynorsk) |
|
||||
| no | Norwegian |
|
||||
| oc | Occitan |
|
||||
| om | Oromo |
|
||||
| or | Oriya |
|
||||
| pa | Punjabi |
|
||||
| pl | Polish |
|
||||
| ps | Pashto |
|
||||
| pt | Portuguese |
|
||||
| pt-BR | Portuguese (Brazil) |
|
||||
| pt-PT | Portuguese (Portugal) |
|
||||
| qu | Quechua |
|
||||
| rm | Romansh |
|
||||
| ro | Romanian |
|
||||
| ru | Russian |
|
||||
| sd | Sindhi |
|
||||
| sh | Serbo-Croatian |
|
||||
| si | Sinhalese |
|
||||
| sk | Slovak |
|
||||
| sl | Slovenian |
|
||||
| sn | Shona |
|
||||
| so | Somali |
|
||||
| sq | Albanian |
|
||||
| sr | Serbian |
|
||||
| st | Sesotho |
|
||||
| su | Sundanese |
|
||||
| sv | Swedish |
|
||||
| sw | Swahili |
|
||||
| ta | Tamil |
|
||||
| te | Telugu |
|
||||
| tg | Tajik |
|
||||
| th | Thai |
|
||||
| ti | Tigrinya |
|
||||
| tk | Turkmen |
|
||||
| to | Tonga |
|
||||
| tr | Turkish |
|
||||
| tt | Tatar |
|
||||
| tw | Twi |
|
||||
| ug | Uighur |
|
||||
| uk | Ukrainian |
|
||||
| ur | Urdu |
|
||||
| uz | Uzbek |
|
||||
| vi | Vietnamese |
|
||||
| xh | Xhosa |
|
||||
| yi | Yiddish |
|
||||
| yo | Yoruba |
|
||||
| zh | Chinese |
|
||||
| zh-CN | Chinese (Simplified) |
|
||||
| zh-TW | Chinese (Traditional) |
|
||||
| zu | Zulu |
|
||||
@@ -1,3 +1,5 @@
|
||||
# Menu
|
||||
|
||||
## Class: Menu
|
||||
|
||||
> Create native application menus and context menus.
|
||||
|
||||
@@ -9,12 +9,15 @@ channel messaging.
|
||||
|
||||
## Class: MessageChannelMain
|
||||
|
||||
> Channel interface for channel messaging in the main process.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
// Main process
|
||||
const { MessageChannelMain } = require('electron')
|
||||
const { port1, port2 } = new MessageChannelMain()
|
||||
w.webContents.postMessage('port', null, [port2])
|
||||
port1.postMessage({ some: 'message' })
|
||||
|
||||
@@ -14,6 +14,8 @@ channel messaging.
|
||||
|
||||
## Class: MessagePortMain
|
||||
|
||||
> Port interface for channel messaging in the main process.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
### Instance Methods
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
## Class: ShareMenu
|
||||
|
||||
> Create share menu on macOS.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
# ShareMenu
|
||||
|
||||
The `ShareMenu` class creates [Share Menu][share-menu] on macOS, which can be
|
||||
used to share information from the current context to apps, social media
|
||||
@@ -11,6 +7,12 @@ accounts, and other services.
|
||||
For including the share menu as a submenu of other menus, please use the
|
||||
`shareMenu` role of [`MenuItem`](menu-item.md).
|
||||
|
||||
## Class: ShareMenu
|
||||
|
||||
> Create share menu on macOS.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
### `new ShareMenu(sharingItem)`
|
||||
|
||||
* `sharingItem` SharingItem - The item to share.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# TouchBar
|
||||
|
||||
## Class: TouchBar
|
||||
|
||||
> Create TouchBar layouts for native macOS applications
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Tray
|
||||
|
||||
## Class: Tray
|
||||
|
||||
> Add icons and context menus to the system's notification area.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Build Instructions
|
||||
|
||||
Follow the guidelines below for building Electron.
|
||||
Follow the guidelines below for building **Electron itself**, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
|
||||
|
||||
[application-distribution]: ../tutorial/application-distribution.md
|
||||
|
||||
## Platform prerequisites
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Build Instructions (Linux)
|
||||
|
||||
Follow the guidelines below for building Electron on Linux.
|
||||
Follow the guidelines below for building **Electron itself** on Linux, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
|
||||
|
||||
[application-distribution]: ../tutorial/application-distribution.md
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Build Instructions (macOS)
|
||||
|
||||
Follow the guidelines below for building Electron on macOS.
|
||||
Follow the guidelines below for building **Electron itself** on macOS, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
|
||||
|
||||
[application-distribution]: ../tutorial/application-distribution.md
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Build Instructions (Windows)
|
||||
|
||||
Follow the guidelines below for building Electron on Windows.
|
||||
Follow the guidelines below for building **Electron itself** on Windows, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
|
||||
|
||||
[application-distribution]: ../tutorial/application-distribution.md
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -100,7 +100,5 @@ script/ - The set of all scripts Electron runs for a variety of purposes.
|
||||
└── uploaders/ - Uploads various release-related files during release.
|
||||
```
|
||||
|
||||
* **tools** - Helper scripts used by GN files.
|
||||
* Scripts put here should never be invoked by users directly, unlike those in `script`.
|
||||
* **typings** - TypeScript typings for Electron's internal code.
|
||||
* **vendor** - Source code for some third party dependencies.
|
||||
|
||||
@@ -29,7 +29,6 @@ auto_filenames = {
|
||||
"docs/api/incoming-message.md",
|
||||
"docs/api/ipc-main.md",
|
||||
"docs/api/ipc-renderer.md",
|
||||
"docs/api/locales.md",
|
||||
"docs/api/menu-item.md",
|
||||
"docs/api/menu.md",
|
||||
"docs/api/message-channel-main.md",
|
||||
|
||||
@@ -63,6 +63,9 @@ Object.defineProperty(app, 'applicationMenu', {
|
||||
return execFile !== 'electron';
|
||||
})();
|
||||
|
||||
// The native implementation is not provided on non-windows platforms
|
||||
app.setAppUserModelId = app.setAppUserModelId || (() => {});
|
||||
|
||||
app._setDefaultAppPaths = (packagePath) => {
|
||||
// Set the user path according to application's name.
|
||||
app.setPath('userData', path.join(app.getPath('appData'), app.name!));
|
||||
|
||||
@@ -188,6 +188,11 @@ class ChunkedBodyStream extends Writable {
|
||||
this._downstream = pipe;
|
||||
if (this._pendingChunk) {
|
||||
const doneWriting = (maybeError: Error | void) => {
|
||||
// If the underlying request has been aborted, we honeslty don't care about the error
|
||||
// all work should cease as soon as we abort anyway, this error is probably a
|
||||
// "mojo pipe disconnected" error (code=9)
|
||||
if (this._clientRequest._aborted) return;
|
||||
|
||||
const cb = this._pendingCallback!;
|
||||
delete this._pendingCallback;
|
||||
delete this._pendingChunk;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "13.0.0-beta.15",
|
||||
"version": "13.0.0-beta.20",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -8,3 +8,4 @@ do_not_export_private_v8_symbols_on_windows.patch
|
||||
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
|
||||
skip_global_registration_of_shared_arraybuffer_backing_stores.patch
|
||||
cherry-pick-02f84c745fc0.patch
|
||||
cherry-pick-512cd5e179f4.patch
|
||||
|
||||
109
patches/v8/cherry-pick-512cd5e179f4.patch
Normal file
109
patches/v8/cherry-pick-512cd5e179f4.patch
Normal file
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Georg Neis <neis@chromium.org>
|
||||
Date: Wed, 14 Apr 2021 13:19:44 +0200
|
||||
Subject: Merged: [compiler] Fix bug in
|
||||
RepresentationChanger::GetWord32RepresentationFor
|
||||
|
||||
Revision: fd29e246f65a7cee130e72cd10f618f3b82af232
|
||||
|
||||
BUG=chromium:1195777
|
||||
NOTRY=true
|
||||
NOPRESUBMIT=true
|
||||
NOTREECHECKS=true
|
||||
R=nicohartmann@chromium.org
|
||||
|
||||
Change-Id: I0400b3ae5736ef86dbeae558d15bfcca2e9f351a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2826114
|
||||
Commit-Queue: Georg Neis <neis@chromium.org>
|
||||
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/9.0@{#34}
|
||||
Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1}
|
||||
Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001}
|
||||
|
||||
diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc
|
||||
index 64b274cdccddf4db63fdf5d80c0527405906ee75..3d937ada1e7e505bfc5cf2307ad4a8a5efef5a19 100644
|
||||
--- a/src/compiler/representation-change.cc
|
||||
+++ b/src/compiler/representation-change.cc
|
||||
@@ -949,10 +949,10 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
|
||||
return node;
|
||||
} else if (output_rep == MachineRepresentation::kWord64) {
|
||||
if (output_type.Is(Type::Signed32()) ||
|
||||
- output_type.Is(Type::Unsigned32())) {
|
||||
- op = machine()->TruncateInt64ToInt32();
|
||||
- } else if (output_type.Is(cache_->kSafeInteger) &&
|
||||
- use_info.truncation().IsUsedAsWord32()) {
|
||||
+ (output_type.Is(Type::Unsigned32()) &&
|
||||
+ use_info.type_check() == TypeCheckKind::kNone) ||
|
||||
+ (output_type.Is(cache_->kSafeInteger) &&
|
||||
+ use_info.truncation().IsUsedAsWord32())) {
|
||||
op = machine()->TruncateInt64ToInt32();
|
||||
} else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
|
||||
use_info.type_check() == TypeCheckKind::kSigned32 ||
|
||||
diff --git a/test/mjsunit/compiler/regress-1195777.js b/test/mjsunit/compiler/regress-1195777.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b122f4f0169af573723d4318b9f1127c857c9e35
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/compiler/regress-1195777.js
|
||||
@@ -0,0 +1,62 @@
|
||||
+// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --allow-natives-syntax
|
||||
+
|
||||
+
|
||||
+(function() {
|
||||
+ function foo(b) {
|
||||
+ let y = (new Date(42)).getMilliseconds();
|
||||
+ let x = -1;
|
||||
+ if (b) x = 0xFFFF_FFFF;
|
||||
+ return y < Math.max(1 << y, x, 1 + y);
|
||||
+ }
|
||||
+ assertTrue(foo(true));
|
||||
+ %PrepareFunctionForOptimization(foo);
|
||||
+ assertTrue(foo(false));
|
||||
+ %OptimizeFunctionOnNextCall(foo);
|
||||
+ assertTrue(foo(true));
|
||||
+})();
|
||||
+
|
||||
+
|
||||
+(function() {
|
||||
+ function foo(b) {
|
||||
+ let x = 0;
|
||||
+ if (b) x = -1;
|
||||
+ return x == Math.max(-1, x >>> Infinity);
|
||||
+ }
|
||||
+ assertFalse(foo(true));
|
||||
+ %PrepareFunctionForOptimization(foo);
|
||||
+ assertTrue(foo(false));
|
||||
+ %OptimizeFunctionOnNextCall(foo);
|
||||
+ assertFalse(foo(true));
|
||||
+})();
|
||||
+
|
||||
+
|
||||
+(function() {
|
||||
+ function foo(b) {
|
||||
+ let x = -1;
|
||||
+ if (b) x = 0xFFFF_FFFF;
|
||||
+ return -1 < Math.max(0, x, -1);
|
||||
+ }
|
||||
+ assertTrue(foo(true));
|
||||
+ %PrepareFunctionForOptimization(foo);
|
||||
+ assertTrue(foo(false));
|
||||
+ %OptimizeFunctionOnNextCall(foo);
|
||||
+ assertTrue(foo(true));
|
||||
+})();
|
||||
+
|
||||
+
|
||||
+(function() {
|
||||
+ function foo(b) {
|
||||
+ let x = 0x7FFF_FFFF;
|
||||
+ if (b) x = 0;
|
||||
+ return 0 < (Math.max(-5 >>> x, -5) % -5);
|
||||
+ }
|
||||
+ assertTrue(foo(true));
|
||||
+ %PrepareFunctionForOptimization(foo);
|
||||
+ assertTrue(foo(false));
|
||||
+ %OptimizeFunctionOnNextCall(foo);
|
||||
+ assertTrue(foo(true));
|
||||
+})();
|
||||
@@ -27,19 +27,22 @@ async function checkIfDocOnlyChange () {
|
||||
}
|
||||
}
|
||||
}
|
||||
const filesChanged = await octokit.pulls.listFiles({
|
||||
owner: 'electron', repo: 'electron', pull_number: pullRequestNumber
|
||||
});
|
||||
const filesChanged = await octokit.paginate(octokit.pulls.listFiles.endpoint.merge({
|
||||
owner: 'electron',
|
||||
repo: 'electron',
|
||||
pull_number: pullRequestNumber,
|
||||
per_page: 100
|
||||
}));
|
||||
|
||||
console.log('Changed Files:', filesChanged.data.map(fileInfo => fileInfo.filename));
|
||||
console.log('Changed Files:', filesChanged.map(fileInfo => fileInfo.filename));
|
||||
|
||||
const nonDocChange = filesChanged.data.find((fileInfo) => {
|
||||
const nonDocChange = filesChanged.find((fileInfo) => {
|
||||
const fileDirs = fileInfo.filename.split('/');
|
||||
if (fileDirs[0] !== 'docs') {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (nonDocChange || filesChanged.data.length === 0) {
|
||||
if (nonDocChange || filesChanged.length === 0) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import itertools
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def validate_pair(ob):
|
||||
if not (len(ob) == 2):
|
||||
print("Unexpected result:", ob, file=sys.stderr)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def consume(iterator):
|
||||
try:
|
||||
while True:
|
||||
next(iterator)
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
|
||||
def get_environment_from_batch_command(env_cmd, initial=None):
|
||||
"""
|
||||
Take a command (either a single command or list of arguments)
|
||||
and return the environment created after running that command.
|
||||
Note that if the command must be a batch file or .cmd file, or the
|
||||
changes to the environment will not be captured.
|
||||
|
||||
If initial is supplied, it is used as the initial environment passed
|
||||
to the child process.
|
||||
"""
|
||||
if not isinstance(env_cmd, (list, tuple)):
|
||||
env_cmd = [env_cmd]
|
||||
# Construct the command that will alter the environment.
|
||||
cmd = subprocess.list2cmdline(env_cmd)
|
||||
# Create a tag so we can tell in the output when the proc is done.
|
||||
tag = 'END OF BATCH COMMAND'
|
||||
# Construct a cmd.exe command to do accomplish this.
|
||||
cmd = 'cmd.exe /s /c "{cmd} && echo "{tag}" && set"'.format(**locals())
|
||||
# Launch the process.
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=initial)
|
||||
# Parse the output sent to stdout.
|
||||
lines = proc.stdout
|
||||
# Consume whatever output occurs until the tag is reached.
|
||||
consume(itertools.takewhile(lambda l: tag not in l, lines))
|
||||
# Define a way to handle each KEY=VALUE line.
|
||||
handle_line = lambda l: l.rstrip().split('=',1)
|
||||
# Parse key/values into pairs.
|
||||
pairs = map(handle_line, lines)
|
||||
# Make sure the pairs are valid.
|
||||
valid_pairs = filter(validate_pair, pairs)
|
||||
# Construct a dictionary of the pairs.
|
||||
result = dict(valid_pairs)
|
||||
# Let the process finish.
|
||||
proc.communicate()
|
||||
return result
|
||||
|
||||
def get_vs_location(vs_version):
|
||||
"""
|
||||
Returns the location of the VS building environment.
|
||||
|
||||
The vs_version can be strings like "[15.0,16.0)", meaning 2017,
|
||||
but not the next version.
|
||||
"""
|
||||
|
||||
# vswhere can't handle spaces. "[15.0, 16.0)" should become "[15.0,16.0)"
|
||||
vs_version = vs_version.replace(" ", "")
|
||||
|
||||
program_files = os.environ.get('ProgramFiles(x86)')
|
||||
# Find visual studio
|
||||
proc = subprocess.Popen(
|
||||
program_files + "\\Microsoft Visual Studio\\Installer\\vswhere.exe "
|
||||
"-property installationPath "
|
||||
"-requires Microsoft.VisualStudio.Component.VC.CoreIde "
|
||||
"-format value "
|
||||
"-version {0}".format(vs_version),
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
location = proc.stdout.readline().rstrip()
|
||||
return location
|
||||
|
||||
def get_vs_env(vs_version, arch):
|
||||
"""
|
||||
Returns the env object for VS building environment.
|
||||
|
||||
vs_version is the version of Visual Studio to use.
|
||||
See get_vs_location for more details.
|
||||
The arch must be one of "x86", "amd64", "arm", "x86_amd64", "x86_arm",
|
||||
"amd64_x86", "amd64_arm", i.e. the args passed to vcvarsall.bat.
|
||||
"""
|
||||
|
||||
location = get_vs_location(vs_version)
|
||||
|
||||
# Launch the process.
|
||||
vsvarsall = "{0}\\VC\\Auxiliary\\Build\\vcvarsall.bat".format(location)
|
||||
|
||||
return get_environment_from_batch_command([vsvarsall, arch])
|
||||
@@ -73,25 +73,6 @@ def am(repo, patch_data, threeway=False, directory=None, exclude=None,
|
||||
proc.returncode))
|
||||
|
||||
|
||||
def apply_patch(repo, patch_path, directory=None, index=False, reverse=False):
|
||||
args = ['git', '-C', repo, 'apply',
|
||||
'--ignore-space-change',
|
||||
'--ignore-whitespace',
|
||||
'--whitespace', 'fix'
|
||||
]
|
||||
if directory:
|
||||
args += ['--directory', directory]
|
||||
if index:
|
||||
args += ['--index']
|
||||
if reverse:
|
||||
args += ['--reverse']
|
||||
args += ['--', patch_path]
|
||||
|
||||
return_code = subprocess.call(args)
|
||||
applied_successfully = (return_code == 0)
|
||||
return applied_successfully
|
||||
|
||||
|
||||
def import_patches(repo, **kwargs):
|
||||
"""same as am(), but we save the upstream HEAD so we can refer to it when we
|
||||
later export patches"""
|
||||
@@ -103,52 +84,12 @@ def import_patches(repo, **kwargs):
|
||||
am(repo=repo, **kwargs)
|
||||
|
||||
|
||||
def get_patch(repo, commit_hash):
|
||||
args = ['git', '-C', repo, 'diff-tree',
|
||||
'-p',
|
||||
commit_hash,
|
||||
'--' # Explicitly tell Git `commit_hash` is a revision, not a path.
|
||||
]
|
||||
|
||||
return subprocess.check_output(args).decode('utf-8')
|
||||
|
||||
|
||||
def get_head_commit(repo):
|
||||
args = ['git', '-C', repo, 'rev-parse', 'HEAD']
|
||||
|
||||
return subprocess.check_output(args).decode('utf-8').strip()
|
||||
|
||||
|
||||
def update_ref(repo, ref, newvalue):
|
||||
args = ['git', '-C', repo, 'update-ref', ref, newvalue]
|
||||
|
||||
return subprocess.check_call(args)
|
||||
|
||||
|
||||
def reset(repo):
|
||||
args = ['git', '-C', repo, 'reset']
|
||||
|
||||
subprocess.check_call(args)
|
||||
|
||||
|
||||
def commit(repo, author, message):
|
||||
"""Commit whatever in the index is now."""
|
||||
|
||||
# Let's setup committer info so git won't complain about it being missing.
|
||||
# TODO: Is there a better way to set committer's name and email?
|
||||
env = os.environ.copy()
|
||||
env['GIT_COMMITTER_NAME'] = 'Anonymous Committer'
|
||||
env['GIT_COMMITTER_EMAIL'] = 'anonymous@electronjs.org'
|
||||
|
||||
args = ['git', '-C', repo, 'commit',
|
||||
'--author', author,
|
||||
'--message', message
|
||||
]
|
||||
|
||||
return_code = subprocess.call(args, env=env)
|
||||
committed_successfully = (return_code == 0)
|
||||
return committed_successfully
|
||||
|
||||
def get_upstream_head(repo):
|
||||
args = [
|
||||
'git',
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from lib.util import scoped_cwd
|
||||
|
||||
|
||||
class GNProject:
|
||||
def __init__(self, out_dir):
|
||||
self.out_dir = out_dir
|
||||
|
||||
def _get_executable_name(self):
|
||||
if sys.platform == 'win32':
|
||||
return 'gn.bat'
|
||||
|
||||
return 'gn'
|
||||
|
||||
def run(self, command_name, command_args):
|
||||
with scoped_cwd(self.out_dir):
|
||||
complete_args = [self._get_executable_name(), command_name, '.'] + \
|
||||
command_args
|
||||
return subprocess.check_output(complete_args)
|
||||
|
||||
def args(self):
|
||||
return GNArgs(self)
|
||||
|
||||
|
||||
class GNArgs:
|
||||
def __init__(self, project):
|
||||
self.project = project
|
||||
|
||||
def _get_raw_value(self, name):
|
||||
# E.g. 'version = "1.0.0"\n'
|
||||
raw_output = self.project.run('args',
|
||||
['--list={}'.format(name), '--short'])
|
||||
|
||||
# E.g. 'version = "1.0.0"'
|
||||
name_with_raw_value = raw_output[:-1]
|
||||
|
||||
# E.g. ['version', '"1.0.0"']
|
||||
name_and_raw_value = name_with_raw_value.split(' = ')
|
||||
|
||||
raw_value = name_and_raw_value[1]
|
||||
return raw_value
|
||||
|
||||
def get_string(self, name):
|
||||
# Expects to get a string in double quotes, e.g. '"some_value"'.
|
||||
raw_value = self._get_raw_value(name)
|
||||
|
||||
# E.g. 'some_value' (without enclosing quotes).
|
||||
value = raw_value[1:-1]
|
||||
return value
|
||||
|
||||
def get_boolean(self, name):
|
||||
# Expects to get a 'true' or a 'false' string.
|
||||
raw_value = self._get_raw_value(name)
|
||||
|
||||
if raw_value == 'true':
|
||||
return True
|
||||
|
||||
if raw_value == 'false':
|
||||
return False
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def gn(out_dir):
|
||||
return GNProject(out_dir)
|
||||
@@ -34,12 +34,6 @@ if sys.platform in ['win32', 'cygwin']:
|
||||
TS_NODE += '.cmd'
|
||||
|
||||
|
||||
def tempdir(prefix=''):
|
||||
directory = tempfile.mkdtemp(prefix=prefix)
|
||||
atexit.register(shutil.rmtree, directory)
|
||||
return directory
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def scoped_cwd(path):
|
||||
cwd = os.getcwd()
|
||||
@@ -65,9 +59,6 @@ def scoped_env(key, value):
|
||||
def download(text, url, path):
|
||||
safe_mkdir(os.path.dirname(path))
|
||||
with open(path, 'wb') as local_file:
|
||||
if hasattr(ssl, '_create_unverified_context'):
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
print("Downloading %s to %s" % (url, path))
|
||||
web_file = urlopen(url)
|
||||
info = web_file.info()
|
||||
@@ -100,19 +91,6 @@ def download(text, url, path):
|
||||
return path
|
||||
|
||||
|
||||
def extract_tarball(tarball_path, member, destination):
|
||||
with tarfile.open(tarball_path) as tarball:
|
||||
tarball.extract(member, destination)
|
||||
|
||||
|
||||
def extract_zip(zip_path, destination):
|
||||
if sys.platform == 'darwin':
|
||||
# Use unzip command on Mac to keep symbol links in zip file work.
|
||||
execute(['unzip', zip_path, '-d', destination])
|
||||
else:
|
||||
with zipfile.ZipFile(zip_path) as z:
|
||||
z.extractall(destination)
|
||||
|
||||
def make_zip(zip_file_path, files, dirs):
|
||||
safe_unlink(zip_file_path)
|
||||
if sys.platform == 'darwin':
|
||||
@@ -169,19 +147,6 @@ def execute(argv, env=None, cwd=None):
|
||||
raise e
|
||||
|
||||
|
||||
def execute_stdout(argv, env=None, cwd=None):
|
||||
if env is None:
|
||||
env = os.environ
|
||||
if is_verbose_mode():
|
||||
print(' '.join(argv))
|
||||
try:
|
||||
subprocess.check_call(argv, env=env, cwd=cwd)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e.output)
|
||||
raise e
|
||||
else:
|
||||
execute(argv, env, cwd)
|
||||
|
||||
def get_electron_branding():
|
||||
SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
|
||||
branding_file_path = os.path.join(
|
||||
@@ -209,10 +174,6 @@ def s3put(bucket, access_key, secret_key, prefix, key_prefix, files):
|
||||
] + files, env)
|
||||
print(output)
|
||||
|
||||
|
||||
def add_exec_bit(filename):
|
||||
os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC)
|
||||
|
||||
def get_out_dir():
|
||||
out_dir = 'Debug'
|
||||
override = os.environ.get('ELECTRON_OUT_DIR')
|
||||
|
||||
@@ -152,7 +152,13 @@ new Promise((resolve, reject) => {
|
||||
resolve(tarballPath);
|
||||
});
|
||||
})
|
||||
.then((tarballPath) => childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag} --otp=${process.env.ELECTRON_NPM_OTP}`))
|
||||
.then((tarballPath) => {
|
||||
const existingVersionJSON = childProcess.execSync(`npm view electron@${rootPackageJson.version} --json`).toString('utf-8');
|
||||
// It's possible this is a re-run and we already have published the package, if not we just publish like normal
|
||||
if (!existingVersionJSON) {
|
||||
childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag} --otp=${process.env.ELECTRON_NPM_OTP}`);
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
const currentTags = JSON.parse(childProcess.execSync('npm show electron dist-tags --json').toString());
|
||||
const localVersion = rootPackageJson.version;
|
||||
|
||||
@@ -88,7 +88,7 @@ def create_checksum(algorithm, directory, filename, files):
|
||||
lines = []
|
||||
for path in files:
|
||||
h = hashlib.new(algorithm)
|
||||
with open(path, 'r') as f:
|
||||
with open(path, 'rb') as f:
|
||||
h.update(f.read())
|
||||
lines.append(h.hexdigest() + ' ' + os.path.relpath(path, directory))
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ from lib.util import get_electron_branding, execute, get_electron_version, \
|
||||
SRC_DIR, ELECTRON_DIR, TS_NODE
|
||||
|
||||
|
||||
ELECTRON_REPO = 'electron/electron'
|
||||
ELECTRON_VERSION = get_electron_version()
|
||||
|
||||
PROJECT_NAME = get_electron_branding()['project_name']
|
||||
@@ -360,14 +359,6 @@ def upload_sha256_checksum(version, file_path, key_prefix=None):
|
||||
key_prefix, [checksum_path])
|
||||
|
||||
|
||||
def auth_token():
|
||||
token = get_env_var('GITHUB_TOKEN')
|
||||
message = ('Error: Please set the $ELECTRON_GITHUB_TOKEN '
|
||||
'environment variable, which is your personal token')
|
||||
assert token, message
|
||||
return token
|
||||
|
||||
|
||||
def get_release(version):
|
||||
script_path = os.path.join(
|
||||
ELECTRON_DIR, 'script', 'release', 'find-github-release.js')
|
||||
|
||||
@@ -143,7 +143,7 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
|
||||
fullscreenable = false;
|
||||
#endif
|
||||
}
|
||||
// Overriden by 'fullscreenable'.
|
||||
// Overridden by 'fullscreenable'.
|
||||
options.Get(options::kFullScreenable, &fullscreenable);
|
||||
SetFullScreenable(fullscreenable);
|
||||
if (fullscreen) {
|
||||
@@ -419,11 +419,11 @@ void NativeWindow::NotifyWindowClosed() {
|
||||
if (is_closed_)
|
||||
return;
|
||||
|
||||
WindowList::RemoveWindow(this);
|
||||
|
||||
is_closed_ = true;
|
||||
for (NativeWindowObserver& observer : observers_)
|
||||
observer.OnWindowClosed();
|
||||
|
||||
WindowList::RemoveWindow(this);
|
||||
}
|
||||
|
||||
void NativeWindow::NotifyWindowEndSession() {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
@@ -164,6 +165,12 @@ class NativeWindowMac : public NativeWindow,
|
||||
void SetCollectionBehavior(bool on, NSUInteger flag);
|
||||
void SetWindowLevel(int level);
|
||||
|
||||
enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
|
||||
|
||||
// Handle fullscreen transitions.
|
||||
void SetFullScreenTransitionState(FullScreenTransitionState state);
|
||||
void HandlePendingFullscreenTransitions();
|
||||
|
||||
enum class VisualEffectState {
|
||||
kFollowWindow,
|
||||
kActive,
|
||||
@@ -182,7 +189,6 @@ class NativeWindowMac : public NativeWindow,
|
||||
ElectronTouchBar* touch_bar() const { return touch_bar_.get(); }
|
||||
bool zoom_to_page_width() const { return zoom_to_page_width_; }
|
||||
bool always_simple_fullscreen() const { return always_simple_fullscreen_; }
|
||||
bool exiting_fullscreen() const { return exiting_fullscreen_; }
|
||||
|
||||
protected:
|
||||
// views::WidgetDelegate:
|
||||
@@ -224,12 +230,17 @@ class NativeWindowMac : public NativeWindow,
|
||||
std::unique_ptr<RootViewMac> root_view_;
|
||||
|
||||
bool is_kiosk_ = false;
|
||||
bool was_fullscreen_ = false;
|
||||
bool zoom_to_page_width_ = false;
|
||||
bool resizable_ = true;
|
||||
bool exiting_fullscreen_ = false;
|
||||
base::Optional<gfx::Point> traffic_light_position_;
|
||||
|
||||
std::queue<bool> pending_transitions_;
|
||||
FullScreenTransitionState fullscreen_transition_state() const {
|
||||
return fullscreen_transition_state_;
|
||||
}
|
||||
FullScreenTransitionState fullscreen_transition_state_ =
|
||||
FullScreenTransitionState::NONE;
|
||||
|
||||
NSInteger attention_request_id_ = 0; // identifier from requestUserAttention
|
||||
|
||||
// The presentation options before entering kiosk mode.
|
||||
|
||||
@@ -535,6 +535,12 @@ void NativeWindowMac::ShowInactive() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::Hide() {
|
||||
// If a sheet is attached to the window when we call [window_ orderOut:nil],
|
||||
// the sheet won't be able to show again on the same window.
|
||||
// Ensure it's closed before calling [window_ orderOut:nil].
|
||||
if ([window_ attachedSheet])
|
||||
[window_ endSheet:[window_ attachedSheet]];
|
||||
|
||||
if (is_modal() && parent()) {
|
||||
[window_ orderOut:nil];
|
||||
[parent()->GetNativeWindow().GetNativeNSWindow() endSheet:window_];
|
||||
@@ -557,6 +563,11 @@ bool NativeWindowMac::IsVisible() {
|
||||
return [window_ isVisible] && !occluded && !IsMinimized();
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetFullScreenTransitionState(
|
||||
FullScreenTransitionState state) {
|
||||
fullscreen_transition_state_ = state;
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsEnabled() {
|
||||
return [window_ attachedSheet] == nil;
|
||||
}
|
||||
@@ -621,13 +632,48 @@ bool NativeWindowMac::IsMinimized() {
|
||||
return [window_ isMiniaturized];
|
||||
}
|
||||
|
||||
void NativeWindowMac::HandlePendingFullscreenTransitions() {
|
||||
if (pending_transitions_.empty())
|
||||
return;
|
||||
|
||||
bool next_transition = pending_transitions_.front();
|
||||
pending_transitions_.pop();
|
||||
SetFullScreen(next_transition);
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetFullScreen(bool fullscreen) {
|
||||
// [NSWindow -toggleFullScreen] is an asynchronous operation, which means
|
||||
// that it's possible to call it while a fullscreen transition is currently
|
||||
// in process. This can create weird behavior (incl. phantom windows),
|
||||
// so we want to schedule a transition for when the current one has completed.
|
||||
if (fullscreen_transition_state() != FullScreenTransitionState::NONE) {
|
||||
if (!pending_transitions_.empty()) {
|
||||
bool last_pending = pending_transitions_.back();
|
||||
// Only push new transitions if they're different than the last transition
|
||||
// in the queue.
|
||||
if (last_pending != fullscreen)
|
||||
pending_transitions_.push(fullscreen);
|
||||
} else {
|
||||
pending_transitions_.push(fullscreen);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (fullscreen == IsFullscreen())
|
||||
return;
|
||||
|
||||
// Take note of the current window size
|
||||
if (IsNormal())
|
||||
original_frame_ = [window_ frame];
|
||||
|
||||
// This needs to be set here because it can be the case that
|
||||
// SetFullScreen is called by a user before windowWillEnterFullScreen
|
||||
// or windowWillExitFullScreen are invoked, and so a potential transition
|
||||
// could be dropped.
|
||||
fullscreen_transition_state_ = fullscreen
|
||||
? FullScreenTransitionState::ENTERING
|
||||
: FullScreenTransitionState::EXITING;
|
||||
|
||||
[window_ toggleFullScreenMode:nil];
|
||||
}
|
||||
|
||||
@@ -989,14 +1035,11 @@ void NativeWindowMac::SetKiosk(bool kiosk) {
|
||||
NSApplicationPresentationDisableHideApplication;
|
||||
[NSApp setPresentationOptions:options];
|
||||
is_kiosk_ = true;
|
||||
was_fullscreen_ = IsFullscreen();
|
||||
if (!was_fullscreen_)
|
||||
SetFullScreen(true);
|
||||
SetFullScreen(true);
|
||||
} else if (!kiosk && is_kiosk_) {
|
||||
is_kiosk_ = false;
|
||||
if (!was_fullscreen_)
|
||||
SetFullScreen(false);
|
||||
[NSApp setPresentationOptions:kiosk_options_];
|
||||
is_kiosk_ = false;
|
||||
SetFullScreen(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,7 +1331,12 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
const bool no_rounded_corner =
|
||||
[window_ styleMask] & NSWindowStyleMaskFullSizeContentView;
|
||||
if (!has_frame() && !is_modal() && !no_rounded_corner) {
|
||||
CGFloat radius = 5.0f; // default corner radius
|
||||
CGFloat radius;
|
||||
if (@available(macOS 11.0, *)) {
|
||||
radius = 9.0f;
|
||||
} else {
|
||||
radius = 5.0f; // smaller corner radius on older versions
|
||||
}
|
||||
CGFloat dimension = 2 * radius + 1;
|
||||
NSSize size = NSMakeSize(dimension, dimension);
|
||||
NSImage* maskImage = [NSImage imageWithSize:size
|
||||
@@ -1547,7 +1595,6 @@ void NativeWindowMac::NotifyWindowEnterFullScreen() {
|
||||
|
||||
void NativeWindowMac::NotifyWindowLeaveFullScreen() {
|
||||
NativeWindow::NotifyWindowLeaveFullScreen();
|
||||
exiting_fullscreen_ = false;
|
||||
}
|
||||
|
||||
void NativeWindowMac::NotifyWindowWillEnterFullScreen() {
|
||||
@@ -1566,7 +1613,7 @@ void NativeWindowMac::NotifyWindowWillLeaveFullScreen() {
|
||||
InternalSetStandardButtonsVisibility(false);
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
}
|
||||
exiting_fullscreen_ = true;
|
||||
|
||||
RedrawTrafficLights();
|
||||
}
|
||||
|
||||
|
||||
@@ -333,6 +333,10 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||
aura::Window* window = GetNativeWindow();
|
||||
if (window)
|
||||
window->AddPreTargetHandler(this);
|
||||
|
||||
// On linux after the widget is initialized we might have to force set the
|
||||
// bounds if the bounds are smaller than the current display
|
||||
SetBounds(gfx::Rect(GetPosition(), bounds.size()), false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 13,0,0,15
|
||||
PRODUCTVERSION 13,0,0,15
|
||||
FILEVERSION 13,0,0,20
|
||||
PRODUCTVERSION 13,0,0,20
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -223,11 +223,23 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
if (is_simple_fs || always_simple_fs) {
|
||||
shell_->SetSimpleFullScreen(!is_simple_fs);
|
||||
} else {
|
||||
bool maximizable = shell_->IsMaximizable();
|
||||
[super toggleFullScreen:sender];
|
||||
if (shell_->IsVisible()) {
|
||||
// Until 10.13, AppKit would obey a call to -toggleFullScreen: made inside
|
||||
// windowDidEnterFullScreen & windowDidExitFullScreen. Starting in 10.13,
|
||||
// it behaves as though the transition is still in progress and just emits
|
||||
// "not in a fullscreen state" when trying to exit fullscreen in the same
|
||||
// runloop that entered it. To handle this, invoke -toggleFullScreen:
|
||||
// asynchronously.
|
||||
[super performSelector:@selector(toggleFullScreen:)
|
||||
withObject:nil
|
||||
afterDelay:0];
|
||||
} else {
|
||||
[super toggleFullScreen:sender];
|
||||
}
|
||||
|
||||
// Exiting fullscreen causes Cocoa to redraw the NSWindow, which resets
|
||||
// the enabled state for NSWindowZoomButton. We need to persist it.
|
||||
bool maximizable = shell_->IsMaximizable();
|
||||
shell_->SetMaximizable(maximizable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
|
||||
using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||
using FullScreenTransitionState =
|
||||
electron::NativeWindowMac::FullScreenTransitionState;
|
||||
|
||||
@implementation ElectronNSWindowDelegate
|
||||
|
||||
@@ -213,23 +215,36 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
|
||||
shell_->SetFullScreenTransitionState(FullScreenTransitionState::ENTERING);
|
||||
|
||||
shell_->NotifyWindowWillEnterFullScreen();
|
||||
|
||||
// Setting resizable to true before entering fullscreen.
|
||||
is_resizable_ = shell_->IsResizable();
|
||||
shell_->SetResizable(true);
|
||||
}
|
||||
|
||||
- (void)windowDidEnterFullScreen:(NSNotification*)notification {
|
||||
shell_->SetFullScreenTransitionState(FullScreenTransitionState::NONE);
|
||||
|
||||
shell_->NotifyWindowEnterFullScreen();
|
||||
|
||||
shell_->HandlePendingFullscreenTransitions();
|
||||
}
|
||||
|
||||
- (void)windowWillExitFullScreen:(NSNotification*)notification {
|
||||
shell_->SetFullScreenTransitionState(FullScreenTransitionState::EXITING);
|
||||
|
||||
shell_->NotifyWindowWillLeaveFullScreen();
|
||||
}
|
||||
|
||||
- (void)windowDidExitFullScreen:(NSNotification*)notification {
|
||||
shell_->SetFullScreenTransitionState(FullScreenTransitionState::NONE);
|
||||
|
||||
shell_->SetResizable(is_resizable_);
|
||||
shell_->NotifyWindowLeaveFullScreen();
|
||||
|
||||
shell_->HandlePendingFullscreenTransitions();
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification*)notification {
|
||||
|
||||
@@ -14,24 +14,32 @@
|
||||
|
||||
namespace platform_util {
|
||||
|
||||
void TrashItemOnBlockingThread(
|
||||
const base::FilePath& full_path,
|
||||
base::OnceCallback<void(bool, const std::string&)> callback) {
|
||||
struct TrashItemResult {
|
||||
bool success;
|
||||
std::string error;
|
||||
};
|
||||
|
||||
TrashItemResult TrashItemOnBlockingThread(const base::FilePath& full_path) {
|
||||
std::string error;
|
||||
bool success = internal::PlatformTrashItem(full_path, &error);
|
||||
content::GetUIThreadTaskRunner({})->PostTask(
|
||||
FROM_HERE, base::BindOnce(std::move(callback), success, error));
|
||||
return {success, error};
|
||||
}
|
||||
|
||||
void TrashItem(const base::FilePath& full_path,
|
||||
base::OnceCallback<void(bool, const std::string&)> callback) {
|
||||
// XXX: is continue_on_shutdown right?
|
||||
base::ThreadPool::PostTask(FROM_HERE,
|
||||
{base::MayBlock(), base::WithBaseSyncPrimitives(),
|
||||
base::TaskPriority::USER_BLOCKING,
|
||||
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
|
||||
base::BindOnce(&TrashItemOnBlockingThread,
|
||||
full_path, std::move(callback)));
|
||||
base::ThreadPool::PostTaskAndReplyWithResult(
|
||||
FROM_HERE,
|
||||
{base::MayBlock(), base::WithBaseSyncPrimitives(),
|
||||
base::TaskPriority::USER_BLOCKING,
|
||||
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
|
||||
base::BindOnce(&TrashItemOnBlockingThread, full_path),
|
||||
base::BindOnce(
|
||||
[](base::OnceCallback<void(bool, const std::string&)> callback,
|
||||
TrashItemResult result) {
|
||||
std::move(callback).Run(result.success, result.error);
|
||||
},
|
||||
std::move(callback)));
|
||||
}
|
||||
|
||||
} // namespace platform_util
|
||||
|
||||
@@ -1721,6 +1721,8 @@ describe('default behavior', () => {
|
||||
});
|
||||
|
||||
describe('window-all-closed', () => {
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('quits when the app does not handle the event', async () => {
|
||||
const result = await runTestApp('window-all-closed');
|
||||
expect(result).to.equal(false);
|
||||
@@ -1730,6 +1732,17 @@ describe('default behavior', () => {
|
||||
const result = await runTestApp('window-all-closed', '--handle-event');
|
||||
expect(result).to.equal(true);
|
||||
});
|
||||
|
||||
it('should omit closed windows from getAllWindows', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const len = new Promise(resolve => {
|
||||
app.on('window-all-closed', () => {
|
||||
resolve(BrowserWindow.getAllWindows().length);
|
||||
});
|
||||
});
|
||||
w.close();
|
||||
expect(await len).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('user agent fallback', () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as http from 'http';
|
||||
import { AddressInfo } from 'net';
|
||||
import { app, BrowserWindow, BrowserView, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents, BrowserWindowConstructorOptions } from 'electron/main';
|
||||
|
||||
import { emittedOnce, emittedUntil } from './events-helpers';
|
||||
import { emittedOnce, emittedUntil, emittedNTimes } from './events-helpers';
|
||||
import { ifit, ifdescribe, defer, delay } from './spec-helpers';
|
||||
import { closeWindow, closeAllWindows } from './window-helpers';
|
||||
|
||||
@@ -4220,6 +4220,42 @@ describe('BrowserWindow module', () => {
|
||||
expect(w.isFullScreen()).to.be.false('isFullScreen');
|
||||
});
|
||||
|
||||
it('handles several transitions starting with fullscreen', async () => {
|
||||
const w = new BrowserWindow({ fullscreen: true, show: true });
|
||||
|
||||
expect(w.isFullScreen()).to.be.true('not fullscreen');
|
||||
|
||||
w.setFullScreen(false);
|
||||
w.setFullScreen(true);
|
||||
|
||||
const enterFullScreen = emittedNTimes(w, 'enter-full-screen', 2);
|
||||
await enterFullScreen;
|
||||
|
||||
expect(w.isFullScreen()).to.be.true('not fullscreen');
|
||||
|
||||
await delay();
|
||||
const leaveFullScreen = emittedOnce(w, 'leave-full-screen');
|
||||
w.setFullScreen(false);
|
||||
await leaveFullScreen;
|
||||
|
||||
expect(w.isFullScreen()).to.be.false('is fullscreen');
|
||||
});
|
||||
|
||||
it('handles several transitions in close proximity', async () => {
|
||||
const w = new BrowserWindow();
|
||||
|
||||
expect(w.isFullScreen()).to.be.false('is fullscreen');
|
||||
|
||||
w.setFullScreen(true);
|
||||
w.setFullScreen(false);
|
||||
w.setFullScreen(true);
|
||||
|
||||
const enterFullScreen = emittedNTimes(w, 'enter-full-screen', 2);
|
||||
await enterFullScreen;
|
||||
|
||||
expect(w.isFullScreen()).to.be.true('not fullscreen');
|
||||
});
|
||||
|
||||
it('does not crash when exiting simpleFullScreen (properties)', async () => {
|
||||
const w = new BrowserWindow();
|
||||
w.setSimpleFullScreen(true);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { BrowserWindow, app } from 'electron/main';
|
||||
import { shell } from 'electron/common';
|
||||
import { closeAllWindows } from './window-helpers';
|
||||
import { emittedOnce } from './events-helpers';
|
||||
import { ifit } from './spec-helpers';
|
||||
import * as http from 'http';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
@@ -62,6 +63,8 @@ describe('shell module', () => {
|
||||
});
|
||||
|
||||
describe('shell.trashItem()', () => {
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('moves an item to the trash', async () => {
|
||||
const dir = await fs.mkdtemp(path.resolve(app.getPath('temp'), 'electron-shell-spec-'));
|
||||
const filename = path.join(dir, 'temp-to-be-deleted');
|
||||
@@ -74,5 +77,11 @@ describe('shell module', () => {
|
||||
const filename = path.join(app.getPath('temp'), 'does-not-exist');
|
||||
await expect(shell.trashItem(filename)).to.eventually.be.rejected();
|
||||
});
|
||||
|
||||
ifit(!(process.platform === 'win32' && process.arch === 'ia32'))('works in the renderer process', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
|
||||
w.loadURL('about:blank');
|
||||
await expect(w.webContents.executeJavaScript('require(\'electron\').shell.trashItem(\'does-not-exist\')')).to.be.rejectedWith(/does-not-exist|Failed to move item|Failed to create FileOperation/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1447,7 +1447,13 @@ describe('font fallback', () => {
|
||||
const fonts = await getRenderedFonts(html);
|
||||
expect(fonts).to.be.an('array');
|
||||
expect(fonts).to.have.length(1);
|
||||
if (process.platform === 'win32') { expect(fonts[0].familyName).to.equal('Arial'); } else if (process.platform === 'darwin') { expect(fonts[0].familyName).to.equal('Helvetica'); } else if (process.platform === 'linux') { expect(fonts[0].familyName).to.equal('DejaVu Sans'); } // I think this depends on the distro? We don't specify a default.
|
||||
if (process.platform === 'win32') {
|
||||
expect(fonts[0].familyName).to.equal('Arial');
|
||||
} else if (process.platform === 'darwin') {
|
||||
expect(fonts[0].familyName).to.equal('Helvetica');
|
||||
} else if (process.platform === 'linux') {
|
||||
expect(fonts[0].familyName).to.equal('DejaVu Sans');
|
||||
} // I think this depends on the distro? We don't specify a default.
|
||||
});
|
||||
|
||||
ifit(process.platform !== 'linux')('should fall back to Japanese font for sans-serif Japanese script', async function () {
|
||||
@@ -1495,8 +1501,8 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await closeAllWindows()
|
||||
;(w as any) = null;
|
||||
await closeAllWindows();
|
||||
(w as any) = null;
|
||||
server.close();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user