macOS: Move QNSView drawing related functionality to its own file
Change-Id: Iaeaa5c57368445a1fd67d110823c919aa7173a7a Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
bbdc1b5ccb
commit
9b604a151a
@ -58,13 +58,15 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
|||||||
|
|
||||||
- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow;
|
- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow;
|
||||||
|
|
||||||
|
- (void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface QT_MANGLE_NAMESPACE(QNSView) (DrawingAPI)
|
||||||
|
- (void)requestUpdate;
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
|
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
- (void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint;
|
|
||||||
- (void)requestUpdate;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface QT_MANGLE_NAMESPACE(QNSView) (MouseAPI)
|
@interface QT_MANGLE_NAMESPACE(QNSView) (MouseAPI)
|
||||||
|
@ -74,6 +74,9 @@
|
|||||||
- (BOOL)isTransparentForUserInput;
|
- (BOOL)isTransparentForUserInput;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface QT_MANGLE_NAMESPACE(QNSView) (Drawing)
|
||||||
|
@end
|
||||||
|
|
||||||
@interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject
|
@interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject
|
||||||
- (instancetype)initWithView:(QNSView *)theView;
|
- (instancetype)initWithView:(QNSView *)theView;
|
||||||
- (void)mouseMoved:(NSEvent *)theEvent;
|
- (void)mouseMoved:(NSEvent *)theEvent;
|
||||||
@ -231,18 +234,6 @@
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
- (void)setQCocoaGLContext:(QCocoaGLContext *)context
|
|
||||||
{
|
|
||||||
m_glContext = context;
|
|
||||||
[m_glContext->nsOpenGLContext() setView:self];
|
|
||||||
if (![m_glContext->nsOpenGLContext() view]) {
|
|
||||||
//was unable to set view
|
|
||||||
m_shouldSetGLContextinDrawRect = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (void)viewDidMoveToSuperview
|
- (void)viewDidMoveToSuperview
|
||||||
{
|
{
|
||||||
if (!m_platformWindow)
|
if (!m_platformWindow)
|
||||||
@ -296,107 +287,6 @@
|
|||||||
[super removeFromSuperview];
|
[super removeFromSuperview];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isOpaque
|
|
||||||
{
|
|
||||||
if (!m_platformWindow)
|
|
||||||
return true;
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (!m_platformWindow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QRegion exposedRegion;
|
|
||||||
const NSRect *dirtyRects;
|
|
||||||
NSInteger numDirtyRects;
|
|
||||||
[self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
|
|
||||||
for (int i = 0; i < numDirtyRects; ++i)
|
|
||||||
exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
|
|
||||||
|
|
||||||
qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
|
|
||||||
[self updateRegion:exposedRegion];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateRegion:(QRegion)dirtyRegion
|
|
||||||
{
|
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
if (m_glContext && m_shouldSetGLContextinDrawRect) {
|
|
||||||
[m_glContext->nsOpenGLContext() setView:self];
|
|
||||||
m_shouldSetGLContextinDrawRect = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window());
|
|
||||||
|
|
||||||
if (m_updateRequested) {
|
|
||||||
Q_ASSERT(windowPrivate->updateRequestPending);
|
|
||||||
qCDebug(lcQpaWindow) << "Delivering update request to" << m_platformWindow->window();
|
|
||||||
windowPrivate->deliverUpdateRequest();
|
|
||||||
m_updateRequested = false;
|
|
||||||
} else {
|
|
||||||
m_platformWindow->handleExposeEvent(dirtyRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(lcQpaDrawing) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
|
|
||||||
dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)wantsUpdateLayer
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateLayer
|
|
||||||
{
|
|
||||||
if (!m_platformWindow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qCDebug(lcQpaDrawing) << "[QNSView updateLayer]" << m_platformWindow->window();
|
|
||||||
|
|
||||||
// FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
|
|
||||||
[self updateRegion:QRectF::fromCGRect(self.bounds).toRect()];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidChangeBackingProperties
|
|
||||||
{
|
|
||||||
if (self.layer)
|
|
||||||
self.layer.contentsScale = self.window.backingScaleFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isFlipped
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isTransparentForUserInput
|
- (BOOL)isTransparentForUserInput
|
||||||
{
|
{
|
||||||
return m_platformWindow->window() &&
|
return m_platformWindow->window() &&
|
||||||
@ -470,6 +360,7 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#include "qnsview_drawing.mm"
|
||||||
#include "qnsview_mouse.mm"
|
#include "qnsview_mouse.mm"
|
||||||
#include "qnsview_touch.mm"
|
#include "qnsview_touch.mm"
|
||||||
#include "qnsview_gestures.mm"
|
#include "qnsview_gestures.mm"
|
||||||
|
162
src/plugins/platforms/cocoa/qnsview_drawing.mm
Normal file
162
src/plugins/platforms/cocoa/qnsview_drawing.mm
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or (at your option) the GNU General
|
||||||
|
** Public license version 3 or any later version approved by the KDE Free
|
||||||
|
** Qt Foundation. The licenses are as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||||
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// This file is included from qnsview.mm, and only used to organize the code
|
||||||
|
|
||||||
|
@implementation QT_MANGLE_NAMESPACE(QNSView) (DrawingAPI)
|
||||||
|
|
||||||
|
- (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
- (void)setQCocoaGLContext:(QCocoaGLContext *)context
|
||||||
|
{
|
||||||
|
m_glContext = context;
|
||||||
|
[m_glContext->nsOpenGLContext() setView:self];
|
||||||
|
if (![m_glContext->nsOpenGLContext() view]) {
|
||||||
|
//was unable to set view
|
||||||
|
m_shouldSetGLContextinDrawRect = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation QT_MANGLE_NAMESPACE(QNSView) (Drawing)
|
||||||
|
|
||||||
|
- (BOOL)isOpaque
|
||||||
|
{
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return true;
|
||||||
|
return m_platformWindow->isOpaque();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isFlipped
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setNeedsDisplayInRect:(NSRect)rect
|
||||||
|
{
|
||||||
|
qDebug() << "setNeedsDisplayInRect" << QRectF::fromCGRect(rect);
|
||||||
|
[super setNeedsDisplayInRect:rect];
|
||||||
|
m_updateRequested = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect:(NSRect)dirtyRect
|
||||||
|
{
|
||||||
|
Q_UNUSED(dirtyRect);
|
||||||
|
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QRegion exposedRegion;
|
||||||
|
const NSRect *dirtyRects;
|
||||||
|
NSInteger numDirtyRects;
|
||||||
|
[self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
|
||||||
|
for (int i = 0; i < numDirtyRects; ++i)
|
||||||
|
exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
|
||||||
|
|
||||||
|
qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
|
||||||
|
[self updateRegion:exposedRegion];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateRegion:(QRegion)dirtyRegion
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
if (m_glContext && m_shouldSetGLContextinDrawRect) {
|
||||||
|
[m_glContext->nsOpenGLContext() setView:self];
|
||||||
|
m_shouldSetGLContextinDrawRect = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window());
|
||||||
|
|
||||||
|
if (m_updateRequested) {
|
||||||
|
Q_ASSERT(windowPrivate->updateRequestPending);
|
||||||
|
qCDebug(lcQpaWindow) << "Delivering update request to" << m_platformWindow->window();
|
||||||
|
windowPrivate->deliverUpdateRequest();
|
||||||
|
m_updateRequested = false;
|
||||||
|
} else {
|
||||||
|
m_platformWindow->handleExposeEvent(dirtyRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(lcQpaDrawing) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
|
||||||
|
dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)wantsUpdateLayer
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateLayer
|
||||||
|
{
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qCDebug(lcQpaDrawing) << "[QNSView updateLayer]" << m_platformWindow->window();
|
||||||
|
|
||||||
|
// FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
|
||||||
|
[self updateRegion:QRectF::fromCGRect(self.bounds).toRect()];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidChangeBackingProperties
|
||||||
|
{
|
||||||
|
if (self.layer)
|
||||||
|
self.layer.contentsScale = self.window.backingScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue
Block a user