commit
1ffba57fcd
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -1412,14 +1412,7 @@ 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");
|
||||
}
|
||||
platformName = QByteArrayLiteral("wayland");
|
||||
}
|
||||
}
|
||||
#ifdef 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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
r = SQLExecDirect(d->hStmt,
|
||||
toSQLTCHAR(query).data(),
|
||||
(SQLINTEGER) query.length());
|
||||
{
|
||||
auto encoded = toSQLTCHAR(query);
|
||||
r = SQLExecDirect(d->hStmt,
|
||||
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;
|
||||
}
|
||||
|
||||
r = SQLPrepare(d->hStmt,
|
||||
toSQLTCHAR(query).data(),
|
||||
(SQLINTEGER) query.length());
|
||||
{
|
||||
auto encoded = toSQLTCHAR(query);
|
||||
r = SQLPrepare(d->hStmt,
|
||||
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));
|
||||
r = SQLDriverConnect(d->hDbc,
|
||||
NULL,
|
||||
toSQLTCHAR(connQStr).data(),
|
||||
(SQLSMALLINT)connQStr.length(),
|
||||
connOut.data(),
|
||||
1024,
|
||||
&cb,
|
||||
/*SQL_DRIVER_NOPROMPT*/0);
|
||||
{
|
||||
auto encoded = toSQLTCHAR(connQStr);
|
||||
r = SQLDriverConnect(d->hDbc,
|
||||
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 */);
|
||||
r = SQLTables(hStmt,
|
||||
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,28 +2462,30 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
|
|||
SQL_ATTR_CURSOR_TYPE,
|
||||
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
|
||||
SQL_IS_UINTEGER);
|
||||
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 */);
|
||||
{
|
||||
auto c = toSQLTCHAR(catalog);
|
||||
auto s = toSQLTCHAR(schema);
|
||||
auto t = toSQLTCHAR(table);
|
||||
r = SQLPrimaryKeys(hStmt,
|
||||
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) {
|
||||
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(),
|
||||
SQL_SCOPE_CURROW,
|
||||
SQL_NULLABLE);
|
||||
auto c = toSQLTCHAR(catalog);
|
||||
auto s = toSQLTCHAR(schema);
|
||||
auto t = toSQLTCHAR(table);
|
||||
r = SQLSpecialColumns(hStmt,
|
||||
SQL_BEST_ROWID,
|
||||
catalog.isEmpty() ? nullptr : c.data(), c.size(),
|
||||
schema.isEmpty() ? nullptr : s.data(), s.size(),
|
||||
t.data(), t.size(),
|
||||
SQL_SCOPE_CURROW,
|
||||
SQL_NULLABLE);
|
||||
|
||||
if (r != SQL_SUCCESS) {
|
||||
qSqlWarning(QLatin1String("QODBCDriver::primaryIndex: Unable to execute primary key list"), d);
|
||||
|
@ -2538,15 +2566,17 @@ QSqlRecord QODBCDriver::record(const QString& tablename) const
|
|||
SQL_ATTR_CURSOR_TYPE,
|
||||
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
|
||||
SQL_IS_UINTEGER);
|
||||
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,
|
||||
0);
|
||||
{
|
||||
auto c = toSQLTCHAR(catalog);
|
||||
auto s = toSQLTCHAR(schema);
|
||||
auto t = toSQLTCHAR(table);
|
||||
r = SQLColumns(hStmt,
|
||||
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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue