Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion config/nativephp.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use App\Providers\NativeAppServiceProvider;

return [
/**
* The version of your app.
Expand Down Expand Up @@ -51,7 +53,7 @@
* takes care of bootstrapping your application and configuring
* any global hotkeys, menus, windows, etc.
*/
'provider' => \App\Providers\NativeAppServiceProvider::class,
'provider' => NativeAppServiceProvider::class,

/**
* A list of environment keys that should be removed from the
Expand Down
18 changes: 13 additions & 5 deletions resources/electron/electron-plugin/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class NativePHP {
this.processes = [];
this.mainWindow = null;
this.schedulerInterval = undefined;
this.quitting = false;
}
bootstrap(app, icon, phpBinary, cert, appPath) {
initialize();
Expand Down Expand Up @@ -52,13 +53,20 @@ class NativePHP {
app.quit();
}
});
app.on('before-quit', () => {
if (this.schedulerInterval) {
clearInterval(this.schedulerInterval);
app.on('before-quit', (event) => __awaiter(this, void 0, void 0, function* () {
if (this.quitting) {
return;
}
stopAllProcesses();
this.quitting = true;
event.preventDefault();
this.killChildProcesses();
});
stopAllProcesses();
const deadline = Date.now() + 12000;
while (Object.keys(state.processes).length > 0 && Date.now() < deadline) {
yield new Promise((resolve) => setTimeout(resolve, 200));
}
app.quit();
}));
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,17 @@ function stopProcess(alias) {
if (proc === undefined) {
return;
}
state.processes[alias].settings.persistent = false;
const settings = state.processes[alias].settings;
settings.persistent = false;
console.log('Process [' + alias + '] stopping with PID [' + proc.pid + '].');
try {
killSync(proc.pid, 'SIGTERM', true);
proc.kill();
if (settings.handlesOwnShutdown && process.platform !== 'win32') {
process.kill(proc.pid, 'SIGTERM');
}
else {
killSync(proc.pid, 'SIGTERM', true);
proc.kill();
}
}
catch (_a) {
console.log('Process [' + alias + '] already exited — nothing to kill.');
Expand Down
30 changes: 25 additions & 5 deletions resources/electron/electron-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class NativePHP {
processes: ChildProcessWithoutNullStreams[] = [];
mainWindow = null;
schedulerInterval = undefined;
quitting = false;

public bootstrap(app: CrossProcessExports.App, icon: string, phpBinary: string, cert: string, appPath: string) {
initialize();
Expand Down Expand Up @@ -59,15 +60,34 @@ class NativePHP {
}
});

app.on('before-quit', () => {
if (this.schedulerInterval) {
clearInterval(this.schedulerInterval);
app.on('before-quit', async (event) => {
// We call app.quit() again at the end, which fires this handler a
// second time. Let that pass straight through so the quit happens.
if (this.quitting) {
return;
}
this.quitting = true;
event.preventDefault();

// Stop the framework's own processes first (the PHP server and the
// like). While they're still up, an incoming request could boot the
// app and spawn fresh child processes that we'd never clean up here.
this.killChildProcesses();

// close all child processes from the app
// Now the app's child processes. The ones started with `handlesOwnShutdown`
// get a plain SIGTERM rather than a tree-kill, so they can bring down
// their own children themselves before they exit.
stopAllProcesses();

this.killChildProcesses();
// Give them a moment to act on that SIGTERM (flush, persist, whatever
// they need) before we pull the plug. Each one drops out of state as
// it exits; the deadline stops a stuck process from blocking the quit.
const deadline = Date.now() + 12_000;
while (Object.keys(state.processes).length > 0 && Date.now() < deadline) {
await new Promise((resolve) => setTimeout(resolve, 200));
}

app.quit();
});

// Default open or close DevTools by F12 in development
Expand Down
19 changes: 15 additions & 4 deletions resources/electron/electron-plugin/src/server/api/childProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,25 @@ function stopProcess(alias) {
}

// Set persistent to false and prevent the process from restarting.
state.processes[alias].settings.persistent = false;
const settings = state.processes[alias].settings;
settings.persistent = false;

console.log('Process [' + alias + '] stopping with PID [' + proc.pid + '].');

try {
// @ts-ignore
killSync(proc.pid, 'SIGTERM', true); // Kill tree
proc.kill(); // Does not work but just in case. (do not put before killSync)
if (settings.handlesOwnShutdown && process.platform !== 'win32') {
// Signal this process alone, leaving its children untouched. A
// process that manages its own long-running children can then shut
// them down on its own terms before it exits, rather than having
// them killed underneath it by a tree-kill. Windows has no real
// signals (a kill there is always immediate), so we fall back to
// the tree-kill below instead of leaving the children orphaned.
process.kill(proc.pid, 'SIGTERM');
} else {
// @ts-ignore
killSync(proc.pid, 'SIGTERM', true); // Kill tree
proc.kill(); // Does not work but just in case. (do not put before killSync)
}
} catch {
console.log('Process [' + alias + '] already exited — nothing to kill.');
}
Expand Down
16 changes: 11 additions & 5 deletions src/ChildProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ChildProcess implements ChildProcessContract

public readonly bool $persistent;

public readonly bool $handlesOwnShutdown;

public readonly ?array $iniSettings;

final public function __construct(protected Client $client) {}
Expand Down Expand Up @@ -66,7 +68,8 @@ public function start(
string $alias,
?string $cwd = null,
?array $env = null,
bool $persistent = false
bool $persistent = false,
bool $handlesOwnShutdown = false
): self {
$cmd = $this->parseCommand($cmd);

Expand All @@ -76,6 +79,7 @@ public function start(
'cwd' => $cwd ?? base_path(),
'env' => $env,
'persistent' => $persistent,
'handlesOwnShutdown' => $handlesOwnShutdown,
])->json();

return $this->fromRuntimeProcess($process);
Expand All @@ -85,7 +89,7 @@ public function start(
* @param string|string[] $cmd
* @return $this
*/
public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self
public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null, bool $handlesOwnShutdown = false): self
{
$cmd = $this->parseCommand($cmd);

Expand All @@ -96,12 +100,13 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool
'env' => $env,
'persistent' => $persistent,
'iniSettings' => $iniSettings,
'handlesOwnShutdown' => $handlesOwnShutdown,
])->json();

return $this->fromRuntimeProcess($process);
}

public function node(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self
public function node(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, bool $handlesOwnShutdown = false): self
{
$cmd = $this->parseCommand($cmd);

Expand All @@ -111,6 +116,7 @@ public function node(string|array $cmd, string $alias, ?array $env = null, ?bool
'cwd' => base_path(),
'env' => $env,
'persistent' => $persistent,
'handlesOwnShutdown' => $handlesOwnShutdown,
])->json();

return $this->fromRuntimeProcess($process);
Expand All @@ -120,13 +126,13 @@ public function node(string|array $cmd, string $alias, ?array $env = null, ?bool
* @param string|string[] $cmd
* @return $this
*/
public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self
public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null, bool $handlesOwnShutdown = false): self
{
$cmd = $this->parseCommand($cmd);

$cmd = ['artisan', ...$cmd];

return $this->php($cmd, $alias, env: $env, persistent: $persistent, iniSettings: $iniSettings);
return $this->php($cmd, $alias, env: $env, persistent: $persistent, iniSettings: $iniSettings, handlesOwnShutdown: $handlesOwnShutdown);
}

public function stop(?string $alias = null): void
Expand Down
9 changes: 5 additions & 4 deletions src/Contracts/ChildProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ public function start(
string $alias,
?string $cwd = null,
?array $env = null,
bool $persistent = false
bool $persistent = false,
bool $handlesOwnShutdown = false
): self;

public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self;
public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null, bool $handlesOwnShutdown = false): self;

public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self;
public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null, bool $handlesOwnShutdown = false): self;

public function node(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self;
public function node(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, bool $handlesOwnShutdown = false): self;

public function stop(?string $alias = null): void;

Expand Down
22 changes: 12 additions & 10 deletions src/Drivers/Electron/Updater/UpdaterManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

namespace Native\Desktop\Drivers\Electron\Updater;

use Illuminate\Contracts\Foundation\Application;
use InvalidArgumentException;
use Native\Desktop\Drivers\Electron\Updater\Contracts\Updater;

class UpdaterManager
{
/**
* The application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
* @var Application
*/
protected $app;

Expand All @@ -23,7 +25,7 @@ class UpdaterManager
/**
* Create a new Updater manager instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param Application $app
* @return void
*/
public function __construct($app)
Expand All @@ -35,7 +37,7 @@ public function __construct($app)
* Get a updater provider instance by name, wrapped in a repository.
*
* @param string|null $name
* @return \Native\Desktop\Drivers\Electron\Updater\Contracts\Updater
* @return Updater
*/
public function provider($name = null)
{
Expand All @@ -48,7 +50,7 @@ public function provider($name = null)
* Get a updater provider instance.
*
* @param string|null $driver
* @return \Native\Desktop\Drivers\Electron\Updater\Contracts\Updater
* @return Updater
*/
public function driver($driver = null)
{
Expand All @@ -59,9 +61,9 @@ public function driver($driver = null)
* Resolve the given store.
*
* @param string $name
* @return \Native\Desktop\Drivers\Electron\Updater\Contracts\Updater
* @return Updater
*
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
*/
public function resolve($name)
{
Expand Down Expand Up @@ -119,7 +121,7 @@ public function setDefaultDriver($name)
/**
* Set the application instance used by the manager.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param Application $app
* @return $this
*/
public function setApplication($app)
Expand All @@ -132,7 +134,7 @@ public function setApplication($app)
/**
* Create an instance of the spaces updater driver.
*
* @return \Native\Desktop\Drivers\Electron\Updater\Contracts\Updater
* @return Updater
*/
protected function createSpacesDriver(array $config)
{
Expand All @@ -142,7 +144,7 @@ protected function createSpacesDriver(array $config)
/**
* Create an instance of the spaces updater driver.
*
* @return \Native\Desktop\Drivers\Electron\Updater\Contracts\Updater
* @return Updater
*/
protected function createS3Driver(array $config)
{
Expand All @@ -152,7 +154,7 @@ protected function createS3Driver(array $config)
/**
* Create an instance of the GitHub updater driver.
*
* @return \Native\Desktop\Drivers\Electron\Updater\Contracts\Updater
* @return Updater
*/
protected function createGitHubDriver(array $config)
{
Expand Down
8 changes: 4 additions & 4 deletions src/Facades/ChildProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
* @method static \Native\Desktop\ChildProcess|null get(string $alias = null)
* @method static \Native\Desktop\ChildProcess message(string $message, string $alias = null)
* @method static \Native\Desktop\ChildProcess restart(string $alias = null)
* @method static \Native\Desktop\ChildProcess start(string|array $cmd, string $alias, string $cwd = null, array $env = null, bool $persistent = false)
* @method static \Native\Desktop\ChildProcess node(string|array $cmd, string $alias, array $env = null, bool $persistent = false)
* @method static \Native\Desktop\ChildProcess php(string|array $cmd, string $alias, array $env = null, bool $persistent = false, ?array $iniSettings = null)
* @method static \Native\Desktop\ChildProcess artisan(string|array $cmd, string $alias, array $env = null, bool $persistent = false, ?array $iniSettings = null)
* @method static \Native\Desktop\ChildProcess start(string|array $cmd, string $alias, string $cwd = null, array $env = null, bool $persistent = false, bool $handlesOwnShutdown = false)
* @method static \Native\Desktop\ChildProcess node(string|array $cmd, string $alias, array $env = null, bool $persistent = false, bool $handlesOwnShutdown = false)
* @method static \Native\Desktop\ChildProcess php(string|array $cmd, string $alias, array $env = null, bool $persistent = false, ?array $iniSettings = null, bool $handlesOwnShutdown = false)
* @method static \Native\Desktop\ChildProcess artisan(string|array $cmd, string $alias, array $env = null, bool $persistent = false, ?array $iniSettings = null, bool $handlesOwnShutdown = false)
* @method static void stop(string $alias = null)
* @method static static when($value = null, ?callable $callback = null, ?callable $default = null)
* @method static static unless($value = null, ?callable $callback = null, ?callable $default = null)
Expand Down
3 changes: 2 additions & 1 deletion src/Facades/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Native\Desktop\Menu\Items\Radio;
use Native\Desktop\Menu\Items\Role;
use Native\Desktop\Menu\Items\Separator;
use Native\Desktop\Menu\MenuBuilder;

/**
* @method static \Native\Desktop\Menu\Menu make(MenuItem ...$items)
Expand Down Expand Up @@ -48,6 +49,6 @@ class Menu extends Facade
{
protected static function getFacadeAccessor()
{
return \Native\Desktop\Menu\MenuBuilder::class;
return MenuBuilder::class;
}
}
3 changes: 2 additions & 1 deletion src/Facades/MenuBar.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Support\Facades\Facade;
use Native\Desktop\Menu\Menu;
use Native\Desktop\MenuBar\MenuBarManager;

/**
* @method static \Native\Desktop\MenuBar\PendingCreateMenuBar create()
Expand All @@ -21,6 +22,6 @@ class MenuBar extends Facade
{
protected static function getFacadeAccessor()
{
return \Native\Desktop\MenuBar\MenuBarManager::class;
return MenuBarManager::class;
}
}
Loading