summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qnsview.mm
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2018-01-22 17:28:10 +0100
committerJani Heikkinen <jani.heikkinen@qt.io>2018-02-01 13:07:03 +0000
commit7d1962cada48f8c351909d1ccc14b13c3adaa542 (patch)
treebb19cb2b58bb321f781d977bf053347435e76412 /src/plugins/platforms/cocoa/qnsview.mm
parent9f065554ffea0e3716b76e4bee4a60f0044193ce (diff)
macOS: Handle update requests via setNeedsDisplay more carefully
Instead of trying to detect situations where we need to send a real expose event instead of an update request in response to a drawRect call, we keep track of when we've asked the view to display due to a requestUpdate call, and only deliver the corresponding drawRect as an update request if no other code has asked the view to display. This should cover all cases of asking the view to display, issued from our code or from AppKit, such as the view changing its backing scale factor, or otherwise needing a real expose event. Task-number: QTBUG-65663 Change-Id: I1783787823aee889dad8e48f34a1cb0f1b7b06bd Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa/qnsview.mm')
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm44
1 files changed, 35 insertions, 9 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 61f0012a2d..e3bee95ad9 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -147,6 +147,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
m_isMenuView = false;
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
+ m_updateRequested = false;
}
return self;
}
@@ -299,6 +300,25 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return m_platformWindow->isOpaque();
}
+- (void)requestUpdate
+{
+ if (self.needsDisplay) {
+ // If the view already has needsDisplay set it means that there may be code waiting for
+ // a real expose event, so we can't issue setNeedsDisplay now as a way to trigger an
+ // update request. We will re-trigger requestUpdate from drawRect.
+ return;
+ }
+
+ [self setNeedsDisplay:YES];
+ m_updateRequested = true;
+}
+
+- (void)setNeedsDisplayInRect:(NSRect)rect
+{
+ [super setNeedsDisplayInRect:rect];
+ m_updateRequested = false;
+}
+
- (void)drawRect:(NSRect)dirtyRect
{
Q_UNUSED(dirtyRect);
@@ -322,18 +342,24 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
#endif
- m_platformWindow->handleExposeEvent(exposedRegion);
+ QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window());
+
+ if (m_updateRequested) {
+ Q_ASSERT(windowPrivate->updateRequestPending);
+ qCDebug(lcQpaCocoaWindow) << "Delivering update request to" << m_platformWindow->window();
+ windowPrivate->deliverUpdateRequest();
+ m_updateRequested = false;
+ } else {
+ m_platformWindow->handleExposeEvent(exposedRegion);
+ }
- if (qt_window_private(m_platformWindow->window())->updateRequestPending) {
- // A call to QWindow::requestUpdate was issued during the expose event, or we
- // had to deliver a real expose event and still need to deliver the update.
- // But AppKit will reset the needsDisplay state of the view after completing
+ if (windowPrivate->updateRequestPending) {
+ // A call to QWindow::requestUpdate was issued during event delivery above,
+ // but AppKit will reset the needsDisplay state of the view after completing
// the current display cycle, so we need to defer the request to redisplay.
// FIXME: Perhaps this should be a trigger to enable CADisplayLink?
- qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
- dispatch_async(dispatch_get_main_queue (), ^{
- [self setNeedsDisplay:YES];
- });
+ qCDebug(lcQpaCocoaWindow) << "Pending update request, triggering re-display";
+ dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; });
}
}