Per Masayuki's suggestion on D302222 (taking my mozregression bisect result as the entry point): the underlying issue is that the existing self-heal path through PresShell::RecordPointerLocation -> SynthesizeMouseMove -> EventStateManager::UpdateCursor cannot complete when sLastPointerId has been cleared, because eMouseEnterIntoWidget itself does not restore it. Today PointerEventHandler::UpdatePointerActiveState deliberately skips UpdateLastPointerId for eMouseEnterIntoWidget. PresShell still schedules a synthesized eMouseMove for it, but that synthesized event fails the IsLastPointerId check bug 1980636 added in EventStateManager::UpdateCursor and returns before updating the on-screen cursor. This is observable on macOS native fullscreen: AppKit tears down the old content view's NSTrackingArea and installs one on the new fullscreen view, firing a real mouseExited / mouseEntered pair on the old view even though the cursor never moves. The mouseExited dispatches eMouseExitFromWidget, which clears sLastPointerId. The matching mouseEntered then dispatches eMouseEnterIntoWidget and schedules the self-heal synthesized eMouseMove — which currently can't complete the cursor update because sLastPointerId has not been restored. As a result, e.g. YouTube/Bilibili's autohide `cursor: none` does not take effect after the user enters fullscreen until they move the mouse. Restore the UpdateLastPointerId call in the eMouseEnterIntoWidget arm of UpdatePointerActiveState (and drop the now-incorrect comment), and remove the corresponding MOZ_ASSERT in UpdateLastPointerId itself. Also drop MOZDynamicCursor::reassertCurrentCursor (the previous fix in this bug, from D299187) and its call site in nsCocoaWindow::CocoaWindowDidEnterFullscreen. With this patch the self-heal path through PresShell -> EventStateManager -> SetCursor restores the correct cursor after the transition, so there is no cached state left to reassert. mozregression bisected the user-visible symptom to bug 1980636 (last good 143.0a1, first bad 144.0a1). Differential Revision: https://phabricator.services.mozilla.com/D302222
38 lines
1.3 KiB
Objective-C
38 lines
1.3 KiB
Objective-C
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef MOZDynamicCursor_h_
|
|
#define MOZDynamicCursor_h_
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
#include "nsIWidget.h"
|
|
|
|
// MOZDynamicCursor.sharedInstance is a singleton NSCursor object whose
|
|
// underlying cursor can be changed at runtime.
|
|
// It can be used in an NSView cursorRect so that the system will call
|
|
// -[NSCursor set] on it at the right moments, for example when the
|
|
// mouse moves into a window or when the cursor needs to be set after
|
|
// a drag operation or when a context menu closes.
|
|
@interface MOZDynamicCursor : NSCursor {
|
|
@private
|
|
NSMutableDictionary* mCursors;
|
|
NSCursor* mCurrentCursor;
|
|
nsCursor mCurrentCursorType;
|
|
}
|
|
|
|
// Sets non-custom cursors and can be used as a fallback if setting
|
|
// a custom cursor did not succeed.
|
|
- (void)setNonCustomCursor:(const nsIWidget::Cursor&)aCursor;
|
|
|
|
// As above, but returns an error if the cursor isn't custom or we couldn't set
|
|
// it for some reason.
|
|
- (nsresult)setCustomCursor:(const nsIWidget::Cursor&)aCursor
|
|
widgetScaleFactor:(CGFloat)aWidgetScaleFactor
|
|
forceUpdate:(bool)aForceUpdate;
|
|
|
|
+ (MOZDynamicCursor*)sharedInstance;
|
|
@end
|
|
|
|
#endif // MOZDynamicCursor_h_
|