diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index c929d51d48..71f7ef7c5d 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -296,7 +296,6 @@ public: if (isSharedWindow) { - r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); [view setFrame: r]; } else @@ -326,10 +325,6 @@ public: flipScreenRect (r); } - else - { - r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height; - } return convertToRectInt (r); } @@ -437,7 +432,7 @@ public: if (NSWindow* const viewWindow = [view window]) { NSRect windowFrame = [viewWindow frame]; - NSPoint windowPoint = [view convertPoint: NSMakePoint (localPos.x, viewFrame.size.height - localPos.y) toView: nil]; + NSPoint windowPoint = [view convertPoint: NSMakePoint (localPos.x, localPos.y) toView: nil]; NSPoint screenPoint = NSMakePoint (windowFrame.origin.x + windowPoint.x, windowFrame.origin.y + windowPoint.y); @@ -448,7 +443,7 @@ public: } NSView* v = [view hitTest: NSMakePoint (viewFrame.origin.x + localPos.getX(), - viewFrame.origin.y + viewFrame.size.height - localPos.getY())]; + viewFrame.origin.y + localPos.getY())]; return trueIfInAChildWindow ? (v != nil) : (v == view); @@ -463,8 +458,8 @@ public: NSRect v = [view convertRect: [view frame] toView: nil]; NSRect w = [window frame]; - b.setTop ((int) (w.size.height - (v.origin.y + v.size.height))); - b.setBottom ((int) v.origin.y); + b.setTop ((int) v.origin.y); + b.setBottom ((int) (w.size.height - (v.origin.y + v.size.height))); b.setLeft ((int) v.origin.x); b.setRight ((int) (w.size.width - (v.origin.x + v.size.width))); } @@ -913,14 +908,14 @@ public: #if USE_COREGRAPHICS_RENDERING if (usingCoreGraphics) { + CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, 0, getComponent().getHeight())); CoreGraphicsContext context (cg, (float) [view frame].size.height); - invokePaint (context); + handlePaint (context); } else #endif { - const Point offset (-roundToInt (r.origin.x), - -roundToInt ([view frame].size.height - (r.origin.y + r.size.height))); + const Point offset (-roundToInt (r.origin.x), -roundToInt (r.origin.y)); auto clipW = (int) (r.size.width + 0.5f); auto clipH = (int) (r.size.height + 0.5f); @@ -941,17 +936,18 @@ public: clip.scaleAll (intScale); auto context = component.getLookAndFeel() - .createGraphicsContext (temp, offset * intScale, clip); + .createGraphicsContext (temp, offset * intScale, clip); if (intScale != 1) context->addTransform (AffineTransform::scale (displayScale)); - invokePaint (*context); + handlePaint (*context); } detail::ColorSpacePtr colourSpace { CGColorSpaceCreateWithName (kCGColorSpaceSRGB) }; CGImageRef image = juce_createCoreGraphicsImage (temp, colourSpace.get(), false); - CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, clipW, clipH), image); + CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, r.origin.x, r.origin.y + clipH)); + CGContextDrawImage (cg, CGRectMake (0.0f, 0.0f, clipW, clipH), image); CGImageRelease (image); } } @@ -964,7 +960,7 @@ public: // a few when there's a lot of activity. // As a work around for this, we use a RectangleList to do our own coalescing of regions before // asynchronously asking the OS to repaint them. - deferredRepaints.add ((float) area.getX(), (float) ([view frame].size.height - area.getBottom()), + deferredRepaints.add ((float) area.getX(), (float) area.getY(), (float) area.getWidth(), (float) area.getHeight()); if (isTimerRunning()) @@ -1008,11 +1004,6 @@ public: deferredRepaints.clear(); } - void invokePaint (LowLevelGraphicsContext& context) - { - handlePaint (context); - } - void performAnyPendingRepaintsNow() override { [view displayIfNeeded]; @@ -1320,7 +1311,7 @@ public: static Point getMousePos (NSEvent* e, NSView* view) { NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil]; - return { (float) p.x, (float) ([view frame].size.height - p.y) }; + return { (float) p.x, (float) p.y }; } static int getModifierForButtonNumber (const NSInteger num) @@ -1356,7 +1347,7 @@ public: NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; ComponentPeer::DragInfo dragInfo; - dragInfo.position.setXY ((int) p.x, (int) ([view frame].size.height - p.y)); + dragInfo.position.setXY ((int) p.x, (int) p.y); if (contentType == NSPasteboardTypeString) dragInfo.text = nsStringToJuce ([pasteboard stringForType: NSPasteboardTypeString]); @@ -1522,13 +1513,12 @@ private: [view getRectsBeingDrawn: &rects count: &numRects]; const Rectangle clipBounds (clipW, clipH); - auto viewH = [view frame].size.height; clip.ensureStorageAllocated ((int) numRects); for (int i = 0; i < numRects; ++i) clip.addWithoutMerging (clipBounds.getIntersection (Rectangle (roundToInt (rects[i].origin.x) + offset.x, - roundToInt (viewH - (rects[i].origin.y + rects[i].size.height)) + offset.y, + roundToInt (rects[i].origin.y) + offset.y, roundToInt (rects[i].size.width), roundToInt (rects[i].size.height)))); } @@ -1741,6 +1731,8 @@ struct JuceNSViewClass : public ObjCClass addMethod (@selector (cut:), cut, "v@:@"); addMethod (@selector (selectAll:), selectAll, "v@:@"); + addMethod (@selector (isFlipped), isFlipped, "c@:"); + addMethod (NSViewComponentPeer::dismissModalsSelector, dismissModals, "v@:"); addMethod (NSViewComponentPeer::asyncMouseDownSelector, asyncMouseDown, "v@:@"); addMethod (NSViewComponentPeer::asyncMouseUpSelector, asyncMouseUp, "v@:@"); @@ -1816,6 +1808,8 @@ private: static void dismissModals (id self, SEL) { if (auto* p = getOwner (self)) p->dismissModals(); } static void becomeKey (id self, SEL) { if (auto* p = getOwner (self)) p->becomeKey(); } + static BOOL isFlipped (id, SEL) { return true; } + static void viewWillDraw (id self, SEL) { // Without setting contentsFormat macOS Big Sur will always set the invalid area @@ -2099,6 +2093,7 @@ struct JuceNSWindowClass : public ObjCClass addMethod (@selector (windowWillStartLiveResize:), windowWillStartLiveResize, "v@:@"); addMethod (@selector (windowDidEndLiveResize:), windowDidEndLiveResize, "v@:@"); addMethod (@selector (window:shouldPopUpDocumentPathMenu:), shouldPopUpPathMenu, "B@:@", @encode (NSMenu*)); + addMethod (@selector (isFlipped), isFlipped, "c@:"); addMethod (@selector (window:shouldDragDocumentWithEvent:from:withPasteboard:), shouldAllowIconDrag, "B@:@", @encode (NSEvent*), @encode (NSPoint), @encode (NSPasteboard*)); @@ -2115,6 +2110,8 @@ private: } //============================================================================== + static BOOL isFlipped (id, SEL) { return true; } + static BOOL canBecomeKeyWindow (id self, SEL) { auto* owner = getOwner (self); @@ -2186,7 +2183,6 @@ private: return proposedFrameSize; NSRect frameRect = [(NSWindow*) self frame]; - frameRect.origin.y -= proposedFrameSize.height - frameRect.size.height; frameRect.size = proposedFrameSize; frameRect = owner->constrainRect (frameRect); diff --git a/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/modules/juce_gui_basics/native/juce_mac_Windowing.mm index 269c7daa38..7d3b1b7911 100644 --- a/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -466,12 +466,6 @@ struct DisplaySettingsChangeCallback : private DeletedAtShutdown JUCE_IMPLEMENT_SINGLETON (DisplaySettingsChangeCallback) -static Rectangle convertDisplayRect (NSRect r, CGFloat mainScreenBottom) -{ - r.origin.y = mainScreenBottom - (r.origin.y + r.size.height); - return convertToRectInt (r); -} - static Displays::Display getDisplayFromScreen (NSScreen* s, CGFloat& mainScreenBottom, const float masterScale) { Displays::Display d; @@ -481,8 +475,8 @@ static Displays::Display getDisplayFromScreen (NSScreen* s, CGFloat& mainScreenB if (d.isMain) mainScreenBottom = [s frame].size.height; - d.userArea = convertDisplayRect ([s visibleFrame], mainScreenBottom) / masterScale; - d.totalArea = convertDisplayRect ([s frame], mainScreenBottom) / masterScale; + d.userArea = convertToRectInt ([s visibleFrame]) / masterScale; + d.totalArea = convertToRectInt ([s frame]) / masterScale; d.scale = masterScale; if ([s respondsToSelector: @selector (backingScaleFactor)]) diff --git a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index 6326283b99..9d7d65d69a 100644 --- a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -125,25 +125,12 @@ public: [view release]; } - void componentMovedOrResized (Component& comp, bool wasMoved, bool wasResized) override - { - ComponentMovementWatcher::componentMovedOrResized (comp, wasMoved, wasResized); - - // The ComponentMovementWatcher version of this method avoids calling - // us when the top-level comp is resized, but for an NSView we need to know this - // because with inverted coordinates, we need to update the position even if the - // top-left pos hasn't changed - if (comp.isOnDesktop() && wasResized) - componentMovedOrResized (wasMoved, wasResized); - } - void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override { if (auto* peer = owner.getTopLevelComponent()->getPeer()) { - auto r = makeNSRect (peer->getAreaCoveredBy (owner)); - r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); - [view setFrame: r]; + const auto newArea = makeNSRect (peer->getAreaCoveredBy (owner)); + [view setFrame: newArea]; } } @@ -204,8 +191,8 @@ private: }; //============================================================================== -NSViewComponent::NSViewComponent() {} -NSViewComponent::~NSViewComponent() {} +NSViewComponent::NSViewComponent() = default; +NSViewComponent::~NSViewComponent() = default; void NSViewComponent::setView (void* view) { @@ -232,8 +219,15 @@ void NSViewComponent::resizeToFitView() { if (attachment != nullptr) { - auto r = [static_cast (attachment.get())->view frame]; + auto* view = static_cast (attachment.get())->view; + auto r = [view frame]; setBounds (Rectangle ((int) r.size.width, (int) r.size.height)); + + if (auto* peer = getTopLevelComponent()->getPeer()) + { + const auto position = peer->getAreaCoveredBy (*this).getPosition().toFloat(); + [view setFrameOrigin: NSMakePoint (position.x, position.y)]; + } } }