Merge pull request #10856 from dittos/mas-login-helper
Implement login helper to manage login item in Mac App Store build
This commit is contained in:
commit
4b8ab8fc97
9 changed files with 138 additions and 18 deletions
11
atom/app/atom_login_helper.mm
Normal file
11
atom/app/atom_login_helper.mm
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
|
||||||
|
pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
|
||||||
|
NSString* path = [NSString pathWithComponents:pathComponents];
|
||||||
|
[[NSWorkspace sharedWorkspace] launchApplication:path];
|
||||||
|
[pool drain];
|
||||||
|
return 0;
|
||||||
|
}
|
16
atom/app/resources/mac/loginhelper-Info.plist
Normal file
16
atom/app/resources/mac/loginhelper-Info.plist
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${ATOM_BUNDLE_ID}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>LSBackgroundOnly</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
|
|
||||||
|
#include "atom/common/platform_util.h"
|
||||||
#include "atom/browser/mac/atom_application.h"
|
#include "atom/browser/mac/atom_application.h"
|
||||||
#include "atom/browser/mac/atom_application_delegate.h"
|
#include "atom/browser/mac/atom_application_delegate.h"
|
||||||
#include "atom/browser/mac/dict_util.h"
|
#include "atom/browser/mac/dict_util.h"
|
||||||
|
@ -193,19 +194,27 @@ bool Browser::UpdateUserActivityState(const std::string& type,
|
||||||
Browser::LoginItemSettings Browser::GetLoginItemSettings(
|
Browser::LoginItemSettings Browser::GetLoginItemSettings(
|
||||||
const LoginItemSettings& options) {
|
const LoginItemSettings& options) {
|
||||||
LoginItemSettings settings;
|
LoginItemSettings settings;
|
||||||
|
#if defined(MAS_BUILD)
|
||||||
|
settings.open_at_login = platform_util::GetLoginItemEnabled();
|
||||||
|
#else
|
||||||
settings.open_at_login = base::mac::CheckLoginItemStatus(
|
settings.open_at_login = base::mac::CheckLoginItemStatus(
|
||||||
&settings.open_as_hidden);
|
&settings.open_as_hidden);
|
||||||
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
|
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
|
||||||
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
|
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
|
||||||
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
|
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
|
||||||
|
#endif
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
|
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
|
||||||
|
#if defined(MAS_BUILD)
|
||||||
|
platform_util::SetLoginItemEnabled(settings.open_at_login);
|
||||||
|
#else
|
||||||
if (settings.open_at_login)
|
if (settings.open_at_login)
|
||||||
base::mac::AddToLoginItems(settings.open_as_hidden);
|
base::mac::AddToLoginItems(settings.open_as_hidden);
|
||||||
else
|
else
|
||||||
base::mac::RemoveFromLoginItems();
|
base::mac::RemoveFromLoginItems();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Browser::GetExecutableFileVersion() const {
|
std::string Browser::GetExecutableFileVersion() const {
|
||||||
|
|
|
@ -57,6 +57,11 @@ bool MoveItemToTrash(const base::FilePath& full_path);
|
||||||
|
|
||||||
void Beep();
|
void Beep();
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
bool GetLoginItemEnabled();
|
||||||
|
void SetLoginItemEnabled(bool enabled);
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace platform_util
|
} // namespace platform_util
|
||||||
|
|
||||||
#endif // ATOM_COMMON_PLATFORM_UTIL_H_
|
#endif // ATOM_COMMON_PLATFORM_UTIL_H_
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <ServiceManagement/ServiceManagement.h>
|
||||||
|
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
@ -98,6 +99,10 @@ std::string OpenURL(NSURL* ns_url, bool activate) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSString* GetLoginHelperBundleIdentifier() {
|
||||||
|
return [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".loginhelper"];
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace platform_util {
|
namespace platform_util {
|
||||||
|
@ -177,4 +182,26 @@ void Beep() {
|
||||||
NSBeep();
|
NSBeep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetLoginItemEnabled() {
|
||||||
|
BOOL enabled = NO;
|
||||||
|
// SMJobCopyDictionary does not work in sandbox (see rdar://13626319)
|
||||||
|
CFArrayRef jobs = SMCopyAllJobDictionaries(kSMDomainUserLaunchd);
|
||||||
|
NSArray* jobs_ = CFBridgingRelease(jobs);
|
||||||
|
NSString* identifier = GetLoginHelperBundleIdentifier();
|
||||||
|
if (jobs_ && [jobs_ count] > 0) {
|
||||||
|
for (NSDictionary* job in jobs_) {
|
||||||
|
if ([identifier isEqualToString:[job objectForKey:@"Label"]]) {
|
||||||
|
enabled = [[job objectForKey:@"OnDemand"] boolValue];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLoginItemEnabled(bool enabled) {
|
||||||
|
NSString* identifier = GetLoginHelperBundleIdentifier();
|
||||||
|
SMLoginItemSetEnabled((__bridge CFStringRef) identifier, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace platform_util
|
} // namespace platform_util
|
||||||
|
|
|
@ -893,30 +893,27 @@ need to pass the same arguments here for `openAtLogin` to be set correctly.
|
||||||
Returns `Object`:
|
Returns `Object`:
|
||||||
|
|
||||||
* `openAtLogin` Boolean - `true` if the app is set to open at login.
|
* `openAtLogin` Boolean - `true` if the app is set to open at login.
|
||||||
* `openAsHidden` Boolean - `true` if the app is set to open as hidden at login.
|
* `openAsHidden` Boolean _macOS_ - `true` if the app is set to open as hidden at login.
|
||||||
This setting is only supported on macOS.
|
This setting is not available on [MAS builds][mas-builds].
|
||||||
* `wasOpenedAtLogin` Boolean - `true` if the app was opened at login
|
* `wasOpenedAtLogin` Boolean _macOS_ - `true` if the app was opened at login
|
||||||
automatically. This setting is only supported on macOS.
|
automatically. This setting is not available on [MAS builds][mas-builds].
|
||||||
* `wasOpenedAsHidden` Boolean - `true` if the app was opened as a hidden login
|
* `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.
|
item. This indicates that the app should not open any windows at startup.
|
||||||
This setting is only supported on macOS.
|
This setting is not available on [MAS builds][mas-builds].
|
||||||
* `restoreState` Boolean - `true` if the app was opened as a login item that
|
* `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
|
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
|
app should restore the windows that were open the last time the app was
|
||||||
closed. This setting is only supported on macOS.
|
closed. This setting is not available on [MAS builds][mas-builds].
|
||||||
|
|
||||||
**Note:** This API has no effect on [MAS builds][mas-builds].
|
|
||||||
|
|
||||||
### `app.setLoginItemSettings(settings)` _macOS_ _Windows_
|
### `app.setLoginItemSettings(settings)` _macOS_ _Windows_
|
||||||
|
|
||||||
* `settings` Object
|
* `settings` Object
|
||||||
* `openAtLogin` Boolean (optional) - `true` to open the app at login, `false` to remove
|
* `openAtLogin` Boolean (optional) - `true` to open the app at login, `false` to remove
|
||||||
the app as a login item. Defaults to `false`.
|
the app as a login item. Defaults to `false`.
|
||||||
* `openAsHidden` Boolean (optional) - `true` to open the app as hidden. Defaults to
|
* `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
|
`false`. The user can edit this setting from the System Preferences so
|
||||||
`app.getLoginItemStatus().wasOpenedAsHidden` should be checked when the app
|
`app.getLoginItemStatus().wasOpenedAsHidden` should be checked when the app
|
||||||
is opened to know the current value. This setting is only supported on
|
is opened to know the current value. This setting is not available on [MAS builds][mas-builds].
|
||||||
macOS.
|
|
||||||
* `path` String (optional) _Windows_ - The executable to launch at login.
|
* `path` String (optional) _Windows_ - The executable to launch at login.
|
||||||
Defaults to `process.execPath`.
|
Defaults to `process.execPath`.
|
||||||
* `args` String[] (optional) _Windows_ - The command-line arguments to pass to
|
* `args` String[] (optional) _Windows_ - The command-line arguments to pass to
|
||||||
|
@ -944,8 +941,6 @@ app.setLoginItemSettings({
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** This API has no effect on [MAS builds][mas-builds].
|
|
||||||
|
|
||||||
### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_
|
### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_
|
||||||
|
|
||||||
Returns `Boolean` - `true` if Chrome's accessibility support is enabled,
|
Returns `Boolean` - `true` if Chrome's accessibility support is enabled,
|
||||||
|
|
|
@ -45,7 +45,7 @@ has your Team ID as value:
|
||||||
</plist>
|
</plist>
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, you need to prepare two entitlements files.
|
Then, you need to prepare three entitlements files.
|
||||||
|
|
||||||
`child.plist`:
|
`child.plist`:
|
||||||
|
|
||||||
|
@ -77,6 +77,19 @@ Then, you need to prepare two entitlements files.
|
||||||
</plist>
|
</plist>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`loginhelper.plist`:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
```
|
||||||
|
|
||||||
You have to replace `TEAM_ID` with your Team ID, and replace `your.bundle.id`
|
You have to replace `TEAM_ID` with your Team ID, and replace `your.bundle.id`
|
||||||
with the Bundle ID of your app.
|
with the Bundle ID of your app.
|
||||||
|
|
||||||
|
@ -97,6 +110,7 @@ INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)"
|
||||||
# The path of your plist files.
|
# The path of your plist files.
|
||||||
CHILD_PLIST="/path/to/child.plist"
|
CHILD_PLIST="/path/to/child.plist"
|
||||||
PARENT_PLIST="/path/to/parent.plist"
|
PARENT_PLIST="/path/to/parent.plist"
|
||||||
|
LOGINHELPER_PLIST="/path/to/loginhelper.plist"
|
||||||
|
|
||||||
FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
|
FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
|
||||||
|
|
||||||
|
@ -110,6 +124,8 @@ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP H
|
||||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
|
||||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
|
||||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"
|
||||||
|
codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper"
|
||||||
|
codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/"
|
||||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
|
||||||
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"
|
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"
|
||||||
|
|
||||||
|
@ -162,8 +178,6 @@ and the following behaviors have been changed:
|
||||||
* Video capture may not work for some machines.
|
* Video capture may not work for some machines.
|
||||||
* Certain accessibility features may not work.
|
* Certain accessibility features may not work.
|
||||||
* Apps will not be aware of DNS changes.
|
* Apps will not be aware of DNS changes.
|
||||||
* APIs for launching apps at login are disabled. See
|
|
||||||
https://github.com/electron/electron/issues/7312#issuecomment-249479237
|
|
||||||
|
|
||||||
Also, due to the usage of app sandboxing, the resources which can be accessed by
|
Also, due to the usage of app sandboxing, the resources which can be accessed by
|
||||||
the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for
|
the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for
|
||||||
|
|
40
electron.gyp
40
electron.gyp
|
@ -122,6 +122,19 @@
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
|
['mas_build==1', {
|
||||||
|
'dependencies': [
|
||||||
|
'<(project_name)_login_helper',
|
||||||
|
],
|
||||||
|
'copies': [
|
||||||
|
{
|
||||||
|
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Library/LoginItems',
|
||||||
|
'files': [
|
||||||
|
'<(PRODUCT_DIR)/<(product_name) Login Helper.app',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
],
|
],
|
||||||
}], # OS!="mac"
|
}], # OS!="mac"
|
||||||
['OS=="win"', {
|
['OS=="win"', {
|
||||||
|
@ -566,6 +579,7 @@
|
||||||
'$(SDKROOT)/System/Library/Frameworks/Quartz.framework',
|
'$(SDKROOT)/System/Library/Frameworks/Quartz.framework',
|
||||||
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
|
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
|
||||||
'$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework',
|
'$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework',
|
||||||
|
'$(SDKROOT)/System/Library/Frameworks/ServiceManagement.framework',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'mac_bundle': 1,
|
'mac_bundle': 1,
|
||||||
|
@ -684,6 +698,32 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}, # target helper
|
}, # target helper
|
||||||
|
{
|
||||||
|
'target_name': '<(project_name)_login_helper',
|
||||||
|
'product_name': '<(product_name) Login Helper',
|
||||||
|
'type': 'executable',
|
||||||
|
'sources': [
|
||||||
|
'<@(login_helper_sources)',
|
||||||
|
],
|
||||||
|
'include_dirs': [
|
||||||
|
'.',
|
||||||
|
'vendor',
|
||||||
|
'<(libchromiumcontent_src_dir)',
|
||||||
|
],
|
||||||
|
'link_settings': {
|
||||||
|
'libraries': [
|
||||||
|
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'mac_bundle': 1,
|
||||||
|
'xcode_settings': {
|
||||||
|
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).loginhelper',
|
||||||
|
'INFOPLIST_FILE': 'atom/app/resources/mac/loginhelper-Info.plist',
|
||||||
|
'OTHER_LDFLAGS': [
|
||||||
|
'-ObjC',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}, # target login_helper
|
||||||
],
|
],
|
||||||
}], # OS!="mac"
|
}], # OS!="mac"
|
||||||
],
|
],
|
||||||
|
|
|
@ -661,6 +661,9 @@
|
||||||
'atom/app/atom_library_main.h',
|
'atom/app/atom_library_main.h',
|
||||||
'atom/app/atom_library_main.mm',
|
'atom/app/atom_library_main.mm',
|
||||||
],
|
],
|
||||||
|
'login_helper_sources': [
|
||||||
|
'atom/app/atom_login_helper.mm',
|
||||||
|
],
|
||||||
'locales': [
|
'locales': [
|
||||||
'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB',
|
'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB',
|
||||||
'en-US', 'es-419', 'es', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'he',
|
'en-US', 'es-419', 'es', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'he',
|
||||||
|
|
Loading…
Reference in a new issue