summaryrefslogtreecommitdiffstats
path: root/widget/cocoa/nsChildView.mm
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-11-20 09:47:03 +0000
committerMoonchild <moonchild@palemoon.org>2020-11-20 09:47:03 +0000
commit5165ed02285315cc0bed7977c7bac6d0a90ca43c (patch)
tree9b761a21eb924915e51c2d803208e6c01b505a45 /widget/cocoa/nsChildView.mm
parente1db27e19989db11fef70f439cf95821316535b3 (diff)
parentca9abcdf1702c37bf00048dab3f460b2252873a3 (diff)
downloadUXP-RC_20201120.tar
UXP-RC_20201120.tar.gz
UXP-RC_20201120.tar.lz
UXP-RC_20201120.tar.xz
UXP-RC_20201120.zip
Merge branch 'redwood' into releaseRELBASE_20201124RELBASE_20201120RC_20201120
Diffstat (limited to 'widget/cocoa/nsChildView.mm')
-rw-r--r--widget/cocoa/nsChildView.mm599
1 files changed, 121 insertions, 478 deletions
diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
index 1a257d899..868687fe1 100644
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -146,7 +146,10 @@ bool gUserCancelledDrag = false;
uint32_t nsChildView::sLastInputEventCount = 0;
-static uint32_t gNumberOfWidgetsNeedingEventThread = 0;
+// The view that will do our drawing or host our NSOpenGLContext or Core Animation layer.
+@interface PixelHostingView : NSView {
+}
+@end
@interface ChildView(Private)
@@ -163,14 +166,9 @@ static uint32_t gNumberOfWidgetsNeedingEventThread = 0;
- (BOOL)isRectObscuredBySubview:(NSRect)inRect;
-- (void)processPendingRedraws;
-
-- (void)drawRect:(NSRect)aRect inContext:(CGContextRef)aContext;
- (LayoutDeviceIntRegion)nativeDirtyRegionWithBoundingRect:(NSRect)aRect;
-- (BOOL)isUsingMainThreadOpenGL;
- (BOOL)isUsingOpenGL;
- (void)drawUsingOpenGL;
-- (void)drawUsingOpenGLCallback;
- (BOOL)hasRoundedBottomCorners;
- (CGFloat)cornerRadius;
@@ -195,7 +193,6 @@ static uint32_t gNumberOfWidgetsNeedingEventThread = 0;
- (LayoutDeviceIntPoint)convertWindowCoordinates:(NSPoint)aPoint;
- (LayoutDeviceIntPoint)convertWindowCoordinatesRoundDown:(NSPoint)aPoint;
-- (IAPZCTreeManager*)apzctm;
- (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent;
- (void)updateWindowDraggableState;
@@ -204,26 +201,10 @@ static uint32_t gNumberOfWidgetsNeedingEventThread = 0;
@end
-@interface EventThreadRunner : NSObject
-{
- NSThread* mThread;
-}
-- (id)init;
-
-+ (void)start;
-+ (void)stop;
-
-@end
-
@interface NSView(NSThemeFrameCornerRadius)
- (float)roundedCornerRadius;
@end
-@interface NSView(DraggableRegion)
-- (CGSRegionObj)_regionForOpaqueDescendants:(NSRect)aRect forMove:(BOOL)aForMove;
-- (CGSRegionObj)_regionForOpaqueDescendants:(NSRect)aRect forMove:(BOOL)aForMove forUnderTitlebar:(BOOL)aForUnderTitlebar;
-@end
-
@interface NSWindow(NSWindowShouldZoomOnDoubleClick)
+ (BOOL)_shouldZoomOnDoubleClick; // present on 10.7 and above
@end
@@ -380,13 +361,6 @@ nsChildView::~nsChildView()
DestroyCompositor();
- if (mAPZC && gfxPrefs::AsyncPanZoomSeparateEventThread()) {
- gNumberOfWidgetsNeedingEventThread--;
- if (gNumberOfWidgetsNeedingEventThread == 0) {
- [EventThreadRunner stop];
- }
- }
-
// An nsChildView object that was in use can be destroyed without Destroy()
// ever being called on it. So we also need to do a quick, safe cleanup
// here (it's too late to just call Destroy(), which can cause crashes).
@@ -455,7 +429,8 @@ nsChildView::Create(nsIWidget* aParent,
// that NS_NATIVE_WIDGET is the NSView.
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mParentView);
NSRect r = nsCocoaUtils::DevPixelsToCocoaPoints(mBounds, scaleFactor);
- mView = [(NSView<mozView>*)CreateCocoaView(r) retain];
+ mView = [[[[ChildView alloc] initWithFrame:r geckoChild:this] autorelease] retain];
+
if (!mView) {
return NS_ERROR_FAILURE;
}
@@ -488,17 +463,6 @@ nsChildView::Create(nsIWidget* aParent,
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
-// Creates the appropriate child view. Override to create something other than
-// our |ChildView| object. Autoreleases, so caller must retain.
-NSView*
-nsChildView::CreateCocoaView(NSRect inFrame)
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- return [[[ChildView alloc] initWithFrame:inFrame geckoChild:this] autorelease];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
void nsChildView::TearDownView()
{
@@ -982,8 +946,9 @@ NS_IMETHODIMP nsChildView::Resize(double aWidth, double aHeight, bool aRepaint)
[mView setFrame:DevPixelsToCocoaPoints(mBounds)];
});
- if (mVisible && aRepaint)
- [mView setNeedsDisplay:YES];
+ if (mVisible && aRepaint) {
+ [[mView pixelHostingView] setNeedsDisplay:YES];
+ }
NotifyRollupGeometryChange();
ReportSizeEvent();
@@ -1021,8 +986,9 @@ NS_IMETHODIMP nsChildView::Resize(double aX, double aY,
[mView setFrame:DevPixelsToCocoaPoints(mBounds)];
});
- if (mVisible && aRepaint)
- [mView setNeedsDisplay:YES];
+ if (mVisible && aRepaint) {
+ [[mView pixelHostingView] setNeedsDisplay:YES];
+ }
NotifyRollupGeometryChange();
if (isMoving) {
@@ -1341,14 +1307,7 @@ NS_IMETHODIMP nsChildView::Invalidate(const LayoutDeviceIntRect& aRect)
NS_ASSERTION(GetLayerManager()->GetBackendType() != LayersBackend::LAYERS_CLIENT,
"Shouldn't need to invalidate with accelerated OMTC layers!");
- if ([NSView focusView]) {
- // if a view is focussed (i.e. being drawn), then postpone the invalidate so that we
- // don't lose it.
- [mView setNeedsPendingDisplayInRect:DevPixelsToCocoaPoints(aRect)];
- }
- else {
- [mView setNeedsDisplayInRect:DevPixelsToCocoaPoints(aRect)];
- }
+ [[mView pixelHostingView] setNeedsDisplayInRect:DevPixelsToCocoaPoints(aRect)];
return NS_OK;
@@ -1920,13 +1879,6 @@ void
nsChildView::ConfigureAPZCTreeManager()
{
nsBaseWidget::ConfigureAPZCTreeManager();
-
- if (gfxPrefs::AsyncPanZoomSeparateEventThread()) {
- if (gNumberOfWidgetsNeedingEventThread == 0) {
- [EventThreadRunner start];
- }
- gNumberOfWidgetsNeedingEventThread++;
- }
}
void
@@ -2557,14 +2509,6 @@ nsChildView::UpdateVibrancy(const nsTArray<ThemeGeometry>& aThemeGeometries)
vm.UpdateVibrantRegion(VibrancyType::DARK, vibrantDarkRegion);
}
-void
-nsChildView::ClearVibrantAreas()
-{
- if (VibrancyManager::SystemSupportsVibrancy()) {
- EnsureVibrancyManager().ClearVibrantAreas();
- }
-}
-
static VibrancyType
ThemeGeometryTypeToVibrancyType(nsITheme::ThemeGeometryType aThemeGeometryType)
{
@@ -2617,7 +2561,7 @@ nsChildView::EnsureVibrancyManager()
{
MOZ_ASSERT(mView, "Only call this once we have a view!");
if (!mVibrancyManager) {
- mVibrancyManager = MakeUnique<VibrancyManager>(*this, mView);
+ mVibrancyManager = MakeUnique<VibrancyManager>(*this, [mView vibrancyViewsContainer]);
}
return *mVibrancyManager;
}
@@ -2787,9 +2731,10 @@ nsChildView::UpdateWindowDraggingRegion(const LayoutDeviceIntRegion& aRegion)
// Suppress calls to setNeedsDisplay during NSView geometry changes.
ManipulateViewWithoutNeedingDisplay(mView, ^() {
- changed = mNonDraggableRegion.UpdateRegion(nonDraggable, *this, mView, ^() {
- return [[NonDraggableView alloc] initWithFrame:NSZeroRect];
- });
+ changed = mNonDraggableRegion.UpdateRegion(
+ nonDraggable, *this, [mView nonDraggableViewsContainer], ^() {
+ return [[NonDraggableView alloc] initWithFrame:NSZeroRect];
+ });
});
if (changed) {
@@ -3160,6 +3105,31 @@ private:
#pragma mark -
+// ViewRegionContainerView is a view class for certain subviews of ChildView
+// which contain the NSViews created for ViewRegions (see ViewRegion.h).
+// It doesn't do anything interesting, it only acts as a container so that it's
+// easier for ChildView to control the z order of its children.
+@interface ViewRegionContainerView : NSView {
+}
+@end
+
+@implementation ViewRegionContainerView
+
+- (NSView*)hitTest:(NSPoint)aPoint {
+ return nil; // Be transparent to mouse events.
+}
+
+- (BOOL)isFlipped {
+ return [[self superview] isFlipped];
+}
+
+- (BOOL)mouseDownCanMoveWindow {
+ return [[self superview] mouseDownCanMoveWindow];
+}
+
+@end
+;
+
@implementation ChildView
// globalDragPboard is non-null during native drag sessions that did not originate
@@ -3215,7 +3185,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
if ((self = [super initWithFrame:inFrame])) {
mGeckoChild = inChild;
- mPendingDisplay = NO;
mBlockedLastMouseDown = NO;
mExpectingWheelStop = NO;
@@ -3236,6 +3205,20 @@ NSEvent* gLastDragMouseDownEvent = nil;
mCancelSwipeAnimation = nil;
#endif
+ mNonDraggableViewsContainer = [[ViewRegionContainerView alloc] initWithFrame:[self bounds]];
+ mVibrancyViewsContainer = [[ViewRegionContainerView alloc] initWithFrame:[self bounds]];
+
+ [mNonDraggableViewsContainer setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ [mVibrancyViewsContainer setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+
+ [self addSubview:mNonDraggableViewsContainer];
+ [self addSubview:mVibrancyViewsContainer];
+
+ mPixelHostingView = [[PixelHostingView alloc] initWithFrame:[self bounds]];
+ [mPixelHostingView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+
+ [self addSubview:mPixelHostingView];
+
mTopLeftCornerMask = NULL;
}
@@ -3250,10 +3233,9 @@ NSEvent* gLastDragMouseDownEvent = nil;
selector:@selector(systemMetricsChanged)
name:NSSystemColorsDidChangeNotification
object:nil];
- // TODO: replace the string with the constant once we build with the 10.7 SDK
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(scrollbarSystemMetricChanged)
- name:@"NSPreferredScrollerStyleDidChangeNotification"
+ name:NSPreferredScrollerStyleDidChangeNotification
object:nil];
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
selector:@selector(systemMetricsChanged)
@@ -3263,7 +3245,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_surfaceNeedsUpdate:)
name:NSViewGlobalFrameDidChangeNotification
- object:self];
+ object:mPixelHostingView];
return self;
@@ -3348,12 +3330,23 @@ NSEvent* gLastDragMouseDownEvent = nil;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
+- (NSView*)vibrancyViewsContainer {
+ return mVibrancyViewsContainer;
+}
+
+- (NSView*)nonDraggableViewsContainer {
+ return mNonDraggableViewsContainer;
+}
+
+- (NSView*)pixelHostingView {
+ return mPixelHostingView;
+}
+
- (void)dealloc
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[mGLContext release];
- [mPendingDirtyRects release];
[mLastMouseDownEvent release];
[mLastKeyDownEvent release];
[mClickThroughMouseDownEvent release];
@@ -3362,6 +3355,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
+ [mVibrancyViewsContainer removeFromSuperview];
+ [mVibrancyViewsContainer release];
+ [mNonDraggableViewsContainer removeFromSuperview];
+ [mNonDraggableViewsContainer release];
+ [mPixelHostingView removeFromSuperview];
+ [mPixelHostingView release];
[super dealloc];
@@ -3408,82 +3407,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
}
}
-- (void)setNeedsPendingDisplay
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- mPendingFullDisplay = YES;
- if (!mPendingDisplay) {
- [self performSelector:@selector(processPendingRedraws) withObject:nil afterDelay:0];
- mPendingDisplay = YES;
- }
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)setNeedsPendingDisplayInRect:(NSRect)invalidRect
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- if (!mPendingDirtyRects)
- mPendingDirtyRects = [[NSMutableArray alloc] initWithCapacity:1];
- [mPendingDirtyRects addObject:[NSValue valueWithRect:invalidRect]];
- if (!mPendingDisplay) {
- [self performSelector:@selector(processPendingRedraws) withObject:nil afterDelay:0];
- mPendingDisplay = YES;
- }
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-// Clears the queue of any pending invalides
-- (void)processPendingRedraws
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- if (mPendingFullDisplay) {
- [self setNeedsDisplay:YES];
- }
- else if (mPendingDirtyRects) {
- unsigned int count = [mPendingDirtyRects count];
- for (unsigned int i = 0; i < count; ++i) {
- [self setNeedsDisplayInRect:[[mPendingDirtyRects objectAtIndex:i] rectValue]];
- }
- }
- mPendingFullDisplay = NO;
- mPendingDisplay = NO;
- [mPendingDirtyRects release];
- mPendingDirtyRects = nil;
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-- (void)setNeedsDisplayInRect:(NSRect)aRect
-{
- if (![self isUsingOpenGL]) {
- [super setNeedsDisplayInRect:aRect];
- return;
- }
-
- if ([[self window] isVisible] && [self isUsingMainThreadOpenGL]) {
- // Draw without calling drawRect. This prevent us from
- // needing to access the normal window buffer surface unnecessarily, so we
- // waste less time synchronizing the two surfaces. (These synchronizations
- // show up in a profiler as CGSDeviceLock / _CGSLockWindow /
- // _CGSSynchronizeWindowBackingStore.) It also means that Cocoa doesn't
- // have any potentially expensive invalid rect management for us.
- if (!mWaitingForPaint) {
- mWaitingForPaint = YES;
- // Use NSRunLoopCommonModes instead of the default NSDefaultRunLoopMode
- // so that the timer also fires while a native menu is open.
- [self performSelector:@selector(drawUsingOpenGLCallback)
- withObject:nil
- afterDelay:0
- inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
- }
- }
-}
-
- (NSString*)description
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
@@ -3537,25 +3460,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
return YES;
}
-- (void)scrollRect:(NSRect)aRect by:(NSSize)offset
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- // Update any pending dirty rects to reflect the new scroll position
- if (mPendingDirtyRects) {
- unsigned int count = [mPendingDirtyRects count];
- for (unsigned int i = 0; i < count; ++i) {
- NSRect oldRect = [[mPendingDirtyRects objectAtIndex:i] rectValue];
- NSRect newRect = NSOffsetRect(oldRect, offset.width, offset.height);
- [mPendingDirtyRects replaceObjectAtIndex:i
- withObject:[NSValue valueWithRect:newRect]];
- }
- }
- [super scrollRect:aRect by:offset];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
- (BOOL)mouseDownCanMoveWindow
{
// Return YES so that parts of this view can be draggable. The non-draggable
@@ -3567,7 +3471,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
-(void)updateGLContext
{
- [mGLContext setView:self];
+ [mGLContext setView:mPixelHostingView];
[mGLContext update];
}
@@ -3580,11 +3484,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
}
}
-- (BOOL)wantsBestResolutionOpenGLSurface
-{
- return nsCocoaUtils::HiDPIEnabled() ? YES : NO;
-}
-
- (void)viewDidChangeBackingProperties
{
[super viewDidChangeBackingProperties];
@@ -3646,7 +3545,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
LayoutDeviceIntRect boundingRect = mGeckoChild->CocoaPointsToDevPixels(aRect);
const NSRect *rects;
NSInteger count;
- [self getRectsBeingDrawn:&rects count:&count];
+ [mPixelHostingView getRectsBeingDrawn:&rects count:&count];
if (count > MAX_RECTS_IN_REGION) {
return boundingRect;
@@ -3662,53 +3561,34 @@ NSEvent* gLastDragMouseDownEvent = nil;
// The display system has told us that a portion of our view is dirty. Tell
// gecko to paint it
-- (void)drawRect:(NSRect)aRect
+// This method is called from mPixelHostingView's drawRect handler.
+- (void)doDrawRect:(NSRect)aRect
{
- CGContextRef cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- [self drawRect:aRect inContext:cgContext];
-
- // If we're a transparent window and our contents have changed, we need
- // to make sure the shadow is updated to the new contents.
- if ([[self window] isKindOfClass:[BaseWindow class]]) {
- [(BaseWindow*)[self window] deferredInvalidateShadow];
+ if (!NS_IsMainThread()) {
+ // In the presence of CoreAnimation, this method can sometimes be called on
+ // a non-main thread. Ignore those calls because Gecko can only react to
+ // them on the main thread.
+ return;
}
-}
-- (void)drawRect:(NSRect)aRect inContext:(CGContextRef)aContext
-{
if (!mGeckoChild || !mGeckoChild->IsVisible())
return;
-
-#ifdef DEBUG_UPDATE
- LayoutDeviceIntRect geckoBounds = mGeckoChild->GetBounds();
-
- fprintf (stderr, "---- Update[%p][%p] [%f %f %f %f] cgc: %p\n gecko bounds: [%d %d %d %d]\n",
- self, mGeckoChild,
- aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height, aContext,
- geckoBounds.x, geckoBounds.y, geckoBounds.width, geckoBounds.height);
-
- CGAffineTransform xform = CGContextGetCTM(aContext);
- fprintf (stderr, " xform in: [%f %f %f %f %f %f]\n", xform.a, xform.b, xform.c, xform.d, xform.tx, xform.ty);
-#endif
+ CGContextRef cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
if ([self isUsingOpenGL]) {
- // For Gecko-initiated repaints in OpenGL mode, drawUsingOpenGL is
- // directly called from a delayed perform callback - without going through
- // drawRect.
- // Paints that come through here are triggered by something that Cocoa
- // controls, for example by window resizing or window focus changes.
-
// Since this view is usually declared as opaque, the window's pixel
// buffer may now contain garbage which we need to prevent from reaching
// the screen. The only place where garbage can show is in the window
// corners and the vibrant regions of the window - the rest of the window
// is covered by opaque content in our OpenGL surface.
// So we need to clear the pixel buffer contents in these areas.
- mGeckoChild->ClearVibrantAreas();
[self clearCorners];
- // Do GL composition and return.
- [self drawUsingOpenGL];
+ // Force a sync OMTC composite into the OpenGL context and return.
+ LayoutDeviceIntRect geckoBounds = mGeckoChild->GetBounds();
+ LayoutDeviceIntRegion region(geckoBounds);
+
+ mGeckoChild->PaintWindow(region);
return;
}
@@ -3720,54 +3600,31 @@ NSEvent* gLastDragMouseDownEvent = nil;
// multiple dev pixels. But Gecko expects its supplied context to be scaled
// to device pixels, so we need to reverse the scaling.
double scale = mGeckoChild->BackingScaleFactor();
- CGContextSaveGState(aContext);
- CGContextScaleCTM(aContext, 1.0 / scale, 1.0 / scale);
+ CGContextSaveGState(cgContext);
+ CGContextScaleCTM(cgContext, 1.0 / scale, 1.0 / scale);
NSSize viewSize = [self bounds].size;
gfx::IntSize backingSize = gfx::IntSize::Truncate(viewSize.width * scale, viewSize.height * scale);
LayoutDeviceIntRegion region = [self nativeDirtyRegionWithBoundingRect:aRect];
- bool painted = mGeckoChild->PaintWindowInContext(aContext, region, backingSize);
+ bool painted = mGeckoChild->PaintWindowInContext(cgContext, region, backingSize);
// Undo the scale transform so that from now on the context is in
// CocoaPoints again.
- CGContextRestoreGState(aContext);
+ CGContextRestoreGState(cgContext);
- if (!painted && [self isOpaque]) {
+ if (!painted && [mPixelHostingView isOpaque]) {
// Gecko refused to draw, but we've claimed to be opaque, so we have to
// draw something--fill with white.
- CGContextSetRGBFillColor(aContext, 1, 1, 1, 1);
- CGContextFillRect(aContext, NSRectToCGRect(aRect));
+ CGContextSetRGBFillColor(cgContext, 1, 1, 1, 1);
+ CGContextFillRect(cgContext, NSRectToCGRect(aRect));
}
if ([self isCoveringTitlebar]) {
[self drawTitleString];
[self drawTitlebarHighlight];
- [self maskTopCornersInContext:aContext];
+ [self maskTopCornersInContext:cgContext];
}
-
-#ifdef DEBUG_UPDATE
- fprintf (stderr, "---- update done ----\n");
-
-#if 0
- CGContextSetRGBStrokeColor (aContext,
- ((((unsigned long)self) & 0xff)) / 255.0,
- ((((unsigned long)self) & 0xff00) >> 8) / 255.0,
- ((((unsigned long)self) & 0xff0000) >> 16) / 255.0,
- 0.5);
-#endif
- CGContextSetRGBStrokeColor(aContext, 1, 0, 0, 0.8);
- CGContextSetLineWidth(aContext, 4.0);
- CGContextStrokeRect(aContext, NSRectToCGRect(aRect));
-#endif
-}
-
-- (BOOL)isUsingMainThreadOpenGL
-{
- if (!mGeckoChild || ![self window])
- return NO;
-
- return mGeckoChild->GetLayerManager(nullptr)->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL;
}
- (BOOL)isUsingOpenGL
@@ -3775,33 +3632,9 @@ NSEvent* gLastDragMouseDownEvent = nil;
if (!mGeckoChild || ![self window])
return NO;
- return mGLContext || mUsingOMTCompositor || [self isUsingMainThreadOpenGL];
-}
-
-- (void)drawUsingOpenGL
-{
- PROFILER_LABEL("ChildView", "drawUsingOpenGL",
- js::ProfileEntry::Category::GRAPHICS);
-
- if (![self isUsingOpenGL] || !mGeckoChild->IsVisible())
- return;
-
- mWaitingForPaint = NO;
-
- LayoutDeviceIntRect geckoBounds = mGeckoChild->GetBounds();
- LayoutDeviceIntRegion region(geckoBounds);
-
- mGeckoChild->PaintWindow(region);
+ return mGLContext || mUsingOMTCompositor;
}
-// Called asynchronously after setNeedsDisplay in order to avoid entering the
-// normal drawing machinery.
-- (void)drawUsingOpenGLCallback
-{
- if (mWaitingForPaint) {
- [self drawUsingOpenGL];
- }
-}
- (BOOL)hasRoundedBottomCorners
{
@@ -4803,12 +4636,6 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
- if (gfxPrefs::AsyncPanZoomSeparateEventThread() && [self apzctm]) {
- // Disable main-thread scrolling completely when using APZ with the
- // separate event thread. This is bug 1013412.
- return;
- }
-
nsAutoRetainCocoaObject kungFuDeathGrip(self);
ChildViewMouseTracker::MouseScrolled(theEvent);
@@ -4928,105 +4755,6 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-- (void)handleAsyncScrollEvent:(CGEventRef)cgEvent ofType:(CGEventType)type
-{
- IAPZCTreeManager* apzctm = [self apzctm];
- if (!apzctm) {
- return;
- }
-
- CGPoint loc = CGEventGetLocation(cgEvent);
- loc.y = nsCocoaUtils::FlippedScreenY(loc.y);
- NSPoint locationInWindow =
- nsCocoaUtils::ConvertPointFromScreen([self window], NSPointFromCGPoint(loc));
- ScreenIntPoint location = ViewAs<ScreenPixel>(
- [self convertWindowCoordinates:locationInWindow],
- PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent);
-
- static NSTimeInterval sStartTime = [NSDate timeIntervalSinceReferenceDate];
- static TimeStamp sStartTimeStamp = TimeStamp::Now();
-
- if (type == kCGEventScrollWheel) {
- NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
- NSEventPhase phase = nsCocoaUtils::EventPhase(event);
- NSEventPhase momentumPhase = nsCocoaUtils::EventMomentumPhase(event);
- CGFloat pixelDeltaX = 0, pixelDeltaY = 0;
- nsCocoaUtils::GetScrollingDeltas(event, &pixelDeltaX, &pixelDeltaY);
- uint32_t eventTime = ([event timestamp] - sStartTime) * 1000;
- TimeStamp eventTimeStamp = sStartTimeStamp +
- TimeDuration::FromSeconds([event timestamp] - sStartTime);
- NSPoint locationInWindowMoved = NSMakePoint(
- locationInWindow.x + pixelDeltaX,
- locationInWindow.y - pixelDeltaY);
- ScreenIntPoint locationMoved = ViewAs<ScreenPixel>(
- [self convertWindowCoordinates:locationInWindowMoved],
- PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent);
- ScreenPoint delta = ScreenPoint(locationMoved - location);
- ScrollableLayerGuid guid;
-
- // MayBegin and Cancelled are dispatched when the fingers start or stop
- // touching the touchpad before any scrolling has occurred. These events
- // can be used to control scrollbar visibility or interrupt scroll
- // animations. They are only dispatched on 10.8 or later, and only by
- // relatively modern devices.
- if (phase == NSEventPhaseMayBegin) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_MAYSTART, eventTime,
- eventTimeStamp, location, ScreenPoint(0, 0), 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- return;
- }
- if (phase == NSEventPhaseCancelled) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_CANCELLED, eventTime,
- eventTimeStamp, location, ScreenPoint(0, 0), 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- return;
- }
-
- // Legacy scroll events are dispatched by devices that do not have a
- // concept of a scroll gesture, for example by USB mice with
- // traditional mouse wheels.
- // For these kinds of scrolls, we want to surround every single scroll
- // event with a PANGESTURE_START and a PANGESTURE_END event. The APZC
- // needs to know that the real scroll gesture can end abruptly after any
- // one of these events.
- bool isLegacyScroll = (phase == NSEventPhaseNone &&
- momentumPhase == NSEventPhaseNone && delta != ScreenPoint(0, 0));
-
- if (phase == NSEventPhaseBegan || isLegacyScroll) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_START, eventTime,
- eventTimeStamp, location, ScreenPoint(0, 0), 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- }
- if (momentumPhase == NSEventPhaseNone && delta != ScreenPoint(0, 0)) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_PAN, eventTime,
- eventTimeStamp, location, delta, 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- }
- if (phase == NSEventPhaseEnded || isLegacyScroll) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_END, eventTime,
- eventTimeStamp, location, ScreenPoint(0, 0), 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- }
-
- // Any device that can dispatch momentum events supports all three momentum phases.
- if (momentumPhase == NSEventPhaseBegan) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMSTART, eventTime,
- eventTimeStamp, location, ScreenPoint(0, 0), 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- }
- if (momentumPhase == NSEventPhaseChanged && delta != ScreenPoint(0, 0)) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMPAN, eventTime,
- eventTimeStamp, location, delta, 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- }
- if (momentumPhase == NSEventPhaseEnded) {
- PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMEND, eventTime,
- eventTimeStamp, location, ScreenPoint(0, 0), 0);
- apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
- }
- }
-}
-
-(NSMenu*)menuForEvent:(NSEvent*)theEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
@@ -5571,11 +5299,6 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
return mGeckoChild->CocoaPointsToDevPixelsRoundDown(localPoint);
}
-- (IAPZCTreeManager*)apzctm
-{
- return mGeckoChild ? mGeckoChild->APZCTM() : nullptr;
-}
-
// This is a utility function used by NSView drag event methods
// to send events. It contains all of the logic needed for Gecko
// dragging to work. Returns the appropriate cocoa drag operation code.
@@ -6209,6 +5932,26 @@ nsChildView::GetSelectionAsPlaintext(nsAString& aResult)
@end
+@implementation PixelHostingView
+
+- (BOOL)isFlipped {
+ return YES;
+}
+
+- (NSView*)hitTest:(NSPoint)aPoint {
+ return nil;
+}
+
+- (void)drawRect:(NSRect)aRect {
+ [(ChildView*)[self superview] doDrawRect:aRect];
+}
+
+- (BOOL)wantsBestResolutionOpenGLSurface {
+ return nsCocoaUtils::HiDPIEnabled() ? YES : NO;
+}
+
+@end
+
#pragma mark -
void
@@ -6377,106 +6120,6 @@ ChildViewMouseTracker::WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent,
#pragma mark -
-@interface EventThreadRunner(Private)
-- (void)runEventThread;
-- (void)shutdownAndReleaseCalledOnEventThread;
-- (void)shutdownAndReleaseCalledOnAnyThread;
-- (void)handleEvent:(CGEventRef)cgEvent type:(CGEventType)type;
-@end
-
-static EventThreadRunner* sEventThreadRunner = nil;
-
-@implementation EventThreadRunner
-
-+ (void)start
-{
- sEventThreadRunner = [[EventThreadRunner alloc] init];
-}
-
-+ (void)stop
-{
- if (sEventThreadRunner) {
- [sEventThreadRunner shutdownAndReleaseCalledOnAnyThread];
- sEventThreadRunner = nil;
- }
-}
-
-- (id)init
-{
- if ((self = [super init])) {
- mThread = nil;
- [NSThread detachNewThreadSelector:@selector(runEventThread)
- toTarget:self
- withObject:nil];
- }
- return self;
-}
-
-static CGEventRef
-HandleEvent(CGEventTapProxy aProxy, CGEventType aType,
- CGEventRef aEvent, void* aClosure)
-{
- [(EventThreadRunner*)aClosure handleEvent:aEvent type:aType];
- return aEvent;
-}
-
-- (void)runEventThread
-{
- char aLocal;
- profiler_register_thread("APZC Event Thread", &aLocal);
- PR_SetCurrentThreadName("APZC Event Thread");
-
- mThread = [NSThread currentThread];
- ProcessSerialNumber currentProcess;
- GetCurrentProcess(&currentProcess);
- CFMachPortRef eventPort =
- CGEventTapCreateForPSN(&currentProcess,
- kCGHeadInsertEventTap,
- kCGEventTapOptionListenOnly,
- CGEventMaskBit(kCGEventScrollWheel),
- HandleEvent,
- self);
- CFRunLoopSourceRef eventPortSource =
- CFMachPortCreateRunLoopSource(kCFAllocatorSystemDefault, eventPort, 0);
- CFRunLoopAddSource(CFRunLoopGetCurrent(), eventPortSource, kCFRunLoopCommonModes);
- CFRunLoopRun();
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventPortSource, kCFRunLoopCommonModes);
- CFRelease(eventPortSource);
- CFRelease(eventPort);
- [self release];
-}
-
-- (void)shutdownAndReleaseCalledOnEventThread
-{
- CFRunLoopStop(CFRunLoopGetCurrent());
-}
-
-- (void)shutdownAndReleaseCalledOnAnyThread
-{
- [self performSelector:@selector(shutdownAndReleaseCalledOnEventThread) onThread:mThread withObject:nil waitUntilDone:NO];
-}
-
-static const CGEventField kCGWindowNumberField = (const CGEventField) 51;
-
-// Called on scroll thread
-- (void)handleEvent:(CGEventRef)cgEvent type:(CGEventType)type
-{
- if (type != kCGEventScrollWheel) {
- return;
- }
-
- int windowNumber = CGEventGetIntegerValueField(cgEvent, kCGWindowNumberField);
- NSWindow* window = [NSApp windowWithWindowNumber:windowNumber];
- if (!window || ![window isKindOfClass:[BaseWindow class]]) {
- return;
- }
-
- ChildView* childView = [(BaseWindow*)window mainChildView];
- [childView handleAsyncScrollEvent:cgEvent ofType:type];
-}
-
-@end
-
@interface NSView (MethodSwizzling)
- (BOOL)nsChildView_NSView_mouseDownCanMoveWindow;
@end