Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xcode 14 modernization #3

Closed
wants to merge 4 commits into from
Closed
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
122 changes: 40 additions & 82 deletions Library/SRRecorderControl.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ typedef NS_ENUM(NSUInteger, _SRRecorderControlButtonTag)
_SRRecorderControlMainButtonTag = 2
};

@interface SRRecorderControl () <NSAccessibility, NSViewToolTipOwner>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unusual to add NSAccessibility conformance like this. What are you indicating?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want NSAccessibilityButton which will populate the role for you

@end

@implementation SRRecorderControl
{
Expand Down Expand Up @@ -146,6 +148,10 @@ - (void)_initInternalState
_shapeYRadious = _SRRecorderControlYosemiteShapeYRadius;
}

[self setAccessibilityElement:YES];
[self setAccessibilityRole:NSAccessibilityButtonRole];
[self setAccessibilityEnabled:YES];

[self setToolTip:SRLoc(@"Click to record shortcut")];
[self updateTrackingAreas];
}
Expand Down Expand Up @@ -193,6 +199,8 @@ - (void)setEnabled:(BOOL)newEnabled
// Focus ring is only drawn when view is enabled
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
[self noteFocusRingMaskChanged];

[self setAccessibilityEnabled:_enabled];
}

- (void)setObjectValue:(NSDictionary *)newObjectValue
Expand Down Expand Up @@ -422,6 +430,11 @@ - (NSString *)accessibilityLabel
return label;
}

- (NSString *)accessibilityTitle
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this duplication resolve a specific issue?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(label is intended to be a clean replacement for title, but there have definitely been bugs historically)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was done in 349fa68 - IIRC VoiceOver reads the title of the button but we were only providing the label.
It results in having VO doing a better job at reading the state of the button.

{
return [self accessibilityLabel];
}

- (NSString *)stringValue
{
if (![self.objectValue count])
Expand Down Expand Up @@ -845,102 +858,47 @@ - (id)value

#pragma mark NSAccessibility

- (BOOL)accessibilityIsIgnored
- (BOOL)accessibilityPerformPress
{
return NO;
[self beginRecording];

return YES;
}

- (NSArray *)accessibilityAttributeNames
- (BOOL)accessibilityPerformCancel
{
static NSArray *AttributeNames = nil;
static dispatch_once_t OnceToken;
dispatch_once(&OnceToken, ^
{
AttributeNames = [[super accessibilityAttributeNames] mutableCopy];
NSArray *newAttributes = @[
NSAccessibilityRoleAttribute,
NSAccessibilityTitleAttribute,
NSAccessibilityEnabledAttribute
];

for (NSString *attributeName in newAttributes)
{
if (![AttributeNames containsObject:attributeName])
[(NSMutableArray *)AttributeNames addObject:attributeName];
}
if (self.isRecording) {
[self endRecording];
}

AttributeNames = [AttributeNames copy];
});
return AttributeNames;
return self.isRecording;
}

- (id)accessibilityAttributeValue:(NSString *)anAttributeName
- (BOOL)accessibilityPerformDelete
{
if ([anAttributeName isEqualToString:NSAccessibilityRoleAttribute])
return NSAccessibilityButtonRole;
else if ([anAttributeName isEqualToString:NSAccessibilityTitleAttribute])
return self.accessibilityLabel;
else if ([anAttributeName isEqualToString:NSAccessibilityEnabledAttribute])
return @(self.enabled);
else
return [super accessibilityAttributeValue:anAttributeName];
if (self.isRecording) {
[self clearAndEndRecording];
}

return self.isRecording;
}

- (NSArray *)accessibilityActionNames
- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector
{
static NSArray *AllActions = nil;
static NSArray *ButtonStateActionNames = nil;
static NSArray *RecorderStateActionNames = nil;
// This method asks us which accessibility selector are allowed. We need
// to limit some of these based on whether we're recording. However, all
// other selectors should return the default result (otherwise we might
// block `accessibilityLabel`).

static dispatch_once_t OnceToken;
dispatch_once(&OnceToken, ^
{
AllActions = @[
NSAccessibilityPressAction,
NSAccessibilityCancelAction,
NSAccessibilityDeleteAction
];

ButtonStateActionNames = @[
NSAccessibilityPressAction
];

RecorderStateActionNames = @[
NSAccessibilityCancelAction,
NSAccessibilityDeleteAction
];
});

// List of supported actions names must be fixed for 10.6, but can vary for 10.7 and above.
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
{
if (self.enabled)
{
if (self.isRecording)
return RecorderStateActionNames;
else
return ButtonStateActionNames;
}
else
return @[];
if (selector == @selector(accessibilityPerformPress)) {
return self.enabled;
} else if (selector == @selector(accessibilityPerformCancel)) {
return self.isRecording;
} else if (selector == @selector(accessibilityPerformDelete)) {
return self.isRecording;
}
else
return AllActions;
}

- (NSString *)accessibilityActionDescription:(NSString *)anAction
{
return NSAccessibilityActionDescription(anAction);
}

- (void)accessibilityPerformAction:(NSString *)anAction
{
if ([anAction isEqualToString:NSAccessibilityPressAction])
[self beginRecording];
else if (self.isRecording && [anAction isEqualToString:NSAccessibilityCancelAction])
[self endRecording];
else if (self.isRecording && [anAction isEqualToString:NSAccessibilityDeleteAction])
[self clearAndEndRecording];
return YES;
}


Expand Down
48 changes: 35 additions & 13 deletions ShortcutRecorder.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -790,19 +790,14 @@
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0800;
LastUpgradeCheck = 1410;
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ShortcutRecorder" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
sv,
Dutch,
ru,
de,
el,
Expand Down Expand Up @@ -1122,7 +1117,9 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
Expand All @@ -1138,7 +1135,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
INFOPLIST_FILE = Demo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
PRODUCT_BUNDLE_IDENTIFIER = "com.kulakov.ShortcutRecorder.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
Expand All @@ -1160,8 +1157,10 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DEAD_CODE_STRIPPING = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
Expand All @@ -1171,7 +1170,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
INFOPLIST_FILE = Demo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
PRODUCT_BUNDLE_IDENTIFIER = "com.kulakov.ShortcutRecorder.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
Expand All @@ -1185,6 +1184,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 2.6;
DYLIB_CURRENT_VERSION = 2.15;
FRAMEWORK_VERSION = A;
Expand All @@ -1206,6 +1206,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 2.6;
DYLIB_CURRENT_VERSION = 2.15;
FRAMEWORK_VERSION = A;
Expand All @@ -1225,17 +1226,27 @@
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CLANG_X86_VECTOR_INSTRUCTIONS = ssse3;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand All @@ -1250,7 +1261,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 11.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SKIP_INSTALL = YES;
Expand All @@ -1264,12 +1275,21 @@
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
Expand All @@ -1287,7 +1307,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 11.0;
SDKROOT = macosx;
SKIP_INSTALL = YES;
WARNING_CFLAGS = "-Wall";
Expand All @@ -1300,6 +1320,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1.4;
FRAMEWORK_VERSION = A;
Expand All @@ -1308,7 +1329,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
INFOPLIST_FILE = PTHotKey/Info.plist;
INSTALL_PATH = "@rpath";
MACOSX_DEPLOYMENT_TARGET = 10.6;
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
OTHER_LDFLAGS = (
"-framework",
Foundation,
Expand All @@ -1326,13 +1347,14 @@
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1.4;
FRAMEWORK_VERSION = A;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
INFOPLIST_FILE = PTHotKey/Info.plist;
INSTALL_PATH = "@rpath";
MACOSX_DEPLOYMENT_TARGET = 10.6;
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
OTHER_LDFLAGS = (
"-framework",
Foundation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down Expand Up @@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -51,8 +49,6 @@
ReferencedContainer = "container:ShortcutRecorder.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
Loading