Skip to content

Commit

Permalink
feat: update app.{set|get}LoginItemSettings(settings)
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Feb 14, 2023
1 parent 8b3e498 commit 03e8bcf
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 62 deletions.
38 changes: 19 additions & 19 deletions docs/api/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -1268,28 +1268,22 @@ Returns `boolean` - Whether the current desktop environment is Unity launcher.
### `app.getLoginItemSettings([options])` _macOS_ _Windows_

* `options` Object (optional)
* `path` string (optional) _Windows_ - The executable path to compare against.
Defaults to `process.execPath`.
* `args` string[] (optional) _Windows_ - The command-line arguments to compare
against. Defaults to an empty array.
* `type` (optional) string _macOS_ - Can be one of `mainAppService`, `agentService`, `daemonService`, or `loginItemService`. Defaults to `mainAppService`. Only available on macOS 13 and up.
* `name` string (optional) _macOS_ - The name of the service. Required if `type` is non-default. Only available on macOS 13 and up.
* `path` string (optional) _Windows_ - The executable path to compare against. Defaults to `process.execPath`.
* `args` string[] (optional) _Windows_ - The command-line arguments to compare against. Defaults to an empty array.

If you provided `path` and `args` options to `app.setLoginItemSettings`, then you
need to pass the same arguments here for `openAtLogin` to be set correctly.

Returns `Object`:

* `openAtLogin` boolean - `true` if the app is set to open at login.
* `openAsHidden` boolean _macOS_ - `true` if the app is set to open as hidden at login.
This setting is not available on [MAS builds][mas-builds].
* `wasOpenedAtLogin` boolean _macOS_ - `true` if the app was opened at login
automatically. This setting is not available on [MAS builds][mas-builds].
* `wasOpenedAsHidden` boolean _macOS_ - `true` if the app was opened as a hidden login
item. This indicates that the app should not open any windows at startup.
This setting is not available on [MAS builds][mas-builds].
* `restoreState` boolean _macOS_ - `true` if the app was opened as a login item that
should restore the state from the previous session. This indicates that the
app should restore the windows that were open the last time the app was
closed. This setting is not available on [MAS builds][mas-builds].
* `openAsHidden` boolean _macOS_ - `true` if the app is set to open as hidden at login. This does not work on macOS 13 and up.
* `wasOpenedAtLogin` boolean _macOS_ - `true` if the app was opened at login automatically. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `wasOpenedAsHidden` boolean _macOS_ - `true` if the app was opened as a hidden login item. This indicates that the app should not open any windows at startup. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `restoreState` boolean _macOS_ - `true` if the app was opened as a login item that should restore the state from the previous session. This indicates that the app should restore the windows that were open the last time the app was closed. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `status` string _macOS_ - can be one of `not-registered`, `enabled`, `requires-approval`, or `not-found`.
* `executableWillLaunchAtLogin` boolean _Windows_ - `true` if app is set to open at login and its run key is not deactivated. This differs from `openAtLogin` as it ignores the `args` option, this property will be true if the given executable would be launched at login with **any** arguments.
* `launchItems` Object[] _Windows_
* `name` string _Windows_ - name value of a registry entry.
Expand All @@ -1303,10 +1297,13 @@ Returns `Object`:
* `settings` Object
* `openAtLogin` boolean (optional) - `true` to open the app at login, `false` to remove
the app as a login item. Defaults to `false`.
* `openAsHidden` boolean (optional) _macOS_ - `true` to open the app as hidden. Defaults to
`false`. The user can edit this setting from the System Preferences so
`app.getLoginItemSettings().wasOpenedAsHidden` should be checked when the app
is opened to know the current value. This setting is not available on [MAS builds][mas-builds].
* `openAsHidden` boolean (optional) _macOS_ - `true` to open the app as hidden. Defaults to `false`. The user can edit this setting from the System Preferences so `app.getLoginItemSettings().wasOpenedAsHidden` should be checked when the app is opened to know the current value. This setting is not available on [MAS build
s][mas-builds] or on macOS 13 and up.
* `type` string (optional) _macOS_ - The type of service to add as a login item. Defaults to `mainAppService`.
* `mainAppService` - The primary application.
* `agentService` - The property list name for a launch agent. The property list name must correspond to a property list in the app’s `Contents/Library/LaunchAgents` directory.
* `daemonService` string (optional) _macOS_ - The property list name for a launch agent. The property list name must correspond to a property list in the app’s `Contents/Library/LaunchDaemons` directory.
* `loginItemService` string (optional) _macOS_ - The property list name for a login item service. The property list name must correspond to a property list in the app’s `Contents/Library/LoginItems` directory.
* `path` string (optional) _Windows_ - The executable to launch at login.
Defaults to `process.execPath`.
* `args` string[] (optional) _Windows_ - The command-line arguments to pass to
Expand All @@ -1315,6 +1312,7 @@ Returns `Object`:
* `enabled` boolean (optional) _Windows_ - `true` will change the startup approved registry key and `enable / disable` the App in Task Manager and Windows Settings.
Defaults to `true`.
* `name` string (optional) _Windows_ - value name to write into registry. Defaults to the app's AppUserModelId().

Set the app's login item settings.

To work with Electron's `autoUpdater` on Windows, which uses [Squirrel][Squirrel-Windows],
Expand All @@ -1336,6 +1334,8 @@ app.setLoginItemSettings({
})
```

For more information about setting different services as login items on macOS 13 and up, see [`SMAppService`](https://developer.apple.com/documentation/servicemanagement/smappservice?language=objc).

### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_

Returns `boolean` - `true` if Chrome's accessibility support is enabled,
Expand Down
18 changes: 13 additions & 5 deletions shell/browser/api/electron_api_app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@

#if BUILDFLAG(IS_MAC)
#include <CoreFoundation/CoreFoundation.h>
#include "base/mac/mac_util.h"
#include "shell/browser/ui/cocoa/electron_bundle_mover.h"
#endif

Expand Down Expand Up @@ -393,29 +394,36 @@ struct Converter<Browser::LoginItemSettings> {
return false;

dict.Get("openAtLogin", &(out->open_at_login));
dict.Get("type", &(out->open_at_login));
dict.Get("openAsHidden", &(out->open_as_hidden));
dict.Get("path", &(out->path));
dict.Get("args", &(out->args));
#if BUILDFLAG(IS_WIN)
dict.Get("name", &(out->name));
dict.Get("enabled", &(out->enabled));
#elif BUILDFLAG(IS_MAC)
dict.Get("name", &(out->name));
dict.Get("type", &(out->type));
#endif
return true;
}

static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
Browser::LoginItemSettings val) {
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
dict.Set("openAtLogin", val.open_at_login);
dict.Set("openAsHidden", val.open_as_hidden);
dict.Set("restoreState", val.restore_state);
dict.Set("wasOpenedAtLogin", val.opened_at_login);
dict.Set("wasOpenedAsHidden", val.opened_as_hidden);
#if BUILDFLAG(IS_WIN)
dict.Set("launchItems", val.launch_items);
dict.Set("executableWillLaunchAtLogin",
val.executable_will_launch_at_login);
#elif BUILDFLAG(IS_MAC)
if (base::mac::IsAtLeastOS13())
dict.Set("status", val.status);
#endif
dict.Set("openAtLogin", val.open_at_login);
dict.Set("openAsHidden", val.open_as_hidden);
dict.Set("restoreState", val.restore_state);
dict.Set("wasOpenedAtLogin", val.opened_at_login);
dict.Set("wasOpenedAsHidden", val.opened_as_hidden);
return dict.GetHandle();
}
};
Expand Down
12 changes: 8 additions & 4 deletions shell/browser/browser.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ class Browser : public WindowListObserver {
std::u16string path;
std::vector<std::u16string> args;

#if BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_MAC)
std::string type = "mainAppService";
std::string name;
std::string status;
#elif BUILDFLAG(IS_WIN)
// used in browser::setLoginItemSettings
bool enabled = true;
std::wstring name;
Expand Down Expand Up @@ -205,9 +209,9 @@ class Browser : public WindowListObserver {
void ApplyForcedRTL();

// Bounce the dock icon.
enum class BounceType {
kCritical = 0, // NSCriticalRequest
kInformational = 10, // NSInformationalRequest
enum class BounceType{
kCritical = 0, // NSCriticalRequest
kInformational = 10, // NSInformationalRequest
};
int DockBounce(BounceType type);
void DockCancelBounce(int request_id);
Expand Down
65 changes: 53 additions & 12 deletions shell/browser/browser_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <string>
#include <utility>

#import <ServiceManagement/ServiceManagement.h>

#include "base/i18n/rtl.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
Expand Down Expand Up @@ -90,6 +92,15 @@ bool CheckLoginItemStatus(bool* is_hidden) {

return true;
}

Browser::LoginItemSettings GetLoginItemSettingsDeprecated() {
Browser::LoginItemSettings settings;
settings.open_at_login = CheckLoginItemStatus(&settings.open_as_hidden);
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
return settings;
}
#endif

} // namespace
Expand Down Expand Up @@ -364,27 +375,57 @@ bool CheckLoginItemStatus(bool* is_hidden) {
const LoginItemSettings& options) {
LoginItemSettings settings;
#if IS_MAS_BUILD()
settings.open_at_login = platform_util::GetLoginItemEnabled();
const std::string enabled =
platform_util::GetLoginItemEnabled(options.type, options.name);
settings.open_at_login = enabled == "enabled";
if (@available(macOS 13, *))
settings.status = enabled;
#else
settings.open_at_login = CheckLoginItemStatus(&settings.open_as_hidden);
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
// If the app was previously set as a LoginItem with the deprecated API,
// we should report its LoginItemSettings via the old API.
LoginItemSettings settings_deprecated = GetLoginItemSettingsDeprecated();
if (@available(macOS 13, *)) {
if (settings_deprecated.open_at_login) {
settings = settings_deprecated;
} else {
const std::string enabled =
platform_util::GetLoginItemEnabled(options.type, options.name);
settings.open_at_login = enabled == "enabled";
settings.status = enabled;
}
} else {
settings = settings_deprecated;
}
#endif
return settings;
}

void Browser::SetLoginItemSettings(LoginItemSettings settings) {
#if IS_MAS_BUILD()
if (!platform_util::SetLoginItemEnabled(settings.open_at_login)) {
LOG(ERROR) << "Unable to set login item enabled on sandboxed app.";
}
platform_util::SetLoginItemEnabled(settings.type, settings.name,
settings.open_at_login);
#else
if (settings.open_at_login) {
base::mac::AddToLoginItems(base::mac::MainBundlePath(),
settings.open_as_hidden);
const base::FilePath bundle_path = base::mac::MainBundlePath();
if (@available(macOS 13, *)) {
// If the app was previously set as a LoginItem with the old API, remove it
// as a LoginItem via the old API before re-enabling with the new API.
bool previously_enabled = CheckLoginItemStatus(&settings.open_as_hidden);
if (previously_enabled) {
base::mac::RemoveFromLoginItems(bundle_path);
if (settings.open_at_login) {
platform_util::SetLoginItemEnabled(settings.type, settings.name,
settings.open_at_login);
}
} else {
platform_util::SetLoginItemEnabled(settings.type, settings.name,
settings.open_at_login);
}
} else {
base::mac::RemoveFromLoginItems(base::mac::MainBundlePath());
if (settings.open_at_login) {
base::mac::AddToLoginItems(bundle_path, settings.open_as_hidden);
} else {
base::mac::RemoveFromLoginItems(bundle_path);
}
}
#endif
}
Expand Down
7 changes: 5 additions & 2 deletions shell/common/platform_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ bool GetFolderPath(int key, base::FilePath* result);
#endif

#if BUILDFLAG(IS_MAC)
bool GetLoginItemEnabled();
bool SetLoginItemEnabled(bool enabled);
std::string GetLoginItemEnabled(const std::string& type,
const std::string& name);
bool SetLoginItemEnabled(const std::string& type,
const std::string& name,
bool enabled);
#endif

#if BUILDFLAG(IS_LINUX)
Expand Down

0 comments on commit 03e8bcf

Please sign in to comment.