Refactored code and removed notification replacing them for async calls
This commit is contained in:
parent
468d29c42d
commit
f387e67a8a
|
|
@ -76,6 +76,8 @@
|
|||
|
||||
@property (nonatomic, strong) NSStatusItem *statusBar;
|
||||
|
||||
@property (atomic, assign) BOOL isSendingAppleEvent;
|
||||
|
||||
@property (assign, nonatomic) NSInteger volumeInc;
|
||||
@property (assign, nonatomic) bool AppleRemoteConnected;
|
||||
@property (assign, nonatomic) bool StartAtLogin;
|
||||
|
|
@ -104,19 +106,7 @@
|
|||
- (BOOL)tryCreateEventTap;
|
||||
|
||||
// - (void)appleRemoteButton: (AppleRemoteEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int) count;
|
||||
|
||||
- (void)resetEventTap;
|
||||
|
||||
- (void)stopVolumeRampTimer;
|
||||
|
||||
- (void)updatePercentages;
|
||||
|
||||
- (void)wasAuthorized;
|
||||
|
||||
- (bool)createEventTap;
|
||||
|
||||
- (void)handleEventTapDisabledByUser;
|
||||
|
||||
- (void)handleAsynchronouslyTappedEventWithKeyCode:(int)keyCode
|
||||
keyState:(BOOL)keyState
|
||||
keyIsRepeat:(BOOL)keyIsRepeat
|
||||
|
|
|
|||
|
|
@ -31,14 +31,18 @@ void handleSIGTERM(int sig) {
|
|||
|
||||
#pragma mark - Tapping key stroke events
|
||||
|
||||
//static void displayPreferencesChanged(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags, void *userInfo) {
|
||||
// [[NSNotificationCenter defaultCenter] postNotificationName:@"displayResolutionHasChanged" object:NULL];
|
||||
//}
|
||||
|
||||
CGEventRef event_tap_callback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
|
||||
{
|
||||
if (type == kCGEventTapDisabledByTimeout) {
|
||||
NSLog(@"[Volume Control] Event tap disabled due to timeout. Disabling tapping.");
|
||||
AppDelegate *app = (__bridge AppDelegate *)refcon;
|
||||
if (app.isSendingAppleEvent) {
|
||||
// False positive timeout caused by TCC
|
||||
NSLog(@"[Volume Control] Tap disabled during AppleEvent/TCC dialog → restarting tap.");
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[app setTapping:YES]; // try to resume
|
||||
});
|
||||
} else {
|
||||
// Real unresponsiveness
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
AppDelegate *app = (__bridge AppDelegate *)refcon;
|
||||
[app setTapping:NO];
|
||||
|
|
@ -59,6 +63,7 @@ CGEventRef event_tap_callback(CGEventTapProxy proxy, CGEventType type, CGEventRe
|
|||
});
|
||||
return event; // always return quickly
|
||||
}
|
||||
}
|
||||
|
||||
// Pass through events we don't care about
|
||||
if (type != NX_SYSDEFINED) return event;
|
||||
|
|
@ -122,6 +127,18 @@ CGEventRef event_tap_callback(CGEventTapProxy proxy, CGEventType type, CGEventRe
|
|||
BOOL _muteDown;
|
||||
}
|
||||
|
||||
// Forward declare private methods
|
||||
- (id)runningPlayer;
|
||||
- (void)completeInitialization;
|
||||
- (void)setVolumeUp:(bool)increase;
|
||||
- (void) setItunesVolume:(NSInteger)volume;
|
||||
- (void) setSpotifyVolume:(NSInteger)volume;
|
||||
- (void) setSystemVolume:(NSInteger)volume;
|
||||
- (void)stopVolumeRampTimer;
|
||||
- (void)updatePercentages;
|
||||
- (bool)createEventTap;
|
||||
- (void)handleEventTapDisabledByUser;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Extention music applications
|
||||
|
|
@ -139,8 +156,13 @@ CGEventRef event_tap_callback(CGEventTapProxy proxy, CGEventType type, CGEventRe
|
|||
|
||||
- (double) currentVolume
|
||||
{
|
||||
AppDelegate *app = (AppDelegate *)NSApp.delegate;
|
||||
app.isSendingAppleEvent = YES;
|
||||
|
||||
double vol = [musicPlayer soundVolume];
|
||||
|
||||
app.isSendingAppleEvent = NO;
|
||||
|
||||
if (fabs(vol-[self doubleVolume])<1)
|
||||
{
|
||||
vol = [self doubleVolume];
|
||||
|
|
@ -241,7 +263,6 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
eventTap = nil;
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
|
||||
|
||||
systemAudio = nil;
|
||||
|
|
@ -268,6 +289,11 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
|
||||
preferences = nil;
|
||||
|
||||
// IMPORTANT: Use [NSApp terminate:nil] for a clean exit.
|
||||
// This ensures AppKit tears down the NSStatusItem properly
|
||||
// and preserves the status bar icon position between launches.
|
||||
// Simply returning or calling exit() would skip this cleanup
|
||||
// and cause the icon to reset to the default position.
|
||||
[NSApp terminate:nil];
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +399,7 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
{
|
||||
[volumeRampTimer invalidate];
|
||||
volumeRampTimer=nil;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"SoundFeedback" object:NULL];
|
||||
[self emitAcousticFeedback];
|
||||
|
||||
checkPlayerTimer = [NSTimer timerWithTimeInterval:checkPlayerTimeout target:self selector:@selector(resetCurrentPlayer:) userInfo:nil repeats:NO];
|
||||
[[NSRunLoop mainRunLoop] addTimer:checkPlayerTimer forMode:NSRunLoopCommonModes];
|
||||
|
|
@ -512,8 +538,7 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
|
||||
if (keyState == 1) {
|
||||
_muteDown = true;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"MuteVol" object:nil];
|
||||
// [self MuteVol:nil];
|
||||
[self MuteVol];
|
||||
} else {
|
||||
_muteDown = false;
|
||||
}
|
||||
|
|
@ -529,11 +554,8 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
|
||||
if (keyState == 1) {
|
||||
if (!self->volumeRampTimer) {
|
||||
if (keyCode == NX_KEYTYPE_SOUND_UP) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:(keyIsRepeat ? @"IncVolRamp" : @"IncVol") object:nil];
|
||||
} else {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:(keyIsRepeat ? @"DecVolRamp" : @"DecVol") object:nil];
|
||||
}
|
||||
BOOL increase = (keyCode == NX_KEYTYPE_SOUND_UP);
|
||||
[self adjustVolumeUp:increase ramp:keyIsRepeat];
|
||||
}
|
||||
} else {
|
||||
if (self->volumeRampTimer) {
|
||||
|
|
@ -559,22 +581,24 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
// NSLog(@"%d keycode (up) sent",key);
|
||||
}
|
||||
|
||||
- (void)PlayPauseMusic:(NSNotification *)aNotification
|
||||
/*
|
||||
- (void)PlayPauseMusic
|
||||
{
|
||||
[self sendMediaKey:NX_KEYTYPE_PLAY];
|
||||
}
|
||||
|
||||
- (void)NextTrackMusic:(NSNotification *)aNotification
|
||||
- (void)NextTrackMusic
|
||||
{
|
||||
[self sendMediaKey:NX_KEYTYPE_NEXT];
|
||||
}
|
||||
|
||||
- (void)PreviousTrackMusic:(NSNotification *)aNotification
|
||||
- (void)PreviousTrackMusic
|
||||
{
|
||||
[self sendMediaKey:NX_KEYTYPE_PREVIOUS];
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)MuteVol:(NSNotification *)aNotification
|
||||
- (void)MuteVol
|
||||
{
|
||||
id runningPlayerPtr = [self runningPlayer];
|
||||
|
||||
|
|
@ -594,10 +618,12 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
if (@available(macOS 16.0, *)) {
|
||||
// Running on Tahoe (2026) or newer
|
||||
} else {
|
||||
[[self->OSDManager sharedManager] showImage:OSDGraphicSpeakerMute onDisplayID:CGSMainDisplayID() priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:0 totalChiclets:(unsigned int)100 locked:NO];
|
||||
id osdMgr = [self->OSDManager sharedManager];
|
||||
if (osdMgr) {
|
||||
[osdMgr showImage:OSDGraphicSpeakerMute onDisplayID:CGSMainDisplayID() priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:0 totalChiclets:(unsigned int)100 locked:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -612,7 +638,10 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
if (@available(macOS 16.0, *)) {
|
||||
// Running on Tahoe (2026) or newer
|
||||
} else {
|
||||
[[self->OSDManager sharedManager] showImage:OSDGraphicSpeaker onDisplayID:CGSMainDisplayID() priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:(unsigned int)[runningPlayerPtr oldVolume] totalChiclets:(unsigned int)100 locked:NO];
|
||||
id osdMgr = [self->OSDManager sharedManager];
|
||||
if (osdMgr) {
|
||||
[osdMgr showImage:OSDGraphicSpeaker onDisplayID:CGSMainDisplayID() priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:(unsigned int)[runningPlayerPtr oldVolume] totalChiclets:(unsigned int)100 locked:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -634,37 +663,25 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)IncVol:(NSNotification *)aNotification
|
||||
{
|
||||
if( [[aNotification name] isEqualToString:@"IncVolRamp"] )
|
||||
{
|
||||
- (void)adjustVolumeUp:(BOOL)increase ramp:(BOOL)ramp {
|
||||
if (ramp) {
|
||||
[checkPlayerTimer invalidate];
|
||||
checkPlayerTimer = nil;
|
||||
volumeRampTimer=[NSTimer timerWithTimeInterval:volumeRampTimeInterval*(NSTimeInterval)increment target:self selector:@selector(rampVolumeUp:) userInfo:nil repeats:YES];
|
||||
|
||||
SEL selector = increase ? @selector(rampVolumeUp:) : @selector(rampVolumeDown:);
|
||||
volumeRampTimer = [NSTimer timerWithTimeInterval:volumeRampTimeInterval * (NSTimeInterval)increment
|
||||
target:self
|
||||
selector:selector
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
[[NSRunLoop mainRunLoop] addTimer:volumeRampTimer forMode:NSRunLoopCommonModes];
|
||||
|
||||
if(timerImgSpeaker) {[timerImgSpeaker invalidate]; timerImgSpeaker=nil;}
|
||||
if (timerImgSpeaker) {
|
||||
[timerImgSpeaker invalidate];
|
||||
timerImgSpeaker = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setVolumeUp:true];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)DecVol:(NSNotification *)aNotification
|
||||
{
|
||||
if( [[aNotification name] isEqualToString:@"DecVolRamp"] )
|
||||
{
|
||||
[checkPlayerTimer invalidate];
|
||||
checkPlayerTimer = nil;
|
||||
volumeRampTimer=[NSTimer timerWithTimeInterval:volumeRampTimeInterval*(NSTimeInterval)increment target:self selector:@selector(rampVolumeDown:) userInfo:nil repeats:YES];
|
||||
[[NSRunLoop mainRunLoop] addTimer:volumeRampTimer forMode:NSRunLoopCommonModes];
|
||||
|
||||
if(timerImgSpeaker) {[timerImgSpeaker invalidate]; timerImgSpeaker=nil;}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setVolumeUp:false];
|
||||
} else {
|
||||
[self setVolumeUp:increase];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -758,7 +775,7 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
return YES; // Default behavior
|
||||
}
|
||||
|
||||
- (void)emitAcousticFeedback:(NSNotification *)aNotification
|
||||
- (void)emitAcousticFeedback
|
||||
{
|
||||
if([self PlaySoundFeedback] && (_AppleCMDModifierPressed != _UseAppleCMDModifier || [[self runningPlayer] isKindOfClass:[SystemApplication class]]))
|
||||
{
|
||||
|
|
@ -770,17 +787,6 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// NSLog(@"FINISHED LAUNCHING");
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(emitAcousticFeedback:) name:@"SoundFeedback" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(IncVol:) name:@"IncVol" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(IncVol:) name:@"IncVolRamp" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(DecVol:) name:@"DecVol" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(DecVol:) name:@"DecVolRamp" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MuteVol:) name:@"MuteVol" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PlayPauseMusic:) name:@"PlayPauseMusic" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(NextTrackMusic:) name:@"NextTrackMusic" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PreviousTrackMusic:) name:@"PreviousTrackMusic" object:nil];
|
||||
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self selector: @selector(receiveWakeNote:) name:NSWorkspaceDidWakeNotification object: NULL];
|
||||
|
||||
signal(SIGTERM, handleSIGTERM);
|
||||
|
|
@ -1083,11 +1089,6 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
[self setTapping:[self Tapping]];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)resetCurrentPlayer:(NSTimer*)theTimer
|
||||
{
|
||||
// Keep memory of the current player until this timeout is reached
|
||||
|
|
@ -1153,9 +1154,9 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
if (volume<0) volume=0;
|
||||
if (volume>100) volume=100;
|
||||
|
||||
OSDGraphic image;
|
||||
NSInteger numFullBlks;
|
||||
NSInteger numQrtsBlks;
|
||||
OSDGraphic image = 0;
|
||||
NSInteger numFullBlks = 0;
|
||||
NSInteger numQrtsBlks = 0;
|
||||
|
||||
if (@available(macOS 16.0, *)) {
|
||||
// Running on Tahoe (2026) or newer
|
||||
|
|
@ -1172,7 +1173,12 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
if (@available(macOS 16.0, *)) {
|
||||
// Running on Tahoe (2026) or newer
|
||||
} else {
|
||||
[[self->OSDManager sharedManager] showImage:image onDisplayID:CGSMainDisplayID() priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:(unsigned int)(round(((numFullBlks*4+numQrtsBlks)*1.5625)*100)) totalChiclets:(unsigned int)10000 locked:NO];
|
||||
if(image) {
|
||||
id osdMgr = [self->OSDManager sharedManager];
|
||||
if (osdMgr) {
|
||||
[osdMgr showImage:image onDisplayID:CGSMainDisplayID() priority:OSDPriorityDefault msecUntilFade:1000 filledChiclets:(unsigned int)(round(((numFullBlks*4+numQrtsBlks)*1.5625)*100)) totalChiclets:(unsigned int)10000 locked:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1182,7 +1188,7 @@ static NSTimeInterval updateSystemVolumeInterval=0.1f;
|
|||
}
|
||||
|
||||
if(self->volumeRampTimer == nil)
|
||||
[self emitAcousticFeedback:nil];
|
||||
[self emitAcousticFeedback];
|
||||
|
||||
if( runningPlayerPtr == iTunes)
|
||||
[self setItunesVolume:volume];
|
||||
|
|
|
|||
Loading…
Reference in New Issue