summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/generic/qgenericengine.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qnsview_drawing.mm3
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow.cpp3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp117
-rw-r--r--src/plugins/platforms/windows/qwindowsdropdataobject.cpp22
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp5
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp3
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp37
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h1
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp30
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm80
16 files changed, 205 insertions, 114 deletions
diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
index 7472758418..b1f28849a7 100644
--- a/src/plugins/bearer/generic/qgenericengine.cpp
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -300,7 +300,7 @@ void QGenericEngine::doRequestUpdate()
if (interface.flags() & QNetworkInterface::IsLoopBack)
continue;
-#ifndef Q_OS_WINRT
+#ifndef Q_OS_WIN
// ignore WLAN interface handled in separate engine
if (qGetInterfaceType(interface.name()) == QNetworkConfiguration::BearerWLAN)
continue;
diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm
index 0cebc8d98d..3690d6ebb4 100644
--- a/src/plugins/platforms/cocoa/qnsview_drawing.mm
+++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm
@@ -154,6 +154,7 @@
<< "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested"
: [self shouldUseMetalLayer] ? "needed by surface type" : "enabled by macOS");
[super setLayer:layer];
+ layer.delegate = self;
}
- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
@@ -163,12 +164,14 @@
return NSViewLayerContentsRedrawDuringViewResize;
}
+#if 0 // Disabled until we enable lazy backingstore resizing
- (NSViewLayerContentsPlacement)layerContentsPlacement
{
// Always place the layer at top left without any automatic scaling,
// so that we can re-use larger layers when resizing a window down.
return NSViewLayerContentsPlacementTopLeft;
}
+#endif
- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
{
diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
index 48469b0f8c..c8a1ddf9b9 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
@@ -199,6 +199,10 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
QEglFSWindow *w = qt_egl_device_integration()->createWindow(window);
w->create();
+ const auto showWithoutActivating = window->property("_q_showWithoutActivating");
+ if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
+ return w;
+
// Activate only the window for the primary screen to make input work
if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
w->requestActivateWindow();
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
index 98e9ee4728..c1d5af47aa 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
@@ -167,6 +167,9 @@ void QEglFSWindow::create()
void QEglFSWindow::destroy()
{
+ if (!m_flags.testFlag(Created))
+ return; // already destroyed
+
#ifndef QT_NO_OPENGL
QOpenGLCompositor::instance()->removeWindow(this);
#endif
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h
index a19cf7e8bc..ee4b7978f1 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h
@@ -55,6 +55,9 @@ public:
: QEglFSWindow(w),
m_integration(integration)
{ }
+
+ ~QEglFSKmsGbmWindow() { destroy(); }
+
void resetSurface() override;
void invalidateSurface() override;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index ecdfb352ab..3e78196227 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -116,6 +116,8 @@ public:
, m_egl_stream(EGL_NO_STREAM_KHR)
{ }
+ ~QEglFSKmsEglDeviceWindow() { destroy(); }
+
void invalidateSurface() override;
void resetSurface() override;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp
index 0d9b6b6290..d1250ec9bf 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2integration.cpp
@@ -205,6 +205,9 @@ public:
: QEglFSWindow(w)
, m_integration(integration)
{}
+
+ ~QEglFSKmsVsp2Window() { destroy(); }
+
void resetSurface() override;
void invalidateSurface() override;
const QEglFSKmsVsp2Integration *m_integration;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 6da7265cfd..9de3268fc8 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -569,12 +569,10 @@ public:
bool isFileSystem() const { return (m_attributes & SFGAO_FILESYSTEM) != 0; }
bool isDir() const { return (m_attributes & SFGAO_FOLDER) != 0; }
- // Copy using IFileOperation
- bool canCopy() const { return (m_attributes & SFGAO_CANCOPY) != 0; }
// Supports IStream
bool canStream() const { return (m_attributes & SFGAO_STREAM) != 0; }
- bool copyData(QIODevice *out);
+ bool copyData(QIODevice *out, QString *errorMessage);
static IShellItems itemsFromItemArray(IShellItemArray *items);
@@ -666,14 +664,19 @@ QWindowsShellItem::IShellItems QWindowsShellItem::itemsFromItemArray(IShellItemA
return result;
}
-bool QWindowsShellItem::copyData(QIODevice *out)
+bool QWindowsShellItem::copyData(QIODevice *out, QString *errorMessage)
{
- if (!canCopy() || !canStream())
+ if (!canStream()) {
+ *errorMessage = QLatin1String("Item not streamable");
return false;
+ }
IStream *istream = nullptr;
HRESULT hr = m_item->BindToHandler(nullptr, BHID_Stream, IID_PPV_ARGS(&istream));
- if (FAILED(hr))
+ if (FAILED(hr)) {
+ *errorMessage = QLatin1String("BindToHandler() failed: ")
+ + QLatin1String(QWindowsContext::comErrorString(hr));
return false;
+ }
enum : ULONG { bufSize = 102400 };
char buffer[bufSize];
ULONG bytesRead;
@@ -686,7 +689,12 @@ bool QWindowsShellItem::copyData(QIODevice *out)
break;
}
istream->Release();
- return hr == S_OK || hr == S_FALSE;
+ if (hr != S_OK && hr != S_FALSE) {
+ *errorMessage = QLatin1String("Read() failed: ")
+ + QLatin1String(QWindowsContext::comErrorString(hr));
+ return false;
+ }
+ return true;
}
// Helper for "Libraries": collections of folders appearing from Windows 7
@@ -735,8 +743,6 @@ void QWindowsShellItem::format(QDebug &d) const
d << " [dir]";
if (canStream())
d << " [stream]";
- if (canCopy())
- d << " [copyable]";
d << ", normalDisplay=\"" << normalDisplay()
<< "\", desktopAbsoluteParsing=\"" << desktopAbsoluteParsing()
<< "\", urlString=\"" << urlString() << "\", fileSysPath=\"" << fileSysPath() << '"';
@@ -967,7 +973,9 @@ void QWindowsNativeFileDialogBase::doExec(HWND owner)
const HRESULT hr = m_fileDialog->Show(owner);
QWindowsDialogs::eatMouseMove();
qCDebug(lcQpaDialogs) << '<' << __FUNCTION__ << " returns " << hex << hr;
- if (hr == S_OK) {
+ // Emit accepted() only if there is a result as otherwise UI hangs occur.
+ // For example, typing in invalid URLs results in empty result lists.
+ if (hr == S_OK && !m_data.selectedFiles().isEmpty()) {
emit accepted();
} else {
emit rejected();
@@ -1393,21 +1401,50 @@ static void cleanupTemporaryItemCopies()
QFile::remove(file);
}
-static QString createTemporaryItemCopy(QWindowsShellItem &qItem)
+// Determine temporary file pattern from a shell item's display
+// name. This can be a URL.
+
+static bool validFileNameCharacter(QChar c)
+{
+ return c.isLetterOrNumber() || c == QLatin1Char('_') || c == QLatin1Char('-');
+}
+
+QString tempFilePattern(QString name)
{
- if (!qItem.canCopy() || !qItem.canStream())
+ const int lastSlash = qMax(name.lastIndexOf(QLatin1Char('/')),
+ name.lastIndexOf(QLatin1Char('\\')));
+ if (lastSlash != -1)
+ name.remove(0, lastSlash + 1);
+
+ int lastDot = name.lastIndexOf(QLatin1Char('.'));
+ if (lastDot < 0)
+ lastDot = name.size();
+ name.insert(lastDot, QStringLiteral("_XXXXXX"));
+
+ for (int i = lastDot - 1; i >= 0; --i) {
+ if (!validFileNameCharacter(name.at(i)))
+ name[i] = QLatin1Char('_');
+ }
+
+ name.prepend(QDir::tempPath() + QLatin1Char('/'));
+ return name;
+}
+
+static QString createTemporaryItemCopy(QWindowsShellItem &qItem, QString *errorMessage)
+{
+ if (!qItem.canStream()) {
+ *errorMessage = QLatin1String("Item not streamable");
return QString();
- QString pattern = qItem.normalDisplay();
- const int lastDot = pattern.lastIndexOf(QLatin1Char('.'));
- const QString placeHolder = QStringLiteral("_XXXXXX");
- if (lastDot >= 0)
- pattern.insert(lastDot, placeHolder);
- else
- pattern.append(placeHolder);
-
- QTemporaryFile targetFile(QDir::tempPath() + QLatin1Char('/') + pattern);
+ }
+
+ QTemporaryFile targetFile(tempFilePattern(qItem.normalDisplay()));
targetFile.setAutoRemove(false);
- if (!targetFile.open() || !qItem.copyData(&targetFile))
+ if (!targetFile.open()) {
+ *errorMessage = QLatin1String("Cannot create temporary file: ")
+ + targetFile.errorString();
+ return QString();
+ }
+ if (!qItem.copyData(&targetFile, errorMessage))
return QString();
const QString result = targetFile.fileName();
if (temporaryItemCopies()->isEmpty())
@@ -1416,23 +1453,41 @@ static QString createTemporaryItemCopy(QWindowsShellItem &qItem)
return result;
}
+static QUrl itemToDialogUrl(QWindowsShellItem &qItem, QString *errorMessage)
+{
+ QUrl url = qItem.url();
+ if (url.isLocalFile() || url.scheme().startsWith(QLatin1String("http")))
+ return url;
+ const QString path = qItem.path();
+ if (path.isEmpty() && !qItem.isDir() && qItem.canStream()) {
+ const QString temporaryCopy = createTemporaryItemCopy(qItem, errorMessage);
+ if (temporaryCopy.isEmpty()) {
+ QDebug(errorMessage).noquote() << "Unable to create a local copy of"
+ << qItem << ": " << errorMessage;
+ return QUrl();
+ }
+ return QUrl::fromLocalFile(temporaryCopy);
+ }
+ if (!url.isValid())
+ QDebug(errorMessage).noquote() << "Invalid URL obtained from" << qItem;
+ return url;
+}
+
QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
{
QList<QUrl> result;
IShellItemArray *items = nullptr;
if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items) {
+ QString errorMessage;
for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) {
QWindowsShellItem qItem(item);
- const QString path = qItem.path();
- if (path.isEmpty() && !qItem.isDir()) {
- const QString temporaryCopy = createTemporaryItemCopy(qItem);
- if (temporaryCopy.isEmpty())
- qWarning() << "Unable to create a local copy of" << qItem;
- else
- result.append(QUrl::fromLocalFile(temporaryCopy));
- } else {
- result.append(qItem.url());
+ const QUrl url = itemToDialogUrl(qItem, &errorMessage);
+ if (!url.isValid()) {
+ qWarning("%s", qPrintable(errorMessage));
+ result.clear();
+ break;
}
+ result.append(url);
}
}
return result;
diff --git a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
index 229ff92894..e1a41c0ede 100644
--- a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
+++ b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
@@ -41,6 +41,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qmimedata.h>
+#include "qwindowsmime.h"
QT_BEGIN_NAMESPACE
@@ -48,8 +49,9 @@ QT_BEGIN_NAMESPACE
\class QWindowsDropDataObject
\brief QWindowsOleDataObject subclass specialized for handling Drag&Drop.
- Only allows "text/uri-list" data to be exported as CF_HDROP, to allow dropped
- files to be attached to Office applications (instead of adding an URL link).
+ Prevents "text/uri-list" data for local files from being exported as text
+ or URLs, to allow dropped files to be attached to Office applications
+ (instead of creating local hyperlinks).
\internal
\ingroup qt-lighthouse-win
@@ -80,14 +82,22 @@ QWindowsDropDataObject::QueryGetData(LPFORMATETC pformatetc)
return QWindowsOleDataObject::QueryGetData(pformatetc);
}
-// If the data is text/uri-list for local files, tell we can only export it as CF_HDROP.
+// If the data is "text/uri-list" only, and all URIs are for local files,
+// we prevent it from being exported as text or URLs, to make target applications
+// like MS Office attach or open the files instead of creating local hyperlinks.
bool QWindowsDropDataObject::shouldIgnore(LPFORMATETC pformatetc) const
{
QMimeData *dropData = mimeData();
- if (dropData && dropData->hasFormat(QStringLiteral("text/uri-list")) && (pformatetc->cfFormat != CF_HDROP)) {
- QList<QUrl> urls = dropData->urls();
- return std::any_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
+ if (dropData && dropData->formats().size() == 1 && dropData->hasUrls()) {
+ QString formatName = QWindowsMimeConverter::clipboardFormatName(pformatetc->cfFormat);
+ if (pformatetc->cfFormat == CF_UNICODETEXT
+ || pformatetc->cfFormat == CF_TEXT
+ || formatName == QStringLiteral("UniformResourceLocator")
+ || formatName == QStringLiteral("UniformResourceLocatorW")) {
+ QList<QUrl> urls = dropData->urls();
+ return std::all_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
+ }
}
return false;
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 96e34fb44c..030d8d1e0f 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -1087,7 +1087,10 @@ bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMi
const QImage image = qvariant_cast<QImage>(mimeData->imageData());
if (image.isNull())
return false;
- return cf == CF_DIBV5 || (cf == CF_DIB) || cf == int(CF_PNG);
+ // QTBUG-64322: Use PNG only for transparent images as otherwise MS PowerPoint
+ // cannot handle it.
+ return cf == CF_DIBV5 || cf == CF_DIB
+ || (cf == int(CF_PNG) && image.hasAlphaChannel());
}
bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
index 85a931e015..c7c0deab3f 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
@@ -113,6 +113,9 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
case QAccessible::ValueChanged:
QWindowsUiaMainProvider::notifyValueChange(static_cast<QAccessibleValueChangeEvent *>(event));
break;
+ case QAccessible::SelectionAdd:
+ QWindowsUiaMainProvider::notifySelectionChange(event);
+ break;
case QAccessible::TextAttributeChanged:
case QAccessible::TextColumnChanged:
case QAccessible::TextInserted:
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index fad83fb165..44328492a6 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -146,9 +146,33 @@ void QWindowsUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *eve
void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *event)
{
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
- if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
- // Notifies changes in values of controls supporting the value interface.
+ if (accessible->role() == QAccessible::ComboBox && accessible->childCount() > 0) {
+ QAccessibleInterface *listacc = accessible->child(0);
+ if (listacc && listacc->role() == QAccessible::List) {
+ int count = listacc->childCount();
+ for (int i = 0; i < count; ++i) {
+ QAccessibleInterface *item = listacc->child(i);
+ if (item && item->text(QAccessible::Name) == event->value()) {
+ if (!item->state().selected) {
+ if (QAccessibleActionInterface *actionInterface = item->actionInterface())
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (event->value().type() == QVariant::String) {
+ if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
+ // Notifies changes in string values.
+ VARIANT oldVal, newVal;
+ clearVariant(&oldVal);
+ setVariantString(event->value().toString(), &newVal);
+ QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal);
+ }
+ } else if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
+ // Notifies changes in values of controls supporting the value interface.
VARIANT oldVal, newVal;
clearVariant(&oldVal);
setVariantDouble(valueInterface->currentValue().toDouble(), &newVal);
@@ -158,6 +182,15 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve
}
}
+void QWindowsUiaMainProvider::notifySelectionChange(QAccessibleEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
+ QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_SelectionItem_ElementSelectedEventId);
+ }
+ }
+}
+
// Notifies changes in text content and selection state of text controls.
void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
{
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
index 325d5b3de4..df0d60f9c9 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
@@ -68,6 +68,7 @@ public:
static void notifyFocusChange(QAccessibleEvent *event);
static void notifyStateChange(QAccessibleStateChangeEvent *event);
static void notifyValueChange(QAccessibleValueChangeEvent *event);
+ static void notifySelectionChange(QAccessibleEvent *event);
static void notifyTextChange(QAccessibleEvent *event);
// IUnknown
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 476de6d1e5..4adf662152 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -270,7 +270,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
// ES does not support any format option
m_format.setOptions(QSurfaceFormat::FormatOptions());
}
-
+ // Robustness must match that of the shared context.
+ if (share && share->format().testOption(QSurfaceFormat::ResetNotification))
+ m_format.setOption(QSurfaceFormat::ResetNotification);
Q_ASSERT(glVersions.count() > 0);
for (int i = 0; !m_context && i < glVersions.count(); i++) {
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 04ddd3c98c..91fd612cde 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -1208,6 +1208,11 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
return handled;
}
+inline qreal scaleOneValuator(qreal normValue, qreal screenMin, qreal screenSize)
+{
+ return screenMin + normValue * screenSize;
+}
+
void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData)
{
auto *ev = reinterpret_cast<const qt_xcb_input_device_event_t *>(event);
@@ -1220,6 +1225,17 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
QPointF global(fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y));
double pressure = 0, rotation = 0, tangentialPressure = 0;
int xTilt = 0, yTilt = 0;
+ static const bool useValuators = !qEnvironmentVariableIsSet("QT_XCB_TABLET_LEGACY_COORDINATES");
+
+ // Valuators' values are relative to the physical size of the current virtual
+ // screen. Therefore we cannot use QScreen/QWindow geometry and should use
+ // QPlatformWindow/QPlatformScreen instead.
+ QRect physicalScreenArea;
+ if (Q_LIKELY(useValuators)) {
+ const QList<QPlatformScreen *> siblings = window->screen()->handle()->virtualSiblings();
+ for (const QPlatformScreen *screen : siblings)
+ physicalScreenArea |= screen->geometry();
+ }
for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData->valuatorInfo.begin(),
ite = tabletData->valuatorInfo.end(); it != ite; ++it) {
@@ -1228,6 +1244,20 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal);
double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal);
switch (valuator) {
+ case QXcbAtom::AbsX:
+ if (Q_LIKELY(useValuators)) {
+ const qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.x(), physicalScreenArea.width());
+ global.setX(value);
+ local.setX(value - window->handle()->geometry().x());
+ }
+ break;
+ case QXcbAtom::AbsY:
+ if (Q_LIKELY(useValuators)) {
+ qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.y(), physicalScreenArea.height());
+ global.setY(value);
+ local.setY(value - window->handle()->geometry().y());
+ }
+ break;
case QXcbAtom::AbsPressure:
pressure = normalizedValue;
break;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 9a11c4d818..847b1a6034 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -1156,66 +1156,6 @@ static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QS
}
#endif
-static NSColor *qt_convertColorForContext(CGContextRef context, NSColor *color)
-{
- Q_ASSERT(color);
- Q_ASSERT(context);
-
- CGColorSpaceRef targetCGColorSpace = CGBitmapContextGetColorSpace(context);
- NSColorSpace *targetNSColorSpace = [[NSColorSpace alloc] initWithCGColorSpace:targetCGColorSpace];
- NSColor *adjusted = [color colorUsingColorSpace:targetNSColorSpace];
- [targetNSColorSpace release];
-
- return adjusted;
-}
-
-static NSColor *qt_colorForContext(CGContextRef context, const CGFloat (&rgba)[4])
-{
- Q_ASSERT(context);
-
- auto colorSpace = CGBitmapContextGetColorSpace(context);
- if (!colorSpace)
- return nil;
-
- return qt_convertColorForContext(context, [NSColor colorWithSRGBRed:rgba[0] green:rgba[1] blue:rgba[2] alpha:rgba[3]]);
-}
-
-static void qt_drawDisclosureButton(CGContextRef context, NSInteger state, bool selected, CGRect rect)
-{
- Q_ASSERT(context);
-
- static const CGFloat gray[] = {0.55, 0.55, 0.55, 0.97};
- static const CGFloat white[] = {1.0, 1.0, 1.0, 0.9};
-
- NSColor *fillColor = qt_colorForContext(context, selected ? white : gray);
- [fillColor setFill];
-
- if (state == NSOffState) {
- static NSBezierPath *triangle = [[NSBezierPath alloc] init];
- [triangle removeAllPoints];
- // In off state, a disclosure button is an equilateral triangle
- // ('pointing' to the right) with a bound rect that can be described
- // as NSMakeRect(0, 0, 8, 9). Inside the 'rect' it's translated by
- // (2, 4).
- [triangle moveToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4)];
- [triangle lineToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4 + 9)];
- [triangle lineToPoint:NSMakePoint(rect.origin.x + 2 + 8, rect.origin.y + 4 + 4.5)];
- [triangle closePath];
- [triangle fill];
- } else {
- static NSBezierPath *openTriangle = [[NSBezierPath alloc] init];
- [openTriangle removeAllPoints];
- // In 'on' state, the button is an equilateral triangle (looking down)
- // with the bounding rect NSMakeRect(0, 0, 9, 8). Inside the 'rect'
- // it's translated by (1, 4).
- [openTriangle moveToPoint:NSMakePoint(rect.origin.x + 1, rect.origin.y + 4 + 8)];
- [openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 9, rect.origin.y + 4 + 8)];
- [openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 4.5, rect.origin.y + 4)];
- [openTriangle closePath];
- [openTriangle fill];
- }
-}
-
void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const
{
QPainterPath focusRingPath;
@@ -3301,15 +3241,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
CGContextScaleCTM(cg, 1, -1);
CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y);
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave && !qt_mac_applicationIsInDarkMode()) {
- // When the real system theme is one of the 'Dark' themes, and an application forces the 'Aqua' theme,
- // under some conditions (see QTBUG-74515 for more details) NSButtonCell seems to select the 'Dark'
- // code path and is becoming transparent, thus 'invisible' on the white background. To workaround this,
- // we draw the disclose triangle manually:
- qt_drawDisclosureButton(cg, triangleCell.state, (opt->state & State_Selected) && viewHasFocus, rect);
- } else {
- [triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
- }
+ [triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
+
d->restoreNSGraphicsContext(cg);
break; }
@@ -3411,18 +3344,20 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
case PE_IndicatorTabClose: {
// Make close button visible only on the hovered tab.
QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget());
+ const QWidget *closeBtn = w;
if (!tabBar) {
// QStyleSheetStyle instead of CloseButton (which has
// a QTabBar as a parent widget) uses the QTabBar itself:
tabBar = qobject_cast<QTabBar *>(const_cast<QWidget*>(w));
+ closeBtn = decltype(closeBtn)(property("_q_styleSheetRealCloseButton").value<void *>());
}
if (tabBar) {
const bool documentMode = tabBar->documentMode();
const QTabBarPrivate *tabBarPrivate = static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar));
const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex();
if (!documentMode ||
- (hoveredTabIndex != -1 && ((w == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) ||
- (w == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide))))) {
+ (hoveredTabIndex != -1 && ((closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) ||
+ (closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide))))) {
const bool hover = (opt->state & State_MouseOver);
const bool selected = (opt->state & State_Selected);
const bool pressed = (opt->state & State_Sunken);
@@ -4323,7 +4258,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
d->setupNSGraphicsContext(cgCtx, YES);
[s.toNSString() drawInRect:textRect
- withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c }];
+ withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c,
+ NSObliquenessAttributeName: [NSNumber numberWithDouble: myFont.italic() ? 0.3 : 0.0]}];
d->restoreNSGraphicsContext(cgCtx);
} else {