2014-10-31 18:17:05 +00:00
|
|
|
// Copyright (c) 2013 GitHub, Inc.
|
2014-04-25 09:49:37 +00:00
|
|
|
// Use of this source code is governed by the MIT license that can be
|
2013-05-02 12:09:19 +00:00
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2014-04-15 01:35:26 +00:00
|
|
|
#import "atom/browser/mac/atom_application.h"
|
2013-05-02 12:09:19 +00:00
|
|
|
|
2018-01-11 22:50:35 +00:00
|
|
|
#import "atom/browser/mac/atom_application_delegate.h"
|
2017-06-26 19:14:44 +00:00
|
|
|
#include "atom/browser/mac/dict_util.h"
|
2015-04-13 12:10:51 +00:00
|
|
|
#include "atom/browser/browser.h"
|
2013-05-02 12:09:19 +00:00
|
|
|
#include "base/auto_reset.h"
|
2013-07-10 08:10:38 +00:00
|
|
|
#include "base/strings/sys_string_conversions.h"
|
2015-04-12 17:44:27 +00:00
|
|
|
#include "content/public/browser/browser_accessibility_state.h"
|
|
|
|
|
2017-09-14 07:12:34 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
inline void dispatch_sync_main(dispatch_block_t block) {
|
|
|
|
if ([NSThread isMainThread])
|
|
|
|
block();
|
|
|
|
else
|
|
|
|
dispatch_sync(dispatch_get_main_queue(), block);
|
2017-08-09 17:28:43 +00:00
|
|
|
}
|
|
|
|
|
2017-09-14 07:12:34 +00:00
|
|
|
} // namespace
|
|
|
|
|
2013-05-02 12:09:19 +00:00
|
|
|
@implementation AtomApplication
|
|
|
|
|
2013-05-30 08:03:10 +00:00
|
|
|
+ (AtomApplication*)sharedApplication {
|
|
|
|
return (AtomApplication*)[super sharedApplication];
|
|
|
|
}
|
|
|
|
|
2018-01-11 22:50:35 +00:00
|
|
|
- (void)terminate:(id)sender {
|
|
|
|
AtomApplicationDelegate* atomDelegate = (AtomApplicationDelegate*) [NSApp delegate];
|
|
|
|
[atomDelegate tryToTerminateApp:self];
|
|
|
|
}
|
|
|
|
|
2013-05-02 12:09:19 +00:00
|
|
|
- (BOOL)isHandlingSendEvent {
|
|
|
|
return handlingSendEvent_;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)sendEvent:(NSEvent*)event {
|
|
|
|
base::AutoReset<BOOL> scoper(&handlingSendEvent_, YES);
|
|
|
|
[super sendEvent:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
|
|
|
|
handlingSendEvent_ = handlingSendEvent;
|
|
|
|
}
|
|
|
|
|
2016-05-05 07:38:47 +00:00
|
|
|
- (void)setCurrentActivity:(NSString*)type
|
2016-05-23 15:49:46 +00:00
|
|
|
withUserInfo:(NSDictionary*)userInfo
|
|
|
|
withWebpageURL:(NSURL*)webpageURL {
|
2016-05-05 07:38:47 +00:00
|
|
|
currentActivity_ = base::scoped_nsobject<NSUserActivity>(
|
|
|
|
[[NSUserActivity alloc] initWithActivityType:type]);
|
|
|
|
[currentActivity_ setUserInfo:userInfo];
|
2016-05-23 15:49:46 +00:00
|
|
|
[currentActivity_ setWebpageURL:webpageURL];
|
2017-09-14 07:12:34 +00:00
|
|
|
[currentActivity_ setDelegate:self];
|
2016-05-05 07:38:47 +00:00
|
|
|
[currentActivity_ becomeCurrent];
|
2017-08-07 19:28:00 +00:00
|
|
|
[currentActivity_ setNeedsSave:YES];
|
2016-05-03 21:57:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSUserActivity*)getCurrentActivity {
|
2016-05-04 18:28:49 +00:00
|
|
|
return currentActivity_.get();
|
2016-05-03 21:57:16 +00:00
|
|
|
}
|
|
|
|
|
2017-06-26 19:14:44 +00:00
|
|
|
- (void)invalidateCurrentActivity {
|
2017-09-14 07:12:34 +00:00
|
|
|
if (currentActivity_) {
|
|
|
|
[currentActivity_ invalidate];
|
2017-06-26 19:14:44 +00:00
|
|
|
currentActivity_.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 07:12:34 +00:00
|
|
|
- (void)updateCurrentActivity:(NSString*)type
|
2017-06-26 19:14:44 +00:00
|
|
|
withUserInfo:(NSDictionary*)userInfo {
|
2017-09-14 07:12:34 +00:00
|
|
|
if (currentActivity_) {
|
|
|
|
[currentActivity_ addUserInfoEntriesFromDictionary:userInfo];
|
2017-06-26 19:14:44 +00:00
|
|
|
}
|
2017-08-09 15:09:47 +00:00
|
|
|
|
|
|
|
[handoffLock_ lock];
|
|
|
|
updateReceived_ = YES;
|
|
|
|
[handoffLock_ signal];
|
|
|
|
[handoffLock_ unlock];
|
2017-06-26 19:14:44 +00:00
|
|
|
}
|
|
|
|
|
2017-08-07 19:28:00 +00:00
|
|
|
- (void)userActivityWillSave:(NSUserActivity *)userActivity {
|
2017-08-09 15:09:47 +00:00
|
|
|
__block BOOL shouldWait = NO;
|
2017-08-09 17:28:43 +00:00
|
|
|
dispatch_sync_main(^{
|
2017-08-07 19:28:00 +00:00
|
|
|
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
|
|
|
std::unique_ptr<base::DictionaryValue> user_info =
|
|
|
|
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
2017-06-26 19:14:44 +00:00
|
|
|
|
2017-08-07 19:28:00 +00:00
|
|
|
atom::Browser* browser = atom::Browser::Get();
|
2017-08-09 15:09:47 +00:00
|
|
|
shouldWait = browser->UpdateUserActivityState(activity_type, *user_info) ? YES : NO;
|
2017-08-07 19:28:00 +00:00
|
|
|
});
|
2017-08-09 15:09:47 +00:00
|
|
|
|
|
|
|
if (shouldWait) {
|
|
|
|
[handoffLock_ lock];
|
|
|
|
updateReceived_ = NO;
|
|
|
|
while (!updateReceived_) {
|
|
|
|
BOOL isSignaled = [handoffLock_ waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
|
2017-09-14 07:12:34 +00:00
|
|
|
if (!isSignaled) break;
|
2017-08-09 15:09:47 +00:00
|
|
|
}
|
|
|
|
[handoffLock_ unlock];
|
|
|
|
}
|
|
|
|
|
2017-08-02 17:41:48 +00:00
|
|
|
[userActivity setNeedsSave:YES];
|
2017-06-26 19:14:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)userActivityWasContinued:(NSUserActivity *)userActivity {
|
2017-08-07 19:28:00 +00:00
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
|
|
|
std::unique_ptr<base::DictionaryValue> user_info =
|
2017-06-26 19:14:44 +00:00
|
|
|
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
|
|
|
|
2017-08-07 19:28:00 +00:00
|
|
|
atom::Browser* browser = atom::Browser::Get();
|
|
|
|
browser->UserActivityWasContinued(activity_type, *user_info);
|
|
|
|
});
|
2017-06-26 19:14:44 +00:00
|
|
|
[userActivity setNeedsSave:YES];
|
|
|
|
}
|
|
|
|
|
2013-07-10 08:10:38 +00:00
|
|
|
- (void)awakeFromNib {
|
|
|
|
[[NSAppleEventManager sharedAppleEventManager]
|
|
|
|
setEventHandler:self
|
|
|
|
andSelector:@selector(handleURLEvent:withReplyEvent:)
|
|
|
|
forEventClass:kInternetEventClass
|
|
|
|
andEventID:kAEGetURL];
|
2017-08-09 15:09:47 +00:00
|
|
|
|
|
|
|
handoffLock_ = [NSCondition new];
|
2013-07-10 08:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
|
|
|
|
withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
|
|
|
|
NSString* url = [
|
|
|
|
[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
|
|
|
atom::Browser::Get()->OpenURL(base::SysNSStringToUTF8(url));
|
|
|
|
}
|
|
|
|
|
2015-10-08 22:56:26 +00:00
|
|
|
- (bool)voiceOverEnabled {
|
|
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
|
|
[defaults addSuiteNamed:@"com.apple.universalaccess"];
|
|
|
|
[defaults synchronize];
|
|
|
|
|
|
|
|
return [defaults boolForKey:@"voiceOverOnOffKey"];
|
|
|
|
}
|
|
|
|
|
2015-04-12 17:44:27 +00:00
|
|
|
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
|
2015-04-13 12:10:51 +00:00
|
|
|
// Undocumented attribute that VoiceOver happens to set while running.
|
2015-04-12 17:44:27 +00:00
|
|
|
// Chromium uses this too, even though it's not exactly right.
|
|
|
|
if ([attribute isEqualToString:@"AXEnhancedUserInterface"]) {
|
2015-10-08 22:56:26 +00:00
|
|
|
bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]);
|
|
|
|
[self updateAccessibilityEnabled:enableAccessibility];
|
2015-04-12 17:44:27 +00:00
|
|
|
}
|
2017-08-19 20:18:12 +00:00
|
|
|
else if ([attribute isEqualToString:@"AXManualAccessibility"]) {
|
|
|
|
[self updateAccessibilityEnabled:[value boolValue]];
|
|
|
|
}
|
2015-04-12 17:44:27 +00:00
|
|
|
return [super accessibilitySetValue:value forAttribute:attribute];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateAccessibilityEnabled:(BOOL)enabled {
|
2015-04-13 12:10:51 +00:00
|
|
|
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
2015-04-12 17:44:27 +00:00
|
|
|
|
|
|
|
if (enabled) {
|
|
|
|
ax_state->OnScreenReaderDetected();
|
|
|
|
} else {
|
|
|
|
ax_state->DisableAccessibility();
|
|
|
|
}
|
2016-07-11 21:09:01 +00:00
|
|
|
|
2016-07-11 21:32:14 +00:00
|
|
|
atom::Browser::Get()->OnAccessibilitySupportChanged();
|
2015-04-12 17:44:27 +00:00
|
|
|
}
|
|
|
|
|
2016-10-10 20:30:58 +00:00
|
|
|
- (void)orderFrontStandardAboutPanel:(id)sender {
|
|
|
|
atom::Browser::Get()->ShowAboutPanel();
|
|
|
|
}
|
|
|
|
|
2013-05-02 12:09:19 +00:00
|
|
|
@end
|