Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: a55b899d0184fc7a610bd4e3de64f286f4feee4a
      
https://github.com/WebKit/WebKit/commit/a55b899d0184fc7a610bd4e3de64f286f4feee4a
  Author: Wenson Hsieh <[email protected]>
  Date:   2025-07-12 (Sat, 12 Jul 2025)

  Changed paths:
    M Source/WebKit/SourcesCocoa.txt
    M Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
    M Source/WebKit/UIProcess/ios/WKScrollView.h
    M Source/WebKit/UIProcess/ios/WKScrollView.mm
    A Source/WebKit/UIProcess/ios/WKUIScrollEdgeEffect.h
    A Source/WebKit/UIProcess/ios/WKUIScrollEdgeEffect.mm
    M Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm
    M Source/WebKit/UIProcess/mac/WebViewImpl.h
    M Source/WebKit/UIProcess/mac/WebViewImpl.mm
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj
    M Tools/TestWebKitAPI/Tests/WebKitCocoa/top-fixed-element.html
    M Tools/TestWebKitAPI/Tests/ios/WKScrollViewTests.mm

  Log Message:
  -----------
  [Liquid Glass] [iOS] Make it possible for clients to hide scroll edge effects 
without breaking fixed color extensions
https://bugs.webkit.org/show_bug.cgi?id=295843
rdar://155241107

Reviewed by Richard Robinson.

Currently, it's not really possible for `WKWebView` clients to hide scroll edge 
effects on the main
scroll view (`webView.scrollView`) without causing bugs in element fullscreen 
or when there are
fixed color extensions along the scroll effect edges being hidden. This is 
because WebKit internally
sets `scrollView.{top|bottom|left|right}EdgeEffect.hidden = YES;` to hide 
scroll edge effects on all
sides with fixed edges, and sets it to `NO` once there's no longer a fixed 
container edge. Since
the WebKit client just uses this same API, it's possible for both WebKit to 
override the last client
value, or for the client to override the last internally-set value.

To prevent the engine and client from stomping over the value of 
`-[UIScrollEdgeEffect hidden]`, we
make `-[WKScrollView {top|bottom|left|right}EdgeEffect]` return a wrapper 
object instead of the real
`UIScrollEdgeEffect`; when calling `-setHidden:` on this wrapper, we then make 
a distinction between
calls coming from within the WebKit engine, and calls coming from the external 
client. The scroll
pocket is only hidden if both WebKit and the external client don't hide the 
pocket.

See below for more details.

* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _updateHiddenScrollPocketEdges]):
* Source/WebKit/UIProcess/ios/WKScrollView.h:
* Source/WebKit/UIProcess/ios/WKScrollView.mm:
(-[WKScrollView topEdgeEffect]):
(-[WKScrollView leftEdgeEffect]):
(-[WKScrollView bottomEdgeEffect]):
(-[WKScrollView rightEdgeEffect]):

Override these APIs return the scroll edge effect wrappers instead.

(-[WKScrollView _wk_topEdgeEffect]):
(-[WKScrollView _wk_leftEdgeEffect]):
(-[WKScrollView _wk_rightEdgeEffect]):
(-[WKScrollView _wk_bottomEdgeEffect]):
(-[WKScrollView _setHiddenPocketEdges:]): Deleted.
(-[WKScrollView _setHiddenPocketEdgesInternal:]): Deleted.

Replace the call to `-_setHiddenPocketEdgesInternal:` with 
`-setInternallyHidden:` on the wrapper
object.

* Source/WebKit/UIProcess/ios/WKUIScrollEdgeEffect.h: Added.
* Source/WebKit/UIProcess/ios/WKUIScrollEdgeEffect.mm: Added.

Introduce `WKUIScrollEdgeEffect`, which wraps the given `UIScrollEdgeEffect` 
and forwards all
selectors (except for `-setHidden:`) to the inner effect object.

(-[WKUIScrollEdgeEffect initWithScrollEdgeEffect:boxSide:]):
(-[WKUIScrollEdgeEffect forwardingTargetForSelector:]):
(-[WKUIScrollEdgeEffect respondsToSelector:]):
(-[WKUIScrollEdgeEffect isKindOfClass:]):
(-[WKUIScrollEdgeEffect setInternallyHidden:]):
(-[WKUIScrollEdgeEffect isInternallyHidden]):

Add support for `-setInternallyHidden:` on the pocket wrapper which is only 
used to hide or unhide
the scroll pocket from within WebKit code.

(-[WKUIScrollEdgeEffect setHidden:]):
(-[WKUIScrollEdgeEffect _setHidden:fromSource:]):

Add `OptionSet<HiddenScrollEdgeEffectSource>`, which tracks whether or not the 
pocket should be
hidden according to the client and WebKit internal state. The `OptionSet` must 
be empty for the
wrapped `UIScrollEdgeEffect` to be unhidden.

(-[WKUIScrollEdgeEffect description]):

Override `-description` to print the wrapped scroll edge effect as well.

* Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm:
* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/top-fixed-element.html:
* Tools/TestWebKitAPI/Tests/ios/WKScrollViewTests.mm:
(TestWebKitAPI::TEST(WKScrollViewTests, PositionFixedLayerAfterScrolling)):
(TestWebKitAPI::TEST(WKScrollViewTests, AllowsKeyboardScrolling)):
(TestWebKitAPI::TEST(WKScrollViewTests, ClientCanHideScrollEdgeEffects)):

Add an API test to exercise the change, by verifying that 
`topEdgeEffect.hidden` can be used without
forcing the pocket to show up over fixed color extensions.

(traverseLayerTree): Deleted.
(TEST(WKScrollViewTests, PositionFixedLayerAfterScrolling)): Deleted.
(TEST(WKScrollViewTests, AsynchronousWheelEventHandling)): Deleted.
(TEST(WKScrollViewTests, 
OverscrollBehaviorAndOverflowHiddenOnRootShouldNotPreventScrolling)): Deleted.
(TEST(WKScrollViewTests, WheelEventDispatchedToSubframe)): Deleted.
(TEST(WKScrollViewTests, IndicatorStyleSetByClient)): Deleted.
(TEST(WKScrollViewTests, BackgroundColorSetByClient)): Deleted.
(TEST(WKScrollViewTests, DecelerationSetByClient)): Deleted.
(TEST(WKScrollViewTests, AllowsKeyboardScrolling)): Deleted.

Canonical link: https://commits.webkit.org/297313@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to