Skip to content

Commit 77f175c

Browse files
committed
Remove accessibility observer once granted access
1 parent b80d03f commit 77f175c

File tree

3 files changed

+23
-35
lines changed

3 files changed

+23
-35
lines changed

DiscreteScroll.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@
249249
buildSettings = {
250250
CODE_SIGN_STYLE = Automatic;
251251
COMBINE_HIDPI_IMAGES = YES;
252-
CURRENT_PROJECT_VERSION = 3;
252+
CURRENT_PROJECT_VERSION = 4;
253253
INFOPLIST_FILE = DiscreteScroll/Info.plist;
254254
LD_RUNPATH_SEARCH_PATHS = (
255255
"$(inherited)",
256256
"@executable_path/../Frameworks",
257257
);
258258
MACOSX_DEPLOYMENT_TARGET = 10.9;
259-
MARKETING_VERSION = 1.1.0;
259+
MARKETING_VERSION = 1.2.0;
260260
PRODUCT_BUNDLE_IDENTIFIER = com.emreyolcu.DiscreteScroll;
261261
PRODUCT_NAME = "$(TARGET_NAME)";
262262
};
@@ -267,14 +267,14 @@
267267
buildSettings = {
268268
CODE_SIGN_STYLE = Automatic;
269269
COMBINE_HIDPI_IMAGES = YES;
270-
CURRENT_PROJECT_VERSION = 3;
270+
CURRENT_PROJECT_VERSION = 4;
271271
INFOPLIST_FILE = DiscreteScroll/Info.plist;
272272
LD_RUNPATH_SEARCH_PATHS = (
273273
"$(inherited)",
274274
"@executable_path/../Frameworks",
275275
);
276276
MACOSX_DEPLOYMENT_TARGET = 10.9;
277-
MARKETING_VERSION = 1.1.0;
277+
MARKETING_VERSION = 1.2.0;
278278
PRODUCT_BUNDLE_IDENTIFIER = com.emreyolcu.DiscreteScroll;
279279
PRODUCT_NAME = "$(TARGET_NAME)";
280280
};

DiscreteScroll/main.c

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
static const CFStringRef AX_NOTIFICATION = CFSTR("com.apple.accessibility.api");
77
static bool TRUSTED;
88

9-
static CFMachPortRef TAP;
10-
static CFRunLoopSourceRef SOURCE;
11-
129
static int LINES;
1310

1411
static CGEventRef tapCallback(CGEventTapProxy proxy,
@@ -37,23 +34,14 @@ static void notificationCallback(CFNotificationCenterRef center, void *observer,
3734
CFNotificationName name, const void *object,
3835
CFDictionaryRef userInfo)
3936
{
40-
if (CFStringCompare(name, AX_NOTIFICATION, 0) == kCFCompareEqualTo) {
41-
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
42-
CFRunLoopPerformBlock(
43-
runLoop, kCFRunLoopDefaultMode, ^{
44-
bool previouslyTrusted = TRUSTED;
45-
if ((TRUSTED = AXIsProcessTrusted()) != previouslyTrusted) {
46-
CFRunLoopStop(runLoop);
47-
if (SOURCE && CFRunLoopContainsSource(runLoop, SOURCE, kCFRunLoopDefaultMode)) {
48-
CGEventTapEnable(TAP, TRUSTED);
49-
CFRunLoopRun();
50-
} else if (!TRUSTED) {
51-
CFRunLoopRun();
52-
}
53-
}
54-
}
55-
);
56-
}
37+
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
38+
CFRunLoopPerformBlock(
39+
runLoop, kCFRunLoopDefaultMode, ^{
40+
bool previouslyTrusted = TRUSTED;
41+
if ((TRUSTED = AXIsProcessTrusted()) && !previouslyTrusted)
42+
CFRunLoopStop(runLoop);
43+
}
44+
);
5745
}
5846

5947
static bool getIntPreference(CFStringRef key, int *valuePtr)
@@ -73,9 +61,10 @@ static bool getIntPreference(CFStringRef key, int *valuePtr)
7361

7462
int main(void)
7563
{
64+
CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
65+
char observer;
7666
CFNotificationCenterAddObserver(
77-
CFNotificationCenterGetDistributedCenter(), NULL,
78-
notificationCallback, AX_NOTIFICATION, NULL,
67+
center, &observer, notificationCallback, AX_NOTIFICATION, NULL,
7968
CFNotificationSuspensionBehaviorDeliverImmediately
8069
);
8170
CFDictionaryRef options = CFDictionaryCreate(
@@ -87,20 +76,21 @@ int main(void)
8776
CFRelease(options);
8877
if (!TRUSTED)
8978
CFRunLoopRun();
79+
CFNotificationCenterRemoveObserver(center, &observer, AX_NOTIFICATION, NULL);
9080

9181
if (!getIntPreference(CFSTR("lines"), &LINES))
9282
LINES = DEFAULT_LINES;
9383

94-
TAP = CGEventTapCreate(
84+
CFMachPortRef tap = CGEventTapCreate(
9585
kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
9686
CGEventMaskBit(kCGEventScrollWheel), tapCallback, NULL
9787
);
98-
if (!TAP)
88+
if (!tap)
9989
displayNoticeAndExit(CFSTR("DiscreteScroll could not create an event tap."));
100-
SOURCE = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, TAP, 0);
101-
if (!SOURCE)
90+
CFRunLoopSourceRef source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0);
91+
if (!source)
10292
displayNoticeAndExit(CFSTR("DiscreteScroll could not create a run loop source."));
103-
CFRunLoopAddSource(CFRunLoopGetCurrent(), SOURCE, kCFRunLoopDefaultMode);
93+
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
10494
CFRunLoopRun();
10595

10696
return EXIT_SUCCESS;

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ You do not need to restart the application
2121
after you grant it access to accessibility features.
2222

2323
> [!CAUTION]
24-
> You may safely toggle accessibility access
24+
> You should not revoke accessibility access
2525
> for DiscreteScroll while it is running.
26-
> *However, you should not remove it from the list of trusted applications
27-
> while it is running without first unchecking the box next to its name.
28-
> Otherwise, your mouse might become unresponsive, requiring a reboot to fix.*
26+
> Otherwise, your mouse might become unresponsive, requiring a reboot to fix.
2927
3028
If you want the application to run automatically when you log in,
3129
do the following:

0 commit comments

Comments
 (0)