Revision: 13360
          http://sourceforge.net/p/skim-app/code/13360
Author:   hofman
Date:     2023-03-14 22:48:42 +0000 (Tue, 14 Mar 2023)
Log Message:
-----------
use fade animation for full screen transition with reduced motion

Modified Paths:
--------------
    trunk/SKMainWindow.h
    trunk/SKMainWindow.m
    trunk/SKMainWindowController.h
    trunk/SKMainWindowController_FullScreen.m

Modified: trunk/SKMainWindow.h
===================================================================
--- trunk/SKMainWindow.h        2023-03-14 17:50:26 UTC (rev 13359)
+++ trunk/SKMainWindow.h        2023-03-14 22:48:42 UTC (rev 13360)
@@ -49,6 +49,7 @@
 }
 
 @property (nonatomic) BOOL disableConstrainedFrame;
+@property (nonatomic, readonly) NSImage *windowImage;
 
 - (id<SKMainWindowDelegate>)delegate;
 - (void)setDelegate:(id<SKMainWindowDelegate>)newDelegate;

Modified: trunk/SKMainWindow.m
===================================================================
--- trunk/SKMainWindow.m        2023-03-14 17:50:26 UTC (rev 13359)
+++ trunk/SKMainWindow.m        2023-03-14 22:48:42 UTC (rev 13360)
@@ -45,6 +45,7 @@
 @implementation SKMainWindow
 
 @synthesize disableConstrainedFrame;
+@dynamic windowImage;
 
 - (void)sendEvent:(NSEvent *)theEvent {
     if ([theEvent type] == NSEventTypeLeftMouseDown || [theEvent type] == 
NSEventTypeRightMouseDown || [theEvent type] == NSEventTypeKeyDown) {
@@ -106,4 +107,19 @@
     [super setDelegate:newDelegate];
 }
 
+- (NSImage *)windowImage {
+    NSRect frame = [self frame];
+    CGImageRef cgImage = CGWindowListCreateImage(CGRectNull, 
kCGWindowListOptionIncludingWindow, (CGWindowID)[self windowNumber], 
kCGWindowImageBoundsIgnoreFraming);
+    size_t width = (size_t)CGImageGetWidth(cgImage);
+    size_t height = (size_t)CGImageGetHeight(cgImage);
+    CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 8, 4 * 
width, CGImageGetColorSpace(cgImage), kCGBitmapByteOrder32Host | 
kCGImageAlphaPremultipliedFirst);
+    CGContextDrawImage(ctx, CGRectMake(0.0, 0.0, width, height), cgImage);
+    CGImageRef copiedCgImage = CGBitmapContextCreateImage(ctx);
+    NSImage *image = [[NSImage alloc] initWithCGImage:copiedCgImage 
size:frame.size];
+    CGContextRelease(ctx);
+    CGImageRelease(cgImage);
+    CGImageRelease(copiedCgImage);
+    return [image autorelease];
+}
+
 @end

Modified: trunk/SKMainWindowController.h
===================================================================
--- trunk/SKMainWindowController.h      2023-03-14 17:50:26 UTC (rev 13359)
+++ trunk/SKMainWindowController.h      2023-03-14 22:48:42 UTC (rev 13360)
@@ -123,7 +123,7 @@
     
     NSWindow                            *mainWindow;
     SKSideWindow                        *sideWindow;
-    NSMutableArray                      *blankingWindows;
+    NSWindow                            *animationWindow;
     
     SKInteractionMode                   interactionMode;
     

Modified: trunk/SKMainWindowController_FullScreen.m
===================================================================
--- trunk/SKMainWindowController_FullScreen.m   2023-03-14 17:50:26 UTC (rev 
13359)
+++ trunk/SKMainWindowController_FullScreen.m   2023-03-14 22:48:42 UTC (rev 
13360)
@@ -63,6 +63,7 @@
 #import "NSScreen_SKExtensions.h"
 #import "NSColor_SKExtensions.h"
 #import "SKStatusBar.h"
+#import "SKAnimatedBorderlessWindow.h"
 
 #define MAINWINDOWFRAME_KEY         @"windowFrame"
 #define LEFTSIDEPANEWIDTH_KEY       @"leftSidePaneWidth"
@@ -83,6 +84,12 @@
 
 static CGFloat fullScreenToolbarOffset = 0.0;
 
+#if SDK_BEFORE(10_12)
+@interface NSWorkSpace (BDSKSierraDeclarations)
+- (void)accessibilityDisplayShouldReduceMotion;
+@end
+#endif
+
 #if SDK_BEFORE(10_14)
 @interface PDFView (SKMojaveDeclarations)
 - (void)enablePageShadows:(BOOL)flag;
@@ -562,22 +569,50 @@
 }
 
 - (NSArray *)customWindowsToEnterFullScreenForWindow:(NSWindow *)window {
-    return [[[self document] windowControllers] valueForKey:WINDOW_KEY];
+    NSArray *windows = [[[self document] windowControllers] 
valueForKey:WINDOW_KEY];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpartial-availability"
+    if (RUNNING_AFTER(10_12) && [[NSWorkspace sharedWorkspace] 
accessibilityDisplayShouldReduceMotion]) {
+#pragma clang diagnostic pop
+        animationWindow = [[SKAnimatedBorderlessWindow alloc] 
initWithContentRect:[window frame]];
+        windows = [windows arrayByAddingObject:animationWindow];
+    }
+    return windows;
 }
 
 - (void)window:(NSWindow *)window 
startCustomAnimationToEnterFullScreenWithDuration:(NSTimeInterval)duration {
     if (fullScreenToolbarOffset <= 0.0 && autoHideToolbarInFullScreen == NO && 
[[mainWindow toolbar] isVisible])
         fullScreenToolbarOffset = toolbarViewOffset(mainWindow);
+    NSRect frame = SKShrinkRect([[window screen] frame], 
-fullScreenOffset(window), NSMaxYEdge);
+    BOOL fade = animationWindow != nil;
     [(SKMainWindow *)window setDisableConstrainedFrame:YES];
+    if (fade) {
+        [(SKAnimatedBorderlessWindow *)animationWindow 
setBackgroundImage:[(SKMainWindow *)window windowImage]];
+        [animationWindow orderWindow:NSWindowBelow relativeTo:window];
+        [window setAlphaValue:0.0];
+        [window setFrame:frame display:YES];
+        for (NSView *view in [[[window 
standardWindowButton:NSWindowCloseButton] superview] subviews])
+            if ([view isKindOfClass:[NSControl class]])
+                [view setAlphaValue:0.0];
+    }
     [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
-            [context setDuration:duration - 0.1];
-            [[window animator] setFrame:SKShrinkRect([[window screen] frame], 
-fullScreenOffset(window), NSMaxYEdge) display:YES];
-            for (NSView *view in [[[window 
standardWindowButton:NSWindowCloseButton] superview] subviews])
-                if ([view isKindOfClass:[NSControl class]])
-                    [[view animator] setAlphaValue:0.0];
+            [context setDuration:duration - 0.01];
+            if (fade) {
+                [[window animator] setAlphaValue:1.0];
+                [[animationWindow animator] setAlphaValue:0.0];
+            } else {
+                [[window animator] setFrame:frame display:YES];
+                for (NSView *view in [[[window 
standardWindowButton:NSWindowCloseButton] superview] subviews])
+                    if ([view isKindOfClass:[NSControl class]])
+                        [[view animator] setAlphaValue:0.0];
+            }
         }
         completionHandler:^{
             [(SKMainWindow *)window setDisableConstrainedFrame:NO];
+            if (fade) {
+                [animationWindow orderOut:nil];
+                SKDESTROY(animationWindow);
+            }
         }];
 }
 
@@ -629,7 +664,15 @@
 }
 
 - (NSArray *)customWindowsToExitFullScreenForWindow:(NSWindow *)window {
-    return [[[self document] windowControllers] valueForKey:WINDOW_KEY];
+    NSArray *windows = [[[self document] windowControllers] 
valueForKey:WINDOW_KEY];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpartial-availability"
+    if (RUNNING_AFTER(10_12) && [[NSWorkspace sharedWorkspace] 
accessibilityDisplayShouldReduceMotion]) {
+#pragma clang diagnostic pop
+        animationWindow = [[SKAnimatedBorderlessWindow alloc] 
initWithContentRect:[window frame]];
+        windows = [windows arrayByAddingObject:animationWindow];
+    }
+    return windows;
 }
 
 - (void)window:(NSWindow *)window 
startCustomAnimationToExitFullScreenWithDuration:(NSTimeInterval)duration {
@@ -636,6 +679,7 @@
     NSString *frameString = [savedNormalSetup 
objectForKey:MAINWINDOWFRAME_KEY];
     NSRect frame = NSRectFromString(frameString);
     NSRect startFrame = [window frame];
+    BOOL fade = animationWindow != nil;
     [(SKMainWindow *)window setDisableConstrainedFrame:YES];
     [window setStyleMask:[window styleMask] & ~NSWindowStyleMaskFullScreen];
     for (NSView *view in [[[window standardWindowButton:NSWindowCloseButton] 
superview] subviews])
@@ -643,16 +687,32 @@
             [view setAlphaValue:0.0];
     [window setFrame:SKShrinkRect(startFrame, -fullScreenOffset(window), 
NSMaxYEdge) display:YES];
     [window setLevel:NSStatusWindowLevel];
+    if (fade) {
+        [(SKAnimatedBorderlessWindow *)animationWindow 
setBackgroundImage:[(SKMainWindow *)window windowImage]];
+        [animationWindow orderWindow:NSWindowBelow relativeTo:window];
+        [window setAlphaValue:0.0];
+        [window setFrame:frame display:YES];
+        for (NSView *view in [[[window 
standardWindowButton:NSWindowCloseButton] superview] subviews])
+            if ([view isKindOfClass:[NSControl class]])
+                [view setAlphaValue:1.0];
+    }
     [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
-            [context setDuration:duration - 0.1];
-            [[window animator] setFrame:frame display:YES];
-            for (NSView *view in [[[window 
standardWindowButton:NSWindowCloseButton] superview] subviews])
-                if ([view isKindOfClass:[NSControl class]])
-                    [[view animator] setAlphaValue:1.0];
+            [context setDuration:duration - 0.01];
+            if (fade) {
+                [[window animator] setAlphaValue:1.0];
+                [[animationWindow animator] setAlphaValue:0.0];
+            } else {
+                [[window animator] setFrame:frame display:YES];
+                for (NSView *view in [[[window 
standardWindowButton:NSWindowCloseButton] superview] subviews])
+                    if ([view isKindOfClass:[NSControl class]])
+                        [[view animator] setAlphaValue:1.0];
+            }
         }
         completionHandler:^{
             [(SKMainWindow *)window setDisableConstrainedFrame:NO];
             [window setLevel:NSNormalWindowLevel];
+            [animationWindow orderOut:nil];
+            SKDESTROY(animationWindow);
         }];
 }
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to