Merge "Merge remote-tracking branch 'origin/5.12' into 5.13" into refs/staging/5.13

bb10
Liang Qi 2019-02-12 18:01:29 +00:00 committed by The Qt Project
commit 93bcd488af
24 changed files with 176 additions and 154 deletions

View File

@ -229,7 +229,10 @@ isEmpty($${target_prefix}.INCDIRS) {
line ~= s/^[ \\t]*// # remove leading spaces
contains(line, "LIBRARY_PATH=.*") {
line ~= s/^LIBRARY_PATH=// # remove leading LIBRARY_PATH=
paths = $$split(line, $$QMAKE_DIRLIST_SEP)
equals(QMAKE_HOST.os, Windows): \
paths = $$split(line, ;)
else: \
paths = $$split(line, $$QMAKE_DIRLIST_SEP)
for (path, paths): \
QMAKE_DEFAULT_LIBDIRS += $$clean_path($$path)
} else: contains(line, "Library search paths:") {

View File

@ -12,11 +12,11 @@ QMKSRC = $(SOURCE_PATH)\qmake
#
!if "$(QMAKESPEC)" == "win32-icc"
CXX = icl
LINKER = link
LINKER = xilink
CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11
!elseif "$(QMAKESPEC)" == "win32-clang-msvc"
CXX = clang-cl
LINKER = link
LINKER = lld-link
CFLAGS_EXTRA = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value
!else
CXX = cl

View File

@ -52,24 +52,6 @@ struct CoreTextFontEngineData {
/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
static CGFloat
coretext_font_size_from_ptem (float ptem)
{
/* CoreText points are CSS pixels (96 per inch),
* NOT typographic points (72 per inch).
*
* https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
*/
ptem *= 96.f / 72.f;
return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
}
static float
coretext_font_size_to_ptem (CGFloat size)
{
size *= 72.f / 96.f;
return size <= 0.f ? 0 : size;
}
static void
release_table_data (void *user_data)
{
@ -104,7 +86,7 @@ _hb_cg_font_release (void *data)
HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
fabs (CTFontGetSize ((CTFontRef) data) - font->ptem) <= .5
)
static CTFontDescriptorRef
@ -308,7 +290,8 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
CGFloat font_size = font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem;
CTFontRef ct_font = create_ct_font (cg_font, font_size);
if (unlikely (!ct_font))
{
@ -340,7 +323,7 @@ hb_coretext_font_create (CTFontRef ct_font)
if (unlikely (hb_object_is_inert (font)))
return font;
hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
hb_font_set_ptem (font, CTFontGetSize (ct_font));
/* Let there be dragons here... */
HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font);

View File

@ -204,7 +204,7 @@ void QWaitCondition::wakeAll()
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
if (quint64(time) > quint64(std::numeric_limits<qint64>::max()))
if (time == std::numeric_limits<unsigned long>::max())
return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever));
return wait(mutex, QDeadlineTimer(time));
}
@ -231,6 +231,8 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
if (time == std::numeric_limits<unsigned long>::max())
return wait(readWriteLock, QDeadlineTimer(QDeadlineTimer::Forever));
return wait(readWriteLock, QDeadlineTimer(time));
}

View File

@ -1125,13 +1125,14 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
for (int index = 0; index < sectionNodesCount; ++index) {
Q_ASSERT(state != Invalid);
if (QStringRef(input, pos, separators.at(index).size()) != separators.at(index)) {
QDTPDEBUG << "invalid because" << input->midRef(pos, separators.at(index).size())
<< "!=" << separators.at(index)
const QString &separator = separators.at(index);
if (input->midRef(pos, separator.size()) != separator) {
QDTPDEBUG << "invalid because" << input->midRef(pos, separator.size())
<< "!=" << separator
<< index << pos << currentSectionIndex;
return StateNode();
}
pos += separators.at(index).size();
pos += separator.size();
sectionNodes[index].pos = pos;
int *current = 0;
const SectionNode sn = sectionNodes.at(index);
@ -1227,7 +1228,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
isSet |= sn.type;
}
if (QStringRef(input, pos, input->size() - pos) != separators.last()) {
if (input->midRef(pos) != separators.last()) {
QDTPDEBUG << "invalid because" << input->midRef(pos)
<< "!=" << separators.last() << pos;
return StateNode();

View File

@ -252,8 +252,6 @@ struct QBidiAlgorithm {
void initScriptAnalysisAndIsolatePairs(Vector<IsolatePair> &isolatePairs)
{
isolatePairs.append({ -1, length }); // treat the whole string as one isolate
int isolateStack[128];
int isolateLevel = 0;
// load directions of string, and determine isolate pairs
@ -304,6 +302,14 @@ struct QBidiAlgorithm {
case QChar::DirS:
case QChar::DirB:
analysis[pos].bidiFlags = QScriptAnalysis::BidiResetToParagraphLevel;
if (uc == QChar::ParagraphSeparator) {
// close all open isolates as we start a new paragraph
while (isolateLevel > 0) {
--isolateLevel;
if (isolateLevel < 128)
isolatePairs[isolateStack[isolateLevel]].end = pos;
}
}
break;
default:
break;
@ -434,21 +440,21 @@ struct QBidiAlgorithm {
doEmbed(true, true, false);
break;
case QChar::DirLRI:
++isolatePairPosition;
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(false, false, true);
++isolatePairPosition;
break;
case QChar::DirRLI:
++isolatePairPosition;
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(true, false, true);
++isolatePairPosition;
break;
case QChar::DirFSI: {
++isolatePairPosition;
const auto &pair = isolatePairs.at(isolatePairPosition);
Q_ASSERT(pair.start == i);
bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
doEmbed(isRtl, false, true);
++isolatePairPosition;
break;
}
@ -492,16 +498,24 @@ struct QBidiAlgorithm {
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
break;
case QChar::DirB:
// paragraph separator, go down to base direction
appendRun(i - 1);
while (stack.counter > 1) {
// there might be remaining isolates on the stack that are missing a PDI. Those need to get
// a continuation indicating to take the eos from the end of the string (ie. the paragraph level)
const auto &t = stack.top();
if (t.isIsolate) {
runs[t.runBeforeIsolate].continuation = -2;
// paragraph separator, go down to base direction, reset all state
if (text[i].unicode() == QChar::ParagraphSeparator) {
appendRun(i - 1);
while (stack.counter > 1) {
// there might be remaining isolates on the stack that are missing a PDI. Those need to get
// a continuation indicating to take the eos from the end of the string (ie. the paragraph level)
const auto &t = stack.top();
if (t.isIsolate) {
runs[t.runBeforeIsolate].continuation = -2;
}
--stack.counter;
}
--stack.counter;
continuationFrom = -1;
lastRunWithContent = -1;
validIsolateCount = 0;
overflowIsolateCount = 0;
overflowEmbeddingCount = 0;
level = baseLevel;
}
break;
default:
@ -1094,6 +1108,22 @@ struct QBidiAlgorithm {
resolveImplicitLevels(runs);
}
BIDI_DEBUG() << "Rule L1:";
// Rule L1:
bool resetLevel = true;
for (int i = length - 1; i >= 0; --i) {
if (analysis[i].bidiFlags & QScriptAnalysis::BidiResetToParagraphLevel) {
BIDI_DEBUG() << "resetting pos" << i << "to baselevel";
analysis[i].bidiLevel = baseLevel;
resetLevel = true;
} else if (resetLevel && analysis[i].bidiFlags & QScriptAnalysis::BidiMaybeResetToParagraphLevel) {
BIDI_DEBUG() << "resetting pos" << i << "to baselevel (maybereset flag)";
analysis[i].bidiLevel = baseLevel;
} else {
resetLevel = false;
}
}
// set directions for BN to the minimum of adjacent chars
// This makes is possible to be conformant with the Bidi algorithm even though we don't
// remove BN and explicit embedding chars from the stream of characters to reorder
@ -1125,22 +1155,6 @@ struct QBidiAlgorithm {
}
}
BIDI_DEBUG() << "Rule L1:";
// Rule L1:
bool resetLevel = true;
for (int i = length - 1; i >= 0; --i) {
if (analysis[i].bidiFlags & QScriptAnalysis::BidiResetToParagraphLevel) {
BIDI_DEBUG() << "resetting pos" << i << "to baselevel";
analysis[i].bidiLevel = baseLevel;
resetLevel = true;
} else if (resetLevel && analysis[i].bidiFlags & QScriptAnalysis::BidiMaybeResetToParagraphLevel) {
BIDI_DEBUG() << "resetting pos" << i << "to baselevel (maybereset flag)";
analysis[i].bidiLevel = baseLevel;
} else {
resetLevel = false;
}
}
if (BidiDebugEnabled) {
BIDI_DEBUG() << "final resolved levels:";
for (int i = 0; i < length; ++i)
@ -2073,8 +2087,6 @@ void QTextEngine::itemize() const
analysis->flags = QScriptAnalysis::Object;
break;
case QChar::LineSeparator:
if (analysis->bidiLevel % 2)
--analysis->bidiLevel;
analysis->flags = QScriptAnalysis::LineOrParagraphSeparator;
if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
const int offset = uc - string;

View File

@ -696,18 +696,22 @@ void QTextTable::insertRows(int pos, int num)
int extended = 0;
int insert_before = 0;
if (pos > 0 && pos < d->nRows) {
int lastCell = -1;
for (int i = 0; i < d->nCols; ++i) {
int cell = d->grid[pos*d->nCols + i];
if (cell == d->grid[(pos-1)*d->nCols+i]) {
// cell spans the insertion place, extend it
QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
QTextCharFormat fmt = c->charFormat(it->format);
fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num);
p->setCharFormat(it.position(), 1, fmt);
if (cell != lastCell) {
QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
QTextCharFormat fmt = c->charFormat(it->format);
fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num);
p->setCharFormat(it.position(), 1, fmt);
}
extended++;
} else if (!insert_before) {
insert_before = cell;
}
lastCell = cell;
}
} else {
insert_before = (pos == 0 ? d->grid[0] : d->fragment_end);

View File

@ -330,7 +330,7 @@ void QCocoaScreen::deliverUpdateRequests()
auto windows = QGuiApplication::allWindows();
for (int i = 0; i < windows.size(); ++i) {
QWindow *window = windows.at(i);
QPlatformWindow *platformWindow = window->handle();
auto *platformWindow = static_cast<QCocoaWindow*>(window->handle());
if (!platformWindow)
continue;
@ -341,7 +341,7 @@ void QCocoaScreen::deliverUpdateRequests()
continue;
// Skip windows that are not doing update requests via display link
if (!(window->format().swapInterval() > 0))
if (!platformWindow->updatesWithDisplayLink())
continue;
platformWindow->deliverUpdateRequest();

View File

@ -129,6 +129,7 @@ public:
bool isForeignWindow() const override;
void requestUpdate() override;
bool updatesWithDisplayLink() const;
void deliverUpdateRequest() override;
void requestActivateWindow() override;

View File

@ -1102,6 +1102,9 @@ void QCocoaWindow::setEmbeddedInForeignView()
void QCocoaWindow::viewDidChangeFrame()
{
if (isContentView())
return; // Handled below
handleGeometryChange();
}
@ -1474,11 +1477,10 @@ void QCocoaWindow::recreateWindowIfNeeded()
void QCocoaWindow::requestUpdate()
{
const int swapInterval = format().swapInterval();
qCDebug(lcQpaDrawing) << "QCocoaWindow::requestUpdate" << window() << "swapInterval" << swapInterval;
qCDebug(lcQpaDrawing) << "QCocoaWindow::requestUpdate" << window()
<< "using" << (updatesWithDisplayLink() ? "display-link" : "timer");
if (swapInterval > 0) {
// Vsync is enabled, deliver via CVDisplayLink
if (updatesWithDisplayLink()) {
static_cast<QCocoaScreen *>(screen())->requestUpdate();
} else {
// Fall back to the un-throttled timer-based callback
@ -1486,6 +1488,12 @@ void QCocoaWindow::requestUpdate()
}
}
bool QCocoaWindow::updatesWithDisplayLink() const
{
// Update via CVDisplayLink if Vsync is enabled
return format().swapInterval() != 0;
}
void QCocoaWindow::deliverUpdateRequest()
{
// Don't send update requests for views that need display, as the update

View File

@ -85,6 +85,7 @@
@end
@interface QT_MANGLE_NAMESPACE(QNSView) (Mouse)
- (void)initMouse;
- (NSPoint)screenMousePoint:(NSEvent *)theEvent;
- (void)mouseMovedImpl:(NSEvent *)theEvent;
- (void)mouseEnteredImpl:(NSEvent *)theEvent;
@ -114,7 +115,6 @@
@implementation QT_MANGLE_NAMESPACE(QNSView) {
QPointer<QCocoaWindow> m_platformWindow;
NSTrackingArea *m_trackingArea;
Qt::MouseButtons m_buttons;
Qt::MouseButtons m_acceptedMouseDowns;
Qt::MouseButtons m_frameStrutButtons;
@ -150,7 +150,6 @@
m_currentlyInterpretedKeyEvent = nil;
m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(),
"_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
m_trackingArea = nil;
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
@ -159,6 +158,7 @@
self.previousWindow = nil;
[self initDrawing];
[self initMouse];
[self registerDragTypes];
[[NSNotificationCenter defaultCenter] addObserver:self
@ -173,10 +173,6 @@
{
qCDebug(lcQpaWindow) << "Deallocating" << self;
if (m_trackingArea) {
[self removeTrackingArea:m_trackingArea];
[m_trackingArea release];
}
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];

View File

@ -39,6 +39,22 @@
// This file is included from qnsview.mm, and only used to organize the code
/*
The reason for using this helper is to ensure that QNSView doesn't implement
the NSResponder callbacks for mouseEntered, mouseExited, and mouseMoved.
If it did, we would get mouse events though the responder chain as well,
for example if a subview has a tracking area of its own and calls super
in the handler, which results in forwarding the event though the responder
chain. The same applies if NSWindow.acceptsMouseMovedEvents is YES.
By having a helper as the target for our tracking areas, we know for sure
that the events we are getting stem from our own tracking areas.
FIXME: Ideally we wouldn't need this workaround, and would correctly
interact with the responder chain by e.g. calling super if Qt does not
accept the mouse event
*/
@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) {
QNSView *view;
}
@ -135,6 +151,28 @@
@implementation QT_MANGLE_NAMESPACE(QNSView) (Mouse)
- (void)initMouse
{
NSUInteger trackingOptions = NSTrackingActiveInActiveApp
| NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate;
// Ideally, NSTrackingMouseMoved should be turned on only if QWidget::mouseTracking
// is enabled, hover is on, or a tool tip is set. Unfortunately, Qt will send "tooltip"
// events on mouse moves, so we need to turn it on in ALL case. That means EVERY QWindow
// gets to pay the cost of mouse moves delivered to it (Apple recommends keeping it OFF
// because there is a performance hit).
trackingOptions |= NSTrackingMouseMoved;
// Using NSTrackingInVisibleRect means AppKit will automatically synchronize the
// tracking rect with changes in the view's visible area, so leave it undefined.
trackingOptions |= NSTrackingInVisibleRect;
static const NSRect trackingRect = NSZeroRect;
QMacAutoReleasePool pool;
[self addTrackingArea:[[[NSTrackingArea alloc] initWithRect:trackingRect
options:trackingOptions owner:m_mouseMoveHelper userInfo:nil] autorelease]];
}
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
@ -406,35 +444,9 @@
[super otherMouseUp:theEvent];
}
- (void)updateTrackingAreas
{
[super updateTrackingAreas];
QMacAutoReleasePool pool;
// NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early
if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea])
return;
// Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
// only be turned on if mouseTracking, hover is on or a tool tip is set.
// Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
// turn it on in ALL case. That means EVERY QWindow gets to pay the cost of
// mouse moves delivered to it (Apple recommends keeping it OFF because there
// is a performance hit). So it goes.
NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
[m_trackingArea release];
m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
owner:m_mouseMoveHelper
userInfo:nil];
[self addTrackingArea:m_trackingArea];
}
- (void)cursorUpdate:(NSEvent *)theEvent
{
qCDebug(lcQpaMouse) << "[QNSView cursorUpdate:]" << self.cursor;
qCDebug(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor;
// Note: We do not get this callback when moving from a subview that
// uses the legacy cursorRect API, so the cursor is reset to the arrow

View File

@ -393,8 +393,14 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
m_shareContext = share ? static_cast<QWindowsEGLContext *>(share)->m_eglContext : nullptr;
QVector<EGLint> contextAttrs;
contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
contextAttrs.append(m_format.majorVersion());
const int major = m_format.majorVersion();
const int minor = m_format.minorVersion();
if (major > 3 || (major == 3 && minor > 0))
qWarning("QWindowsEGLContext: ANGLE only partially supports OpenGL ES > 3.0");
contextAttrs.append(EGL_CONTEXT_MAJOR_VERSION);
contextAttrs.append(major);
contextAttrs.append(EGL_CONTEXT_MINOR_VERSION);
contextAttrs.append(minor);
contextAttrs.append(EGL_NONE);
QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);

View File

@ -45,8 +45,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFramebufferObject>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
QT_BEGIN_NAMESPACE
@ -83,7 +82,7 @@ bool QWinRTBackingStore::initialize()
return true;
d->context.reset(new QOpenGLContext);
QSurfaceFormat format = window()->requestedFormat();
QSurfaceFormat format = window()->format();
d->context->setFormat(format);
d->context->setScreen(window()->screen());
if (!d->context->create())
@ -138,7 +137,7 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
const int y2 = y1 + bounds.height();
const int x1 = bounds.x();
const int x2 = x1 + bounds.width();
glBlitFramebufferANGLE(x1, y1, x2, y2,
glBlitFramebuffer(x1, y1, x2, y2,
x1, d->size.height() - y1, x2, d->size.height() - y2,
GL_COLOR_BUFFER_BIT, GL_NEAREST);

View File

@ -134,11 +134,14 @@ void QWinRTEGLContext::initialize()
const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext)
? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0;
const int major = d->format.majorVersion();
const int minor = d->format.minorVersion();
if (major > 3 || (major == 3 && minor > 0))
qWarning("QWinRTEGLContext: ANGLE only partially supports OpenGL ES > 3.0");
const EGLint attributes[] = {
EGL_CONTEXT_CLIENT_VERSION, d->format.majorVersion(),
EGL_CONTEXT_MINOR_VERSION_KHR, d->format.minorVersion(),
EGL_CONTEXT_FLAGS_KHR, flags,
EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true,
EGL_NONE
};
d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, d->eglShareContext, attributes);

View File

@ -158,8 +158,6 @@ HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane)
return S_OK;
}
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2)
{
ComPtr<IInputPaneStatics> factory;
@ -221,6 +219,4 @@ void QWinRTInputContext::hideInputPanel()
});
}
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
QT_END_NAMESPACE

View File

@ -74,10 +74,8 @@ public:
bool isInputPanelVisible() const override;
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
void showInputPanel() override;
void hideInputPanel() override;
#endif
private slots:
void updateScreenCursorRect();

View File

@ -91,13 +91,10 @@ typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterRe
typedef ITypedEventHandler<CoreWindow*, InputEnabledEventArgs*> InputEnabledHandler;
typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler;
typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
typedef ITypedEventHandler<ICorePointerRedirector*, PointerEventArgs*> RedirectHandler;
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
typedef ITypedEventHandler<ApplicationView*, IInspectable*> VisibleBoundsChangedHandler;
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
QT_BEGIN_NAMESPACE
@ -479,10 +476,8 @@ typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRe
uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall ICorePointerRedirector::*RedirectorCallbackRemover)(EventRegistrationToken);
uint qHash(RedirectorCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
typedef HRESULT (__stdcall IApplicationView2::*ApplicationView2CallbackRemover)(EventRegistrationToken);
uint qHash(ApplicationView2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
class QWinRTScreenPrivate
{
@ -509,10 +504,8 @@ public:
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
QHash<RedirectorCallbackRemover, EventRegistrationToken> redirectTokens;
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
QHash<ApplicationView2CallbackRemover, EventRegistrationToken> view2Tokens;
ComPtr<IApplicationView2> view2;
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
QAtomicPointer<QWinRTWindow> mouseGrabWindow;
QAtomicPointer<QWinRTWindow> keyboardGrabWindow;
QWindow *currentPressWindow = nullptr;
@ -603,10 +596,8 @@ QWinRTScreen::QWinRTScreen()
d->cursor.reset(new QWinRTCursor);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
hr = d->view.As(&d->view2);
Q_ASSERT_SUCCEEDED(hr);
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
}
QWinRTScreen::~QWinRTScreen()
@ -630,12 +621,10 @@ QWinRTScreen::~QWinRTScreen()
hr = (d->redirect.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
for (QHash<ApplicationView2CallbackRemover, EventRegistrationToken>::const_iterator i = d->view2Tokens.begin(); i != d->view2Tokens.end(); ++i) {
hr = (d->view2.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
return hr;
});
RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks");
@ -777,14 +766,8 @@ void QWinRTScreen::initialize()
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
Q_ASSERT_SUCCEEDED(hr);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
hr = d->view2->add_VisibleBoundsChanged(Callback<VisibleBoundsChangedHandler>(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->view2Tokens[&IApplicationView2::remove_VisibleBoundsChanged]);
Q_ASSERT_SUCCEEDED(hr);
#else
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
Q_ASSERT_SUCCEEDED(hr)
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
@ -820,7 +803,6 @@ void QWinRTScreen::setKeyboardRect(const QRectF &keyboardRect)
return;
}
d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
Rect visibleRect;
hr = d->view2->get_VisibleBounds(&visibleRect);
if (FAILED(hr)) {
@ -828,9 +810,6 @@ void QWinRTScreen::setKeyboardRect(const QRectF &keyboardRect)
return;
}
visibleRectF = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height);
#else
visibleRectF = d->logicalRect;
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
// if keyboard is snapped to the bottom of the screen and would cover the cursor the content is
// moved up to make it visible
if (keyboardRect.intersects(mCursorRect)
@ -1528,11 +1507,7 @@ HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEvent
return onPointerUpdated(nullptr, args);
}
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *)
#else
HRESULT QWinRTScreen::onWindowSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *)
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
{
Q_D(QWinRTScreen);
@ -1543,14 +1518,10 @@ HRESULT QWinRTScreen::onWindowSizeChanged(ICoreWindow *, IWindowSizeChangedEvent
RETURN_OK_IF_FAILED("Failed to get window bounds");
d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
Rect visibleRect;
hr = d->view2->get_VisibleBounds(&visibleRect);
RETURN_OK_IF_FAILED("Failed to get window visible bounds");
d->visibleRect = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height);
#else
d->visibleRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height);
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalRect;
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());

View File

@ -59,7 +59,6 @@ namespace ABI {
struct IPointerEventArgs;
struct IVisibilityChangedEventArgs;
struct IWindowActivatedEventArgs;
struct IWindowSizeChangedEventArgs;
}
namespace Xaml {
struct IDependencyObject;
@ -154,11 +153,7 @@ private:
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
HRESULT onWindowSizeChanged(ABI::Windows::UI::ViewManagement::IApplicationView *, IInspectable *);
#else
HRESULT onWindowSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
#endif
HRESULT onRedirectReleased(ABI::Windows::UI::Core::ICorePointerRedirector *, ABI::Windows::UI::Core::IPointerEventArgs *);
QScopedPointer<QWinRTScreenPrivate> d_ptr;

View File

@ -112,6 +112,8 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
d->screen = static_cast<QWinRTScreen *>(screen());
handleContentOrientationChange(window->contentOrientation());
d->surfaceFormat.setMajorVersion(3);
d->surfaceFormat.setMinorVersion(0);
d->surfaceFormat.setAlphaBufferSize(0);
d->surfaceFormat.setRedBufferSize(8);
d->surfaceFormat.setGreenBufferSize(8);

View File

@ -2396,6 +2396,19 @@ void tst_QDateTime::fromStringStringFormat_data()
QTest::newRow("late") << QString("9999-12-31T23:59:59.999Z")
<< QString("yyyy-MM-ddThh:mm:ss.zZ")
<< QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
// Separators match /([^aAdhHMmstyz]*)/
QTest::newRow("oddly-separated") // To show broken-separator's format is valid.
<< QStringLiteral("2018 wilful long working block relief 12-19T21:09 cruel blurb encore flux")
<< QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux")
<< QDateTime(QDate(2018, 12, 19), QTime(21, 9));
QTest::newRow("broken-separator")
<< QStringLiteral("2018 wilful")
<< QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux")
<< invalidDateTime();
QTest::newRow("broken-terminator")
<< QStringLiteral("2018 wilful long working block relief 12-19T21:09 cruel")
<< QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux")
<< invalidDateTime();
}
void tst_QDateTime::fromStringStringFormat()

View File

@ -431,6 +431,12 @@ void tst_QTextTable::insertRows()
table->insertRows(5, 2);
QCOMPARE(table->rows(), 7);
table = cursor.insertTable(5,5);
table->mergeCells(0,0,3,3);
table->insertRows(2,1);
QCOMPARE(table->rows(), 6);
}
void tst_QTextTable::deleteInTable()

View File

@ -78,7 +78,7 @@ const LV logical_visual[] = {
{ "data42", "foo\nfoo", "foo\nfoo", QChar::DirL },
{ "data43", "\327\251\327\234\327\225\327\235\n\327\251\327\234\327\225\327\235", "\327\235\327\225\327\234\327\251\n\327\235\327\225\327\234\327\251", QChar::DirR },
{ "data44", "foo\n\327\251\327\234\327\225\327\235", "foo\n\327\235\327\225\327\234\327\251", QChar::DirL },
{ "data45", "\327\251\327\234\327\225\327\235\nfoo", "\327\235\327\225\327\234\327\251\nfoo", QChar::DirR },
{ "data45", "\327\251\327\234\327\225\327\235\nfoo", "foo\n\327\235\327\225\327\234\327\251", QChar::DirR },
{ "data46", "\330\250 1.23 \330\250", "\330\250 1.23 \330\250", QChar::DirR },
{ "data47", "\331\204\330\250 1.23 \331\202\330\250", "\330\250\331\202 1.23 \330\250\331\204", QChar::DirR },
{ "data48", "\330\250 1.2 \330\250", "\330\250 1.2 \330\250", QChar::DirR },

View File

@ -66,8 +66,19 @@ void tst_QComplexText::bidiReorderString_data()
<< QString::fromUtf8( data->logical )
<< QString::fromUtf8( data->visual )
<< (int) data->basicDir;
QTest::newRow( QByteArray(data->name) + " (doubled)" )
<< (QString::fromUtf8( data->logical ) + QChar(QChar::ParagraphSeparator) + QString::fromUtf8( data->logical ))
<< (QString::fromUtf8( data->visual ) + QChar(QChar::ParagraphSeparator) + QString::fromUtf8( data->visual ))
<< (int) data->basicDir;
data++;
}
QString isolateAndBoundary = QString(QChar(0x2068 /* DirFSI */)) + QChar(0x1c /* DirB */) + QChar(0x2069 /* DirPDI */);
QTest::newRow( "isolateAndBoundary" )
<< QString::fromUtf8( data->logical )
<< QString::fromUtf8( data->visual )
<< (int) QChar::DirL;
}
void tst_QComplexText::bidiReorderString()
@ -426,7 +437,7 @@ ushort unicodeForDirection(const QByteArray &direction)
{ "ET", 0x24 },
{ "AN", 0x660 },
{ "CS", 0x2c },
{ "B", QChar::ParagraphSeparator },
{ "B", '\n' },
{ "S", 0x9 },
{ "WS", 0x20 },
{ "ON", 0x2a },