fix-build-error

This commit is contained in:
韩品龙 2023-05-05 17:25:02 +08:00
parent 3c0ac47400
commit 86ca2acfe9
20 changed files with 268 additions and 246 deletions

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
qtbase-opensource-src (5.15.8+dfsg-ok1.1test2) yangtze; urgency=medium
qtbase-opensource-src (5.15.8+dfsg-ok1.1test3) yangtze; urgency=medium
* rebuild

View File

@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
finish();
}
void ThreadEngineBase::startBlocking()
{
start();
barrier.acquire();
startThreads();
bool throttled = false;
#ifndef QT_NO_EXCEPTIONS
try {
#endif
while (threadFunction() == ThrottleThread) {
if (threadThrottleExit()) {
throttled = true;
break;
}
}
#ifndef QT_NO_EXCEPTIONS
} catch (QException &e) {
handleException(e);
} catch (...) {
handleException(QUnhandledException());
}
#endif
if (throttled == false) {
barrier.release();
}
barrier.wait();
finish();
exceptionStore.throwPossibleException();
}
void ThreadEngineBase::startThread()
{
startThreadInternal();

View File

@ -91,6 +91,7 @@ public:
ThreadEngineBase();
virtual ~ThreadEngineBase();
void startSingleThreaded();
void startBlocking();
void startThread();
bool isCanceled();
void waitForResume();
@ -143,6 +144,15 @@ public:
return result();
}
// Runs the user algorithm using multiple threads.
// This function blocks until the algorithm is finished,
// and then returns the result.
T *startBlocking()
{
ThreadEngineBase::startBlocking();
return result();
}
// Runs the user algorithm using multiple threads.
// Does not block, returns a future.
QFuture<T> startAsynchronously()
@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
public:
ThreadEngineStarter(TypedThreadEngine *eng)
: Base(eng) { }
T startBlocking()
{
T t = *this->threadEngine->startBlocking();
delete this->threadEngine;
return t;
}
};
// Full template specialization where T is void.
@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
public:
ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
: ThreadEngineStarterBase<void>(_threadEngine) {}
void startBlocking()
{
this->threadEngine->startBlocking();
delete this->threadEngine;
}
};
//! [qtconcurrentthreadengine-1]

View File

@ -515,9 +515,9 @@ QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq)
*/
QImageReaderPrivate::~QImageReaderPrivate()
{
delete handler;
if (deleteDevice)
delete device;
delete handler;
}
/*!
@ -774,12 +774,12 @@ bool QImageReader::decideFormatFromContent() const
*/
void QImageReader::setDevice(QIODevice *device)
{
delete d->handler;
d->handler = nullptr;
if (d->device && d->deleteDevice)
delete d->device;
d->device = device;
d->deleteDevice = false;
delete d->handler;
d->handler = nullptr;
d->text.clear();
}

View File

@ -349,9 +349,9 @@ QImageWriter::QImageWriter(const QString &fileName, const QByteArray &format)
*/
QImageWriter::~QImageWriter()
{
delete d->handler;
if (d->deleteDevice)
delete d->device;
delete d->handler;
delete d;
}
@ -396,13 +396,13 @@ QByteArray QImageWriter::format() const
*/
void QImageWriter::setDevice(QIODevice *device)
{
delete d->handler;
d->handler = nullptr;
if (d->device && d->deleteDevice)
delete d->device;
d->device = device;
d->deleteDevice = false;
delete d->handler;
d->handler = nullptr;
}
/*!

View File

@ -1412,16 +1412,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
if (sessionType == QByteArrayLiteral("x11") && !platformName.contains(QByteArrayLiteral("xcb"))) {
platformName = QByteArrayLiteral("xcb");
} else if (sessionType == QByteArrayLiteral("wayland") && !platformName.contains(QByteArrayLiteral("wayland"))) {
QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower();
QByteArray sessionDesktop = qgetenv("XDG_SESSION_DESKTOP").toLower();
if (currentDesktop.contains("gnome") || sessionDesktop.contains("gnome")) {
qInfo() << "Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome."
<< "Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.";
} else {
platformName = QByteArrayLiteral("wayland");
}
}
}
#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
// Add it as fallback in case XDG_SESSION_TYPE is something wrong
if (!platformName.contains(QT_QPA_DEFAULT_PLATFORM_NAME))
@ -3064,8 +3057,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QEvent::Type mouseEventType = QEvent::MouseMove;
Qt::MouseButton button = Qt::NoButton;
Qt::MouseButtons buttons = Qt::LeftButton;
if ((eventType == QEvent::TouchBegin && m_fakeMouseSourcePointId < 0)
|| (touchPoints.count() == 1 && m_fakeMouseSourcePointId != touchPoints.first().id()))
if (eventType == QEvent::TouchBegin && m_fakeMouseSourcePointId < 0)
m_fakeMouseSourcePointId = touchPoints.first().id();
for (const auto &touchPoint : touchPoints) {
if (touchPoint.id() == m_fakeMouseSourcePointId) {

View File

@ -455,7 +455,7 @@ init_context:
}
// Enable bug workarounds.
long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
q_SSL_CTX_set_options(sslContext->ctx, options);
// Tell OpenSSL to release memory early

View File

@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
// Defined in qsslsocket.cpp
void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
{
long options;
qssloptions options;
if (protocol == QSsl::TlsV1SslV3)
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
else if (protocol == QSsl::SecureProtocols)

View File

@ -107,6 +107,12 @@
QT_BEGIN_NAMESPACE
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
typedef uint64_t qssloptions;
#else
typedef unsigned long qssloptions;
#endif
struct QSslErrorEntry {
int code;
int depth;
@ -171,7 +177,7 @@ public:
QVector<QSslError> ocspErrors;
QByteArray ocspResponseDer;
Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);

View File

@ -157,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
#ifdef TLS1_3_VERSION

View File

@ -245,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
int q_SSL_session_reused(SSL *a);
unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);

View File

@ -471,7 +471,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
} else if (event->modifiers() & Qt::KeypadModifier) {
if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
} else if (isLatin(qtKey) && event->text().isUpper()) {
} else if (isLatin1(qtKey) && event->text().isUpper()) {
keysyms.append(qtKey);
}
@ -523,7 +523,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
// With standard shortcuts we should prefer a latin character, this is
// for checks like "some qkeyevent == QKeySequence::Copy" to work even
// when using for example 'russian' keyboard layout.
if (!QXkbCommon::isLatin(keysym)) {
if (!QXkbCommon::isLatin1(keysym)) {
xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
if (latinKeysym != XKB_KEY_NoSymbol)
keysym = latinKeysym;
@ -546,7 +546,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
} else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
// numeric keypad keys
qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
} else if (QXkbCommon::isLatin(keysym)) {
} else if (QXkbCommon::isLatin1(keysym)) {
qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
} else {
// check if we have a direct mapping
@ -678,7 +678,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
Qt::KeyboardModifiers neededMods = ModsTbl[i];
if ((modifiers & neededMods) == neededMods) {
if (i == 8) {
if (isLatin(baseQtKey))
if (isLatin1(baseQtKey))
continue;
// add a latin key as a fall back key
sym = lookupLatinKeysym(state, keycode);
@ -733,7 +733,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
if (keysyms && isLatin(keysyms[0]))
if (keysyms && isLatin1(keysyms[0]))
nrLatinKeys++;
if (nrLatinKeys > 10) // arbitrarily chosen threshold
return;
@ -766,7 +766,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
continue;
if (isLatin(syms[0])) {
if (isLatin1(syms[0])) {
sym = syms[0];
break;
}

View File

@ -94,8 +94,8 @@ public:
static void verifyHasLatinLayout(xkb_keymap *keymap);
static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
static bool isLatin(xkb_keysym_t sym) {
return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
static bool isLatin1(xkb_keysym_t sym) {
return sym <= 0xff;
}
static bool isKeypad(xkb_keysym_t sym) {
return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;

View File

@ -593,10 +593,6 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event);
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event))
xi2ProcessTouch(xiDeviceEvent, platformWindow);
else { // When the window cannot be matched, delete it from touchPoints
if (TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid))
dev->touchPoints.remove((xiDeviceEvent->detail % INT_MAX));
}
break;
}
} else if (xiEnterEvent && !xi2MouseEventsDisabled() && eventListener) {

View File

@ -93,6 +93,8 @@ enum {
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE);
#undef FocusIn
@ -297,11 +299,6 @@ void QXcbWindow::create()
return;
}
QPlatformWindow::setGeometry(rect);
if (platformScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
const QSize minimumSize = windowMinimumSize();
if (rect.width() > 0 || rect.height() > 0) {
rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
@ -313,6 +310,11 @@ void QXcbWindow::create()
rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
}
QPlatformWindow::setGeometry(rect);
if (platformScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
xcb_window_t xcb_parent_id = platformScreen->root();
if (parent()) {
xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
@ -555,6 +557,7 @@ void QXcbWindow::destroy()
}
m_mapped = false;
m_recreationReasons = RecreationNotNeeded;
if (m_pendingSyncRequest)
m_pendingSyncRequest->invalidate();
@ -564,11 +567,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
{
QPlatformWindow::setGeometry(rect);
if (shouldDeferTask(Task::SetGeometry)) {
m_deferredGeometry = rect;
return;
}
propagateSizeHints();
QXcbScreen *currentScreen = xcbScreen();
@ -693,10 +691,12 @@ void QXcbWindow::setVisible(bool visible)
void QXcbWindow::show()
{
if (shouldDeferTask(Task::Map))
return;
if (window()->isTopLevel()) {
if (m_recreationReasons != RecreationNotNeeded) {
qCDebug(lcQpaWindow) << "QXcbWindow: need to recreate window" << window() << m_recreationReasons;
create();
m_recreationReasons = RecreationNotNeeded;
}
// update WM_NORMAL_HINTS
propagateSizeHints();
@ -746,10 +746,6 @@ void QXcbWindow::show()
void QXcbWindow::hide()
{
if (shouldDeferTask(Task::Unmap))
return;
m_wmStateValid = false;
xcb_unmap_window(xcb_connection(), m_window);
// send synthetic UnmapNotify event according to icccm 4.1.4
@ -909,9 +905,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
{
if (shouldDeferTask(Task::SetWindowFlags))
return;
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
if (type == Qt::ToolTip)
@ -919,6 +912,12 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
if (type == Qt::Popup)
flags |= Qt::X11BypassWindowManagerHint;
Qt::WindowFlags oldflags = window()->flags();
if ((oldflags & Qt::WindowStaysOnTopHint) != (flags & Qt::WindowStaysOnTopHint))
m_recreationReasons |= WindowStaysOnTopHintChanged;
if ((oldflags & Qt::WindowStaysOnBottomHint) != (flags & Qt::WindowStaysOnBottomHint))
m_recreationReasons |= WindowStaysOnBottomHintChanged;
const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
const quint32 values[] = {
// XCB_CW_OVERRIDE_REDIRECT
@ -941,8 +940,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
}
void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
@ -1142,9 +1139,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
if (state == m_windowState)
return;
if (shouldDeferTask(Task::SetWindowState))
return;
// unset old state
if (m_windowState & Qt::WindowMinimized)
xcb_map_window(xcb_connection(), m_window);
@ -1894,10 +1888,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
if (event->window == m_window) {
m_mapped = false;
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
if (!m_isWmManagedWindow || parent()) {
m_wmStateValid = true;
handleDeferredTasks();
}
}
}
@ -2212,98 +2202,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
}
bool QXcbWindow::shouldDeferTask(Task task)
{
if (m_wmStateValid)
return false;
m_deferredTasks.append(task);
return true;
}
void QXcbWindow::handleDeferredTasks()
{
Q_ASSERT(m_wmStateValid == true);
if (m_deferredTasks.isEmpty())
return;
bool map = false;
bool unmap = false;
QVector<Task> tasks;
for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
if (!tasks.contains(*taskIt))
tasks.prepend(*taskIt);
}
for (Task task : tasks) {
switch (task) {
case Task::Map:
map = true;
unmap = false;
break;
case Task::Unmap:
unmap = true;
map = false;
break;
case Task::SetGeometry:
setGeometry(m_deferredGeometry);
break;
case Task::SetWindowFlags:
setWindowFlags(window()->flags());
break;
case Task::SetWindowState:
setWindowState(window()->windowState());
break;
}
}
m_deferredTasks.clear();
if (map) {
Q_ASSERT(unmap == false);
show();
}
if (unmap) {
Q_ASSERT(map == false);
hide();
}
}
void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
{
connection()->setTime(event->time);
const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
if (netWmStateChanged || wmStateChanged) {
if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
// ICCCM 4.1.4
// Clients that want to re-use a client window (e.g. by mapping it again)
// after withdrawing it must wait for the withdrawal to be complete before
// proceeding. The preferred method for doing this is for clients to wait for
// a window manager to update or remove the WM_STATE property.
m_wmStateValid = true;
handleDeferredTasks();
}
if (event->state == XCB_PROPERTY_DELETE)
const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
if (propertyDeleted)
return;
if (wmStateChanged) {
Qt::WindowStates newState = Qt::WindowNoState;
if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
0, m_window, atom(QXcbAtom::WM_STATE),
XCB_ATOM_ANY, 0, 1024);
if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
if (reply->length != 0) {
const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
}
const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
if (reply->length != 0)
m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
|| (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
}
}
// _NET_WM_STATE handling
Qt::WindowStates newState = Qt::WindowNoState;
const NetWmStates states = netWmStates();
// _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
// not be visible on the screen if its desktop/viewport were active and its coordinates were
@ -2325,6 +2247,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
connection()->setMouseGrabber(nullptr);
}
return;
} else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
m_dirtyFrameMargins = true;
}

View File

@ -74,13 +74,12 @@ public:
Q_DECLARE_FLAGS(NetWmStates, NetWmState)
enum Task {
Map,
Unmap,
SetGeometry,
SetWindowFlags,
SetWindowState
enum RecreationReason {
RecreationNotNeeded = 0,
WindowStaysOnTopHintChanged = 0x1,
WindowStaysOnBottomHintChanged = 0x2
};
Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
QXcbWindow(QWindow *window);
~QXcbWindow();
@ -151,9 +150,6 @@ public:
QXcbWindow *toWindow() override;
bool shouldDeferTask(Task task);
void handleDeferredTasks();
void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
@ -293,10 +289,7 @@ protected:
qreal m_sizeHintsScaleFactor = 1.0;
bool m_wmStateValid = true;
QVector<Task> m_deferredTasks;
bool m_isWmManagedWindow = true;
QRect m_deferredGeometry;
RecreationReasons m_recreationReasons = RecreationNotNeeded;
};
class QXcbForeignWindow : public QXcbWindow

View File

@ -92,23 +92,39 @@ inline static QString fromSQLTCHAR(const QVarLengthArray<SQLTCHAR>& input, int s
return result;
}
template <size_t SizeOfChar = sizeof(SQLTCHAR)>
void toSQLTCHARImpl(QVarLengthArray<SQLTCHAR> &result, const QString &input); // primary template undefined
template <typename Container>
void do_append(QVarLengthArray<SQLTCHAR> &result, const Container &c)
{
result.append(reinterpret_cast<const SQLTCHAR *>(c.data()), c.size());
}
template <>
void toSQLTCHARImpl<1>(QVarLengthArray<SQLTCHAR> &result, const QString &input)
{
const auto u8 = input.toUtf8();
do_append(result, u8);
}
template <>
void toSQLTCHARImpl<2>(QVarLengthArray<SQLTCHAR> &result, const QString &input)
{
do_append(result, input);
}
template <>
void toSQLTCHARImpl<4>(QVarLengthArray<SQLTCHAR> &result, const QString &input)
{
const auto u32 = input.toUcs4();
do_append(result, u32);
}
inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input)
{
QVarLengthArray<SQLTCHAR> result;
result.resize(input.size());
switch(sizeof(SQLTCHAR)) {
case 1:
memcpy(result.data(), input.toUtf8().data(), input.size());
break;
case 2:
memcpy(result.data(), input.unicode(), input.size() * 2);
break;
case 4:
memcpy(result.data(), input.toUcs4().data(), input.size() * 4);
break;
default:
qCritical("sizeof(SQLTCHAR) is %d. Don't know how to handle this.", int(sizeof(SQLTCHAR)));
}
toSQLTCHARImpl(result, input);
result.append(0); // make sure it's null terminated, doesn't matter if it already is, it does if it isn't.
return result;
}
@ -763,6 +779,14 @@ QChar QODBCDriverPrivate::quoteChar()
return quote;
}
static SQLRETURN qt_string_SQLSetConnectAttr(SQLHDBC handle, SQLINTEGER attr, const QString &val)
{
auto encoded = toSQLTCHAR(val);
return SQLSetConnectAttr(handle, attr,
encoded.data(),
SQLINTEGER(encoded.size() * sizeof(SQLTCHAR))); // size in bytes
}
bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
{
@ -798,10 +822,7 @@ bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
v = val.toUInt();
r = SQLSetConnectAttr(hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) size_t(v), 0);
} else if (opt.toUpper() == QLatin1String("SQL_ATTR_CURRENT_CATALOG")) {
val.utf16(); // 0 terminate
r = SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG,
toSQLTCHAR(val).data(),
val.length()*sizeof(SQLTCHAR));
r = qt_string_SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG, val);
} else if (opt.toUpper() == QLatin1String("SQL_ATTR_METADATA_ID")) {
if (val.toUpper() == QLatin1String("SQL_TRUE")) {
v = SQL_TRUE;
@ -816,10 +837,7 @@ bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
v = val.toUInt();
r = SQLSetConnectAttr(hDbc, SQL_ATTR_PACKET_SIZE, (SQLPOINTER) size_t(v), 0);
} else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACEFILE")) {
val.utf16(); // 0 terminate
r = SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE,
toSQLTCHAR(val).data(),
val.length()*sizeof(SQLTCHAR));
r = qt_string_SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE, val);
} else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACE")) {
if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_OFF")) {
v = SQL_OPT_TRACE_OFF;
@ -1022,9 +1040,12 @@ bool QODBCResult::reset (const QString& query)
return false;
}
{
auto encoded = toSQLTCHAR(query);
r = SQLExecDirect(d->hStmt,
toSQLTCHAR(query).data(),
(SQLINTEGER) query.length());
encoded.data(),
SQLINTEGER(encoded.size()));
}
if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r!= SQL_NO_DATA) {
setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
"Unable to execute statement"), QSqlError::StatementError, d));
@ -1371,9 +1392,12 @@ bool QODBCResult::prepare(const QString& query)
return false;
}
{
auto encoded = toSQLTCHAR(query);
r = SQLPrepare(d->hStmt,
toSQLTCHAR(query).data(),
(SQLINTEGER) query.length());
encoded.data(),
SQLINTEGER(encoded.size()));
}
if (r != SQL_SUCCESS) {
setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
@ -1401,7 +1425,7 @@ bool QODBCResult::exec()
SQLCloseCursor(d->hStmt);
QVector<QVariant>& values = boundValues();
QVector<QByteArray> tmpStorage(values.count(), QByteArray()); // holds temporary buffers
QVector<QByteArray> tmpStorage(values.count(), QByteArray()); // targets for SQLBindParameter()
QVarLengthArray<SQLLEN, 32> indicators(values.count());
memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
@ -1580,35 +1604,36 @@ bool QODBCResult::exec()
case QVariant::String:
if (d->unicode) {
QByteArray &ba = tmpStorage[i];
QString str = val.toString();
{
const auto encoded = toSQLTCHAR(val.toString());
ba = QByteArray(reinterpret_cast<const char *>(encoded.data()),
encoded.size() * sizeof(SQLTCHAR));
}
if (*ind != SQL_NULL_DATA)
*ind = str.length() * sizeof(SQLTCHAR);
int strSize = str.length() * sizeof(SQLTCHAR);
*ind = ba.size();
if (bindValueType(i) & QSql::Out) {
const QVarLengthArray<SQLTCHAR> a(toSQLTCHAR(str));
ba = QByteArray((const char *)a.constData(), a.size() * sizeof(SQLTCHAR));
r = SQLBindParameter(d->hStmt,
i + 1,
qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TCHAR,
strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
ba.size() > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
0, // god knows... don't change this!
0,
ba.data(),
const_cast<char *>(ba.constData()), // don't detach
ba.size(),
ind);
break;
}
ba = QByteArray ((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
r = SQLBindParameter(d->hStmt,
i + 1,
qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TCHAR,
strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
strSize,
ba.size() > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
ba.size(),
0,
const_cast<char *>(ba.constData()),
const_cast<char *>(ba.constData()), // don't detach
ba.size(),
ind);
break;
@ -1716,10 +1741,11 @@ bool QODBCResult::exec()
case QVariant::String:
if (d->unicode) {
if (bindValueType(i) & QSql::Out) {
const QByteArray &first = tmpStorage.at(i);
QVarLengthArray<SQLTCHAR> array;
array.append((const SQLTCHAR *)first.constData(), first.size());
values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR));
const QByteArray &bytes = tmpStorage.at(i);
const auto strSize = bytes.size() / int(sizeof(SQLTCHAR));
QVarLengthArray<SQLTCHAR> string(strSize);
memcpy(string.data(), bytes.data(), strSize * sizeof(SQLTCHAR));
values[i] = fromSQLTCHAR(string);
}
break;
}
@ -1966,14 +1992,16 @@ bool QODBCDriver::open(const QString & db,
SQLSMALLINT cb;
QVarLengthArray<SQLTCHAR> connOut(1024);
memset(connOut.data(), 0, connOut.size() * sizeof(SQLTCHAR));
{
auto encoded = toSQLTCHAR(connQStr);
r = SQLDriverConnect(d->hDbc,
NULL,
toSQLTCHAR(connQStr).data(),
(SQLSMALLINT)connQStr.length(),
nullptr,
encoded.data(), SQLSMALLINT(encoded.size()),
connOut.data(),
1024,
&cb,
/*SQL_DRIVER_NOPROMPT*/0);
}
if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d));
@ -2352,17 +2380,15 @@ QStringList QODBCDriver::tables(QSql::TableType type) const
if (tableType.isEmpty())
return tl;
QString joinedTableTypeString = tableType.join(QLatin1Char(','));
{
auto joinedTableTypeString = toSQLTCHAR(tableType.join(u','));
r = SQLTables(hStmt,
NULL,
0,
NULL,
0,
NULL,
0,
toSQLTCHAR(joinedTableTypeString).data(),
joinedTableTypeString.length() /* characters, not bytes */);
nullptr, 0,
nullptr, 0,
nullptr, 0,
joinedTableTypeString.data(), joinedTableTypeString.size());
}
if (r != SQL_SUCCESS)
qSqlWarning(QLatin1String("QODBCDriver::tables Unable to execute table list"), d);
@ -2436,26 +2462,28 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
SQL_IS_UINTEGER);
{
auto c = toSQLTCHAR(catalog);
auto s = toSQLTCHAR(schema);
auto t = toSQLTCHAR(table);
r = SQLPrimaryKeys(hStmt,
catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(),
catalog.length(),
schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
schema.length(),
toSQLTCHAR(table).data(),
table.length() /* in characters, not in bytes */);
catalog.isEmpty() ? nullptr : c.data(), c.size(),
schema.isEmpty() ? nullptr : s.data(), s.size(),
t.data(), t.size());
}
// if the SQLPrimaryKeys() call does not succeed (e.g the driver
// does not support it) - try an alternative method to get hold of
// the primary index (e.g MS Access and FoxPro)
if (r != SQL_SUCCESS) {
auto c = toSQLTCHAR(catalog);
auto s = toSQLTCHAR(schema);
auto t = toSQLTCHAR(table);
r = SQLSpecialColumns(hStmt,
SQL_BEST_ROWID,
catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(),
catalog.length(),
schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
schema.length(),
toSQLTCHAR(table).data(),
table.length(),
catalog.isEmpty() ? nullptr : c.data(), c.size(),
schema.isEmpty() ? nullptr : s.data(), s.size(),
t.data(), t.size(),
SQL_SCOPE_CURROW,
SQL_NULLABLE);
@ -2538,15 +2566,17 @@ QSqlRecord QODBCDriver::record(const QString& tablename) const
SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
SQL_IS_UINTEGER);
{
auto c = toSQLTCHAR(catalog);
auto s = toSQLTCHAR(schema);
auto t = toSQLTCHAR(table);
r = SQLColumns(hStmt,
catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(),
catalog.length(),
schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
schema.length(),
toSQLTCHAR(table).data(),
table.length(),
NULL,
catalog.isEmpty() ? nullptr : c.data(), c.size(),
schema.isEmpty() ? nullptr : s.data(), s.size(),
t.data(), t.size(),
nullptr,
0);
}
if (r != SQL_SUCCESS)
qSqlWarning(QLatin1String("QODBCDriver::record: Unable to execute column list"), d);

View File

@ -624,6 +624,29 @@ void QMenuPrivate::hideMenu(QMenu *menu)
menu->d_func()->causedPopup.widget = nullptr;
}
QWindow *QMenuPrivate::transientParentWindow() const
{
Q_Q(const QMenu);
if (const QWidget *parent = q->nativeParentWidget()) {
if (parent->windowHandle())
return parent->windowHandle();
}
if (const QWindow *w = q->windowHandle()) {
if (w->transientParent())
return w->transientParent();
}
if (causedPopup.widget) {
if (const QWidget *w = causedPopup.widget.data()) {
if (const QWidget *ww = w->window())
return ww->windowHandle();
}
}
return nullptr;
}
void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
{
Q_Q(QMenu);
@ -3060,6 +3083,8 @@ QMenu::event(QEvent *e)
d->sloppyState.reset();
if (d->currentAction)
d->popupAction(d->currentAction, 0, false);
if (isWindow() && window() && window()->windowHandle() && !window()->windowHandle()->transientParent())
window()->windowHandle()->setTransientParent(d->transientParentWindow());
break;
#ifndef QT_NO_TOOLTIP
case QEvent::ToolTip:

View File

@ -440,6 +440,7 @@ public:
QMenuCaused causedPopup;
void hideUpToMenuBar();
void hideMenu(QMenu *menu);
QWindow *transientParentWindow() const;
//index mappings
inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }

View File

@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
testProcess.setEnvironment(environment);
#endif
testProcess.start("desktopsettingsaware_helper");
testProcess.start("./desktopsettingsaware_helper");
QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(10000));
@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
#if QT_CONFIG(process)
QProcess testProcess;
QStringList arguments;
testProcess.start("modal_helper", arguments);
testProcess.start("./modal_helper", arguments);
QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(20000));