Skip to content
This repository
Browse code

Completely avoid moving windows that cannot be moved to a third of th…

…e display.

Previously Spectacle would try to move a window to a third of the display, regardless of whether the window can actually fit. If it couldn't Spectacle tries to move it back to where it came from. This behavior resulted in an annoying "flicker" as the window is moved around.

To prevent this issue Spectacle now attempts to remember which window sizes and positions have posed a problem in the past.

In next iterations Spectacle should persist this "blacklist" to the filesystem.
  • Loading branch information...
commit 6cd5131c1c660047d60e017fb2674e762f7ef9d7 1 parent 99b8326
Eric Czarny authored August 28, 2012
2  Frameworks/ZeroKit
... ...
@@ -1 +1 @@
1  
-Subproject commit 3236f4406d9509a06130b88220575101d1f01e16
  1
+Subproject commit e1b9c7583f7d91d1f0d2bddb202e5987bb627180
4  SpectacleUtilities.h
@@ -24,6 +24,10 @@
24 24
 
25 25
 #pragma mark -
26 26
 
  27
+#define WindowRectToString(windowRect) [NSString stringWithFormat: @"(%f, %f) %fx%f", windowRect.origin.x, windowRect.origin.y, windowRect.size.width, windowRect.size.height]
  28
+
  29
+#pragma mark -
  30
+
27 31
 @interface SpectacleUtilities : ZeroKitUtilities
28 32
 
29 33
 + (void)displayAccessibilityAPIAlert;
1  SpectacleWindowPositionManager.h
@@ -24,6 +24,7 @@ typedef enum {
24 24
 @interface SpectacleWindowPositionManager : NSObject {
25 25
     NSMutableDictionary *myUndoHistory;
26 26
     NSMutableDictionary *myRedoHistory;
  27
+    NSMutableSet *myBlacklistedWindowRects;
27 28
 }
28 29
 
29 30
 + (SpectacleWindowPositionManager *)sharedManager;
30  SpectacleWindowPositionManager.m
@@ -25,12 +25,20 @@
25 25
 
26 26
 #pragma mark -
27 27
 
  28
+#define BlacklistedWindowRect(applicationName, windowRect) [NSString stringWithFormat: @"%@ - %@", applicationName, WindowRectToString(windowRect)]
  29
+
  30
+#pragma mark -
  31
+
28 32
 @interface SpectacleWindowPositionManager (SpectacleWindowPositionManagerPrivate)
29 33
 
30 34
 - (ZeroKitAccessibilityElement *)frontMostWindowElement;
31 35
 
32 36
 #pragma mark -
33 37
 
  38
+- (NSString *)frontMostApplicationName;
  39
+
  40
+#pragma mark -
  41
+
34 42
 - (CGRect)rectOfWindowWithAccessibilityElement: (ZeroKitAccessibilityElement *)accessibilityElement;
35 43
 
36 44
 #pragma mark -
@@ -79,6 +87,7 @@ - (id)init {
79 87
     if ((self = [super init])) {
80 88
         myUndoHistory = [[NSMutableDictionary dictionary] retain];
81 89
         myRedoHistory = [[NSMutableDictionary dictionary] retain];
  90
+        myBlacklistedWindowRects = [[NSMutableSet set] retain];
82 91
     }
83 92
     
84 93
     return self;
@@ -177,6 +186,7 @@ - (void)redoLastWindowAction {
177 186
 - (void)dealloc {
178 187
     [myUndoHistory release];
179 188
     [myRedoHistory release];
  189
+    [myBlacklistedWindowRects release];
180 190
     
181 191
     [super dealloc];
182 192
 }
@@ -207,6 +217,15 @@ - (ZeroKitAccessibilityElement *)frontMostWindowElement {
207 217
 
208 218
 #pragma mark -
209 219
 
  220
+- (NSString *)frontMostApplicationName {
  221
+    ZeroKitAccessibilityElement *systemWideElement = [ZeroKitAccessibilityElement systemWideElement];
  222
+    ZeroKitAccessibilityElement *applicationWithFocusElement = [systemWideElement elementWithAttribute: kAXFocusedApplicationAttribute];
  223
+    
  224
+    return [applicationWithFocusElement stringValueOfAttribute: kAXTitleAttribute];
  225
+}
  226
+
  227
+#pragma mark -
  228
+
210 229
 - (CGRect)rectOfWindowWithAccessibilityElement: (ZeroKitAccessibilityElement *)accessibilityElement {
211 230
     CGRect result = CGRectNull;
212 231
     
@@ -228,6 +247,15 @@ - (CGRect)rectOfWindowWithAccessibilityElement: (ZeroKitAccessibilityElement *)a
228 247
 #pragma mark -
229 248
 
230 249
 - (void)moveWindowRect: (CGRect)windowRect frameOfScreen: (CGRect)frameOfScreen visibleFrameOfScreen: (CGRect)visibleFrameOfScreen frontMostWindowElement: (ZeroKitAccessibilityElement *)frontMostWindowElement action: (SpectacleWindowAction)action {
  250
+    NSString *frontMostApplicationName = [self frontMostApplicationName];
  251
+    NSString *blacklistedWindowRect = BlacklistedWindowRect(frontMostApplicationName, windowRect);
  252
+    
  253
+    if ([myBlacklistedWindowRects containsObject: blacklistedWindowRect]) {
  254
+        NSBeep();
  255
+        
  256
+        return;
  257
+    }
  258
+    
231 259
     CGRect previousWindowRect = [self rectOfWindowWithAccessibilityElement: [self frontMostWindowElement]];
232 260
     
233 261
     [self moveWindowRect: windowRect frontMostWindowElement: frontMostWindowElement];
@@ -237,6 +265,8 @@ - (void)moveWindowRect: (CGRect)windowRect frameOfScreen: (CGRect)frameOfScreen
237 265
     if (MovingToThirdOfDisplay(action) && !CGRectEqualToRect(movedWindowRect, windowRect)) {
238 266
         NSBeep();
239 267
         
  268
+        [myBlacklistedWindowRects addObject: blacklistedWindowRect];
  269
+        
240 270
         [self moveWindowRect: previousWindowRect frontMostWindowElement: frontMostWindowElement];
241 271
         
242 272
         return;

0 notes on commit 6cd5131

Please sign in to comment.
Something went wrong with that request. Please try again.