diff --git a/easy-move-resize.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/easy-move-resize.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/easy-move-resize.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/easy-move-resize.xcodeproj/xcshareddata/xcschemes/easy-move-resize.xcscheme b/easy-move-resize.xcodeproj/xcshareddata/xcschemes/easy-move-resize.xcscheme new file mode 100644 index 0000000..e6a4a49 --- /dev/null +++ b/easy-move-resize.xcodeproj/xcshareddata/xcschemes/easy-move-resize.xcscheme @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/easy-move-resize/EMRAppDelegate.h b/easy-move-resize/EMRAppDelegate.h index 5aaa57b..87c2303 100644 --- a/easy-move-resize/EMRAppDelegate.h +++ b/easy-move-resize/EMRAppDelegate.h @@ -33,6 +33,8 @@ static const double kResizeFilterInterval = 0.04; @property (weak) IBOutlet NSMenuItem *resizeOnlyMenu; @property (weak) IBOutlet NSMenuItem *disabledAppsMenu; @property (weak) IBOutlet NSMenuItem *lastAppMenu; + @property (nonatomic) BOOL sessionActive; +@property NSTimeInterval refreshInterval; @end diff --git a/easy-move-resize/EMRAppDelegate.m b/easy-move-resize/EMRAppDelegate.m index e517c95..d1ded4b 100644 --- a/easy-move-resize/EMRAppDelegate.m +++ b/easy-move-resize/EMRAppDelegate.m @@ -11,12 +11,22 @@ - (id) init { if (self) { NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"userPrefs"]; preferences = [[EMRPreferences alloc] initWithUserDefaults:userDefaults]; + + // Default to 60hz, but check each connected screen for a faster refresh and use the fastest one we find + self.refreshInterval = 0.0167; + for (NSScreen *screen in [NSScreen screens]) { + if (@available(macOS 12.0, *)) { + NSTimeInterval maxRefreshInterval = [screen maximumRefreshInterval]; + if (maxRefreshInterval < self.refreshInterval) { + self.refreshInterval = maxRefreshInterval; + } + } + } } return self; } CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, CGEventRef event, void *refcon) { - EMRAppDelegate *ourDelegate = (__bridge EMRAppDelegate*)refcon; int keyModifierFlags = [ourDelegate modifierFlags]; bool shouldMiddleClickResize = [ourDelegate shouldMiddleClickResize]; @@ -26,6 +36,8 @@ CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, C CGEventType resizeModifierUp = kCGEventRightMouseUp; bool handled = NO; + double refreshInterval = [ourDelegate refreshInterval]; + if (![ourDelegate sessionActive]) { return event; } @@ -35,7 +47,7 @@ CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, C return event; } - if (shouldMiddleClickResize){ + if (shouldMiddleClickResize) { resizeModifierDown = kCGEventOtherMouseDown; resizeModifierDragged = kCGEventOtherMouseDragged; resizeModifierUp = kCGEventOtherMouseUp; @@ -90,7 +102,7 @@ CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, C pid_t PID; NSRunningApplication* app; - if(!AXUIElementGetPid(_clickedWindow, &PID)) { + if (!AXUIElementGetPid(_clickedWindow, &PID)) { app = [NSRunningApplication runningApplicationWithProcessIdentifier:PID]; if ([[ourDelegate getDisabledApps] objectForKey:[app bundleIdentifier]] != nil) { [moveResize setTracking:0]; @@ -99,7 +111,7 @@ CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, C [ourDelegate setMostRecentApp:app]; } - if([ourDelegate shouldBringWindowToFront]){ + if ([ourDelegate shouldBringWindowToFront]) { if (app != nil) { [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; } @@ -139,7 +151,7 @@ CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, C CFTypeRef _position; // actually applying the change is expensive, so only do it every kMoveFilterInterval seconds - if (CACurrentMediaTime() - [moveResize tracking] > kMoveFilterInterval) { + if (CACurrentMediaTime() - [moveResize tracking] > refreshInterval) { _position = (CFTypeRef) (AXValueCreate(kAXValueCGPointType, (const void *) &thePoint)); AXUIElementSetAttributeValue(_clickedWindow, (__bridge CFStringRef) NSAccessibilityPositionAttribute, (CFTypeRef *) _position); if (_position != NULL) CFRelease(_position); @@ -237,7 +249,7 @@ CGEventRef myCGEventCallback(CGEventTapProxy __unused proxy, CGEventType type, C [moveResize setWndSize:wndSize]; // actually applying the change is expensive, so only do it every kResizeFilterInterval events - if (CACurrentMediaTime() - [moveResize tracking] > kResizeFilterInterval) { + if (CACurrentMediaTime() - [moveResize tracking] > refreshInterval) { // only make a call to update the position if we need to if (resizeSection.xResizeDirection == left || resizeSection.yResizeDirection == bottom) { CFTypeRef _position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&cTopLeft)); @@ -350,7 +362,7 @@ - (void)becameInactive:(NSNotification*) notification { _sessionActive = false; } --(void)awakeFromNib{ +- (void)awakeFromNib{ NSImage *icon = [NSImage imageNamed:@"MenuIcon"]; statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; [statusItem setMenu:statusMenu]; @@ -383,13 +395,13 @@ - (void)initMenuItems { bool shouldMiddleClickResize = [preferences shouldMiddleClickResize]; bool resizeOnly = [preferences resizeOnly]; - if(shouldBringWindowToFront){ + if (shouldBringWindowToFront) { [_bringWindowFrontMenu setState:1]; } - if(shouldMiddleClickResize){ + if (shouldMiddleClickResize) { [_middleClickResizeMenu setState:1]; } - if(resizeOnly){ + if (resizeOnly) { [_resizeOnlyMenu setState:1]; } @@ -483,21 +495,26 @@ - (IBAction)enableDisabledApp:(id)sender { - (int)modifierFlags { return keyModifierFlags; } -- (void) setMostRecentApp:(NSRunningApplication*)app { + +- (void)setMostRecentApp:(NSRunningApplication*)app { lastApp = app; [_lastAppMenu setTitle:[NSString stringWithFormat:@"Disable for %@", [app localizedName]]]; [_lastAppMenu setEnabled:YES]; } -- (NSDictionary*) getDisabledApps { + +- (NSDictionary*)getDisabledApps { return [preferences getDisabledApps]; } --(BOOL)shouldBringWindowToFront { + +- (BOOL)shouldBringWindowToFront { return [preferences shouldBringWindowToFront]; } --(BOOL)shouldMiddleClickResize { + +- (BOOL)shouldMiddleClickResize { return [preferences shouldMiddleClickResize]; } --(BOOL)resizeOnly { + +- (BOOL)resizeOnly { return [preferences resizeOnly]; } diff --git a/easy-move-resize/EMRMoveResize.m b/easy-move-resize/EMRMoveResize.m index 91c2a40..8537095 100644 --- a/easy-move-resize/EMRMoveResize.m +++ b/easy-move-resize/EMRMoveResize.m @@ -33,7 +33,7 @@ - (void)setWindow:(AXUIElementRef)window { _window = window; } -- (CFRunLoopSourceRef) runLoopSource { +- (CFRunLoopSourceRef)runLoopSource { return _runLoopSource; } diff --git a/easy-move-resize/EMRPreferences.h b/easy-move-resize/EMRPreferences.h index 7edf941..f6d01df 100644 --- a/easy-move-resize/EMRPreferences.h +++ b/easy-move-resize/EMRPreferences.h @@ -21,7 +21,6 @@ #define FN_KEY @"FN" @interface EMRPreferences : NSObject { - } @property (nonatomic) BOOL shouldBringWindowToFront; @@ -32,19 +31,19 @@ - (id)initWithUserDefaults:(NSUserDefaults *)defaults; // Get the modifier flags from the standard preferences -- (int) modifierFlags; +- (int)modifierFlags; // Set or unset the given modifier key in the preferences -- (void) setModifierKey:(NSString*)singleFlagString enabled:(BOOL)enabled; +- (void)setModifierKey:(NSString*)singleFlagString enabled:(BOOL)enabled; // returns a set of the currently persisted key constants -- (NSSet*) getFlagStringSet; +- (NSSet*)getFlagStringSet; // returns a dict of disabled apps -- (NSDictionary*) getDisabledApps; +- (NSDictionary*)getDisabledApps; // add or remove an app from the disabled apps list -- (void) setDisabledForApp:(NSString*)bundleIdentifier withLocalizedName:(NSString*)localizedName disabled:(BOOL)disabled; +- (void)setDisabledForApp:(NSString*)bundleIdentifier withLocalizedName:(NSString*)localizedName disabled:(BOOL)disabled; // reset preferences to the defaults - (void)setToDefaults; diff --git a/easy-move-resize/EMRPreferences.m b/easy-move-resize/EMRPreferences.m index 50c6d14..66a1ff7 100644 --- a/easy-move-resize/EMRPreferences.m +++ b/easy-move-resize/EMRPreferences.m @@ -52,7 +52,6 @@ - (void)setModifierFlagString:(NSString *)flagString { [userDefaults setObject:flagString forKey:MODIFIER_FLAGS_DEFAULTS_KEY]; } - - (void)setModifierKey:(NSString *)singleFlagString enabled:(BOOL)enabled { singleFlagString = [singleFlagString uppercaseString]; NSString *modifierFlagString = [userDefaults stringForKey:MODIFIER_FLAGS_DEFAULTS_KEY]; @@ -141,26 +140,28 @@ - (int)flagsFromFlagString:(NSString*)modifierFlagString { return modifierFlags; } --(BOOL)shouldBringWindowToFront { +- (BOOL)shouldBringWindowToFront { return [userDefaults boolForKey:SHOULD_BRING_WINDOW_TO_FRONT]; } --(void)setShouldBringWindowToFront:(BOOL)bringToFront { + +- (void)setShouldBringWindowToFront:(BOOL)bringToFront { [userDefaults setBool:bringToFront forKey:SHOULD_BRING_WINDOW_TO_FRONT]; } --(BOOL)shouldMiddleClickResize { +- (BOOL)shouldMiddleClickResize { return [userDefaults boolForKey:SHOULD_MIDDLE_CLICK_RESIZE]; } --(void)setShouldMiddleClickResize:(BOOL)middleClickResize { + +- (void)setShouldMiddleClickResize:(BOOL)middleClickResize { [userDefaults setBool:middleClickResize forKey:SHOULD_MIDDLE_CLICK_RESIZE]; } --(BOOL)resizeOnly { +- (BOOL)resizeOnly { return [userDefaults boolForKey:RESIZE_ONLY]; } --(void)setResizeOnly:(BOOL)resizeOnly { + +- (void)setResizeOnly:(BOOL)resizeOnly { [userDefaults setBool:resizeOnly forKey:RESIZE_ONLY]; } @end - diff --git a/easy-move-resize/en.lproj/MainMenu.xib b/easy-move-resize/en.lproj/MainMenu.xib index 614894f..abb5964 100644 --- a/easy-move-resize/en.lproj/MainMenu.xib +++ b/easy-move-resize/en.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - +