Skip to content

Commit

Permalink
[visionOS] Hide ornaments when entering fullscreen
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=258786
rdar://111453364

Reviewed by Tim Horton.

Ornaments are smaller pieces of UI associated with a particular window scene.
When performing the fullscreen transition, these pieces of UI should be hidden
alongside the presenting window.

* Source/WebKit/Platform/spi/visionos/MRUIKitSPI.h:
* Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
(-[WKFullScreenParentWindowState initWithWindow:]):

Store the original depth of ornaments to restore their depth after exiting fullscreen.

(-[WKFullScreenParentWindowState ornamentDepths]):
(-[WKFullScreenWindowController _performSpatialFullScreenTransition:completionHandler:]):

Animate the ornaments as if they were a part of the presenting window, matching
the fade and depth animations.

Canonical link: https://commits.webkit.org/265733@main
  • Loading branch information
pxlcoder authored and hortont424 committed Jul 3, 2023
1 parent 7b10b12 commit d131b55
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
15 changes: 15 additions & 0 deletions Source/WebKit/Platform/spi/visionos/MRUIKitSPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,19 @@ typedef void (^MRUIWindowSceneResizeRequestCompletion)(CGSize grantedSize, NSErr

#endif // USE(APPLE_INTERNAL_SDK)

// FIXME: <rdar://111655142> Import ornaments SPI using framework headers.

@interface MRUIPlatterOrnament : NSObject
@property (nonatomic, assign, getter=_depthDisplacement, setter=_setDepthDisplacement:) CGFloat depthDisplacement;
@end

@interface MRUIPlatterOrnamentManager : NSObject
@property (nonatomic, readonly) NSArray<MRUIPlatterOrnament *> *ornaments;
@end

@interface UIWindowScene (MRUIPlatterOrnaments)
@property (nonatomic, readonly) MRUIPlatterOrnamentManager *_mrui_platterOrnamentManager;
@property (nonatomic, readwrite) BOOL prefersOrnamentsHidden_forLMKOnly;
@end

#endif // PLATFORM(VISION)
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,11 @@ void store(WKWebView* webView)
static constexpr CGFloat kFullScreenWindowCornerRadius = 12;
static constexpr CGFloat kDarknessAnimationDuration = 0.6;
static constexpr CGFloat kOutgoingWindowFadeDuration = 0.4;
static constexpr CGFloat kOutgoingWindowTranslationDuration = 0.6;
static constexpr CGFloat kOutgoingWindowZOffset = -150;
static constexpr CGFloat kIncomingWindowFadeDuration = 0.6;
static constexpr CGFloat kIncomingWindowFadeDelay = 0.2;
static constexpr CGFloat kIncomingWindowTranslationDuration = 0.6;
static constexpr CGFloat kIncomingWindowZOffset = -170;
static constexpr CGFloat kWindowTranslationDuration = 0.6;
static constexpr NSString *kPrefersFullScreenDimmingKey = @"WebKitPrefersFullScreenDimming";
#endif

Expand Down Expand Up @@ -476,12 +475,17 @@ @interface WKFullScreenParentWindowState : NSObject
@property (nonatomic, readonly) RSSSceneChromeOptions sceneChromeOptions;
@property (nonatomic, readonly) MRUISceneResizingBehavior sceneResizingBehavior;
@property (nonatomic, readonly) MRUIDarknessPreference preferredDarkness;
@property (nonatomic, readonly) BOOL prefersOrnamentsHidden;

@property (nonatomic, readonly) NSMapTable<MRUIPlatterOrnament *, NSNumber *> *ornamentDepths;

- (id)initWithWindow:(UIWindow *)window;

@end

@implementation WKFullScreenParentWindowState
@implementation WKFullScreenParentWindowState {
RetainPtr<NSMapTable<MRUIPlatterOrnament *, NSNumber *>> _ornamentDepths;
}

- (id)initWithWindow:(UIWindow *)window
{
Expand All @@ -490,14 +494,28 @@ - (id)initWithWindow:(UIWindow *)window

_transform3D = window.transform3D;
_windowClass = object_getClass(window);
_sceneMinimumSize = window.windowScene.sizeRestrictions.minimumSize;
_sceneChromeOptions = window.windowScene.mrui_placement.preferredChromeOptions;
_sceneResizingBehavior = window.windowScene.mrui_placement.preferredResizingBehavior;
_preferredDarkness = UIApplication.sharedApplication.mrui_activeStage.preferredDarkness;

UIWindowScene *windowScene = window.windowScene;
_sceneMinimumSize = windowScene.sizeRestrictions.minimumSize;
_sceneChromeOptions = windowScene.mrui_placement.preferredChromeOptions;
_sceneResizingBehavior = windowScene.mrui_placement.preferredResizingBehavior;
_prefersOrnamentsHidden = windowScene.prefersOrnamentsHidden_forLMKOnly;

_ornamentDepths = [NSMapTable weakToStrongObjectsMapTable];

MRUIPlatterOrnamentManager *ornamentManager = windowScene._mrui_platterOrnamentManager;
for (MRUIPlatterOrnament *ornament in ornamentManager.ornaments)
[_ornamentDepths setObject:@(ornament._depthDisplacement) forKey:ornament];

return self;
}

- (NSMapTable<MRUIPlatterOrnament *, NSNumber *> *)ornamentDepths
{
return _ornamentDepths.get();
}

@end

@interface WKFullscreenWindowSceneDelegate : NSObject <MRUIWindowSceneDelegate>
Expand Down Expand Up @@ -1557,16 +1575,31 @@ - (void)_performSpatialFullScreenTransition:(BOOL)enter completionHandler:(Compl

[UIView animateWithDuration:kOutgoingWindowFadeDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
outWindow.alpha = 0;
if (enter)
outWindow.windowScene.prefersOrnamentsHidden_forLMKOnly = YES;
} completion:nil];

[UIView animateWithDuration:kOutgoingWindowTranslationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[UIView animateWithDuration:kWindowTranslationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
outWindow.transform3D = CATransform3DTranslate(outWindow.transform3D, 0, 0, kOutgoingWindowZOffset);
} completion:nil];

[UIView animateWithDuration:kIncomingWindowTranslationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[UIView animateWithDuration:kWindowTranslationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
inWindow.transform3D = originalState.transform3D;
} completion:nil];

for (MRUIPlatterOrnament *ornament in originalState.ornamentDepths) {
CGFloat originalDepth = [[originalState.ornamentDepths objectForKey:ornament] floatValue];
CGFloat finalDepth = originalDepth;
if (enter)
finalDepth += kOutgoingWindowZOffset;
else
[ornament _setDepthDisplacement:originalDepth + kIncomingWindowZOffset];

[UIView animateWithDuration:kWindowTranslationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[ornament _setDepthDisplacement:finalDepth];
} completion:nil];
}

auto completion = makeBlockPtr([controller = retainPtr(controller), inWindow = retainPtr(inWindow), originalState = retainPtr(originalState), enter, completionHandler = WTFMove(completionHandler)] (BOOL finished) mutable {
WebKit::resizeScene([inWindow windowScene], [inWindow bounds].size, [controller, inWindow, originalState, enter, completionHandler = WTFMove(completionHandler)]() mutable {
Class inWindowClass = enter ? [UIWindow class] : [originalState windowClass];
Expand Down Expand Up @@ -1594,6 +1627,8 @@ - (void)_performSpatialFullScreenTransition:(BOOL)enter completionHandler:(Compl

[UIView animateWithDuration:kIncomingWindowFadeDuration delay:kIncomingWindowFadeDelay options:UIViewAnimationOptionCurveEaseInOut animations:^{
inWindow.alpha = 1;
if (!enter)
inWindow.windowScene.prefersOrnamentsHidden_forLMKOnly = originalState.prefersOrnamentsHidden;
} completion:completion.get()];
}

Expand Down

0 comments on commit d131b55

Please sign in to comment.