From 2b47afadc0fcc9a2617d5c9e8be0ee035762e0b9 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Wed, 12 Jul 2017 17:15:10 +0200 Subject: gtk3: Disable native file dialogs on GTK3 < 3.15.5 Showing file dialogs if running on a system that has an older GTK3 version installed results in a crash. Do a version check at runtime and disable native file dialog support if the version is too old. (GTK3 bug: https://bugzilla.gnome.org/show_bug.cgi?id=725164) Change-Id: I77bd23f1298333412bae04f52153e1a224ddf470 Reviewed-by: Oswald Buddenhagen Reviewed-by: J-P Nurmi Reviewed-by: Dmitry Shachnev --- src/plugins/platformthemes/gtk3/qgtk3theme.cpp | 17 ++++++++++++++++- src/plugins/platformthemes/gtk3/qgtk3theme.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp index 6447776f25..077955eb4e 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp @@ -153,7 +153,7 @@ bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const case ColorDialog: return true; case FileDialog: - return true; + return useNativeFileDialog(); case FontDialog: return true; default: @@ -167,6 +167,8 @@ QPlatformDialogHelper *QGtk3Theme::createPlatformDialogHelper(DialogType type) c case ColorDialog: return new QGtk3ColorDialogHelper; case FileDialog: + if (!useNativeFileDialog()) + return nullptr; return new QGtk3FileDialogHelper; case FontDialog: return new QGtk3FontDialogHelper; @@ -185,4 +187,17 @@ QPlatformMenuItem* QGtk3Theme::createPlatformMenuItem() const return new QGtk3MenuItem; } +bool QGtk3Theme::useNativeFileDialog() +{ + /* Require GTK3 >= 3.15.5 to avoid running into this bug: + * https://bugzilla.gnome.org/show_bug.cgi?id=725164 + * + * While this bug only occurs when using widget-based file dialogs + * (native GTK3 dialogs are fine) we have to disable platform file + * dialogs entirely since we can't avoid creation of a platform + * dialog helper. + */ + return gtk_check_version(3, 15, 5) == 0; +} + QT_END_NAMESPACE diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.h b/src/plugins/platformthemes/gtk3/qgtk3theme.h index 52036680c6..abc5dbfd17 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3theme.h +++ b/src/plugins/platformthemes/gtk3/qgtk3theme.h @@ -59,6 +59,8 @@ public: QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE; static const char *name; +private: + static bool useNativeFileDialog(); }; QT_END_NAMESPACE -- cgit v1.2.3 From 6d50f746fe05a7008b63818e77784dd0c99270a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Ryyn=C3=A4nen?= Date: Fri, 2 Jun 2017 12:53:23 +0300 Subject: Support for Q_OS_ANDROID_EMBEDDED and android-embedded build flags The Embedded Android build (Boot to Qt Android injection) is defined by having both Q_OS_ANDROID and Q_OS_ANDROID_EMBEDDED flags defined, as well as having Qt config android-embedded. This commit enables the possibility to build embedded Android builds. (i.e. Qt build for Android baselayer only, without JNI) Change-Id: I8406e959fdf1c8d9efebbbe53f1a391fa25f336a Reviewed-by: Oswald Buddenhagen Reviewed-by: Paul Olav Tvete --- src/plugins/bearer/bearer.pro | 2 +- src/plugins/platforms/eglfs/api/qeglfswindow.cpp | 2 +- src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp | 6 +++--- src/plugins/platforms/platforms.pro | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index 824fd0388f..afdc613167 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -6,6 +6,6 @@ QT_FOR_CONFIG += network-private SUBDIRS += connman networkmanager } -android:SUBDIRS += android +android:!android-embedded: SUBDIRS += android isEmpty(SUBDIRS):SUBDIRS = generic diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index 9b4732eab4..17e4aa1df8 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -117,7 +117,7 @@ void QEglFSWindow::create() QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); if (screen->primarySurface() != EGL_NO_SURFACE) { if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) { -#if !defined(Q_OS_ANDROID) +#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED) // We can have either a single OpenGL window or multiple raster windows. // Other combinations cannot work. qFatal("EGLFS: OpenGL windows cannot be mixed with others."); diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index 6f79cd96d3..f835dbf6d4 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -59,13 +59,13 @@ #include #endif -#if QT_CONFIG(evdev) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) #include #include #include #endif -#if QT_CONFIG(tslib) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(tslib) #include #endif @@ -162,7 +162,7 @@ void QLinuxFbIntegration::createInputHandlers() new QTsLibMouseHandler(QLatin1String("TsLib"), QString()); #endif -#if QT_CONFIG(evdev) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this); #if QT_CONFIG(tslib) diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 9ccc2b54b9..9414f01ef0 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs QT_FOR_CONFIG += gui-private -android: SUBDIRS += android +android:!android-embedded: SUBDIRS += android !android: SUBDIRS += minimal -- cgit v1.2.3 From a69a0e8254b79c62fad7372e8c14f66d440ad744 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 23 Jan 2018 10:21:49 +0100 Subject: glx: Avoid losing the stereo flag in QSurfaceFormat Task-number: QTBUG-59636 Change-Id: I38394009993e92ab9db853a1450687fc48e471f5 Reviewed-by: Andy Nichols --- src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/plugins') 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 e2e573f0e1..fc1806f982 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -134,7 +134,11 @@ static void updateFormatFromContext(QSurfaceFormat &format) } format.setProfile(QSurfaceFormat::NoProfile); + const bool isStereo = format.testOption(QSurfaceFormat::StereoBuffers); format.setOptions(QSurfaceFormat::FormatOptions()); + // Restore flags that come from the VisualInfo/FBConfig. + if (isStereo) + format.setOption(QSurfaceFormat::StereoBuffers); if (format.renderableType() == QSurfaceFormat::OpenGL) { if (format.version() < qMakePair(3, 0)) { -- cgit v1.2.3 From 965bcca6d4e22788721a9af906adfbd97af9af29 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 23 Mar 2017 17:49:16 +0100 Subject: Cocoa: Explicitly hide popup windows when the application is hidden MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the application is hidden then Qt will hide the popup windows associated with it when it has lost the activation for the application. However, when it gets to this point it believes the popup windows to be hidden already due to the fact that the application itself is hidden. As a result, when the application is restored it causes a problem with the still visible popup window as it is taking the input events without responding to them. Therefore we need to explicitly hide the windows right before the application is hidden to ensure that they are actually hidden correctly. Task-number: QTBUG-58727 Change-Id: I4be1e1c0b1388d0c9ec872e7732185670998b7af Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoaapplicationdelegate.mm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 35ac7182af..03148c769b 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -328,6 +328,24 @@ QT_END_NAMESPACE return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together. } +- (void)applicationWillHide:(NSNotification *)notification +{ + if (reflectionDelegate + && [reflectionDelegate respondsToSelector:@selector(applicationWillHide:)]) { + [reflectionDelegate applicationWillHide:notification]; + } + + // When the application is hidden Qt will hide the popup windows associated with + // it when it has lost the activation for the application. However, when it gets + // to this point it believes the popup windows to be hidden already due to the + // fact that the application itself is hidden, which will cause a problem when + // the application is made visible again. + const QWindowList topLevelWindows = QGuiApplication::topLevelWindows(); + for (QWindow *topLevelWindow : qAsConst(topLevelWindows)) { + if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) + topLevelWindow->hide(); + } +} - (void)applicationDidBecomeActive:(NSNotification *)notification { -- cgit v1.2.3 From a87b549edfb66b3c3bc14466455792aea6e80c84 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Wed, 17 Jan 2018 11:01:28 +0200 Subject: Fix compilation with -no-feature-regularexpression Change-Id: I4d213a266034d388af723337deeeb4cdd1f5cbdb Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsdialoghelpers.cpp | 27 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 6b978a38fe..bdae764025 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -65,7 +65,6 @@ #include #include #include -#include #include #include @@ -1153,12 +1152,32 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel } } +static bool isHexRange(const QString& s, int start, int end) +{ + for (;start < end; ++start) { + QChar ch = s.at(start); + if (!(ch.isDigit() + || (ch >= QLatin1Char('a') && ch <= QLatin1Char('f')) + || (ch >= QLatin1Char('A') && ch <= QLatin1Char('F')))) + return false; + } + return true; +} + static inline bool isClsid(const QString &s) { // detect "374DE290-123F-4565-9164-39C4925E467B". - static const QRegularExpression pattern(QLatin1String("\\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\z")); - Q_ASSERT(pattern.isValid()); - return pattern.match(s).hasMatch(); + const QChar dash(QLatin1Char('-')); + return s.size() == 36 + && isHexRange(s, 0, 8) + && s.at(8) == dash + && isHexRange(s, 9, 13) + && s.at(13) == dash + && isHexRange(s, 14, 18) + && s.at(18) == dash + && isHexRange(s, 19, 23) + && s.at(23) == dash + && isHexRange(s, 24, 36); } void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const -- cgit v1.2.3 From f5b1b10a1120ce5f9ffb43cc05fe4a0e39f43e36 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 24 Jan 2018 12:38:10 +0100 Subject: Android: Fix compilation with warnings-are-errors Variable was added in e2e874415e1f1c6a96915d9dc85dd31c61f73e24 but is not used anywhere. Change-Id: Iff1e7c20317bb489978eb77d24b8da12493d7e45 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/androidjniclipboard.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/androidjniclipboard.cpp b/src/plugins/platforms/android/androidjniclipboard.cpp index 833996403c..d169035339 100644 --- a/src/plugins/platforms/android/androidjniclipboard.cpp +++ b/src/plugins/platforms/android/androidjniclipboard.cpp @@ -47,7 +47,6 @@ namespace QtAndroidClipboard { QAndroidPlatformClipboard *m_manager = nullptr; - static char const *const QtNativeClassName = "org/qtproject/qt5/android/QtNative"; static JNINativeMethod methods[] = { {"onClipboardDataChanged", "()V", (void *)onClipboardDataChanged} }; -- cgit v1.2.3 From 089969540f4877c778172ee0ccbd69960a179b43 Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Fri, 26 Jan 2018 19:10:46 +0300 Subject: Remove traces of Growl in QSystemTrayIcon code and documentation Growl support was removed in Qt 5.8. Change-Id: I00a36cd955194ca8ceee52841a89ca579da01284 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index e756f0aeb0..f4c968ab57 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -72,8 +72,6 @@ ** ****************************************************************************/ -#define QT_MAC_SYSTEMTRAY_USE_GROWL - #include "qcocoasystemtrayicon.h" #ifndef QT_NO_SYSTEMTRAYICON -- cgit v1.2.3 From 6b1ecb1904c3f7281d90e672971f23d54bb76600 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 13 Dec 2017 15:00:36 +0200 Subject: Android: Hide handler(s) if the cursor is not visible anymore On Android if the edit control is bigger than the remaining screen we resize it, this caused the handler(s) to remain outside the control. A better fix will be to ensure that the cursor/selection remains visible when the control is resized but I don't know if this is the desired behavior on all platforms. Task-number: QTBUG-62994 Task-number: QTBUG-58700 Change-Id: If43eb7bc1ecde426697694a8f26118e95fccb80c Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/qandroidinputcontext.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index fe4c5be4cb..fb33ad6e21 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -438,6 +438,16 @@ QAndroidInputContext::QAndroidInputContext() QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QAndroidInputContext::updateSelectionHandles); + QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::anchorRectangleChanged, + this, &QAndroidInputContext::updateSelectionHandles); + QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::inputItemClipRectangleChanged, this, [this]{ + auto im = qGuiApp->inputMethod(); + if (!im->inputItemClipRectangle().contains(im->anchorRectangle()) || + !im->inputItemClipRectangle().contains(im->cursorRectangle())) { + m_cursorHandleShown = CursorHandleNotShown; + updateSelectionHandles(); + } + }); } QAndroidInputContext::~QAndroidInputContext() -- cgit v1.2.3 From 5f924134ff48bc89defe4d6c2ccabeaea6b4450d Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 15 Dec 2017 11:08:16 +0200 Subject: Check selection handles position This patch fixes the strange behavior when selecting text. This patch (on a Left To Right text) makes sure that: - the left handle will select text only on the left & above of the right handle - the right handle will select text only on the right & below of the left handle For RTL is way more complicated: - the left handle is acuatually the right handle but on the left side and it acts as a right handle - the right handle is acuatually the left handle but on the right side and it acts as a left handle Change-Id: Ifca591398103199d5aef479f0a080161c9f44c0e Reviewed-by: Paul Olav Tvete --- .../platforms/android/qandroidinputcontext.cpp | 48 +++++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index fb33ad6e21..f548a1fa96 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -605,27 +605,63 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y) double pixelDensity = window ? QHighDpiScaling::factor(window) : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); - QPoint point(x / pixelDensity, y / pixelDensity); - y -= leftRect.width() / 2; + QPointF point(x / pixelDensity, y / pixelDensity); + point.setY(point.y() - leftRect.width() / 2); if (handleId == 1) { setSelectionOnFocusObject(point, point); return; } - QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition); + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImCurrentSelection); QCoreApplication::sendEvent(m_focusObject, &query); int cpos = query.value(Qt::ImCursorPosition).toInt(); int anchor = query.value(Qt::ImAnchorPosition).toInt(); - + bool rtl = query.value(Qt::ImCurrentSelection).toString().isRightToLeft(); auto rightRect = im->anchorRectangle(); if (cpos > anchor) std::swap(leftRect, rightRect); + auto checkLeftHandle = [&rightRect](QPointF &handlePos) { + if (handlePos.y() > rightRect.center().y()) + handlePos.setY(rightRect.center().y()); // adjust Y handle pos + if (handlePos.y() >= rightRect.y() && handlePos.y() <= rightRect.bottom() && handlePos.x() >= rightRect.x()) + return false; // same line and wrong X pos ? + return true; + }; + + auto checkRtlRightHandle = [&rightRect](QPointF &handlePos) { + if (handlePos.y() > rightRect.center().y()) + handlePos.setY(rightRect.center().y()); // adjust Y handle pos + if (handlePos.y() >= rightRect.y() && handlePos.y() <= rightRect.bottom() && rightRect.x() >= handlePos.x()) + return false; // same line and wrong X pos ? + return true; + }; + + auto checkRightHandle = [&leftRect](QPointF &handlePos) { + if (handlePos.y() < leftRect.center().y()) + handlePos.setY(leftRect.center().y()); // adjust Y handle pos + if (handlePos.y() >= leftRect.y() && handlePos.y() <= leftRect.bottom() && leftRect.x() >= handlePos.x()) + return false; // same line and wrong X pos ? + return true; + }; + + auto checkRtlLeftHandle = [&leftRect](QPointF &handlePos) { + if (handlePos.y() < leftRect.center().y()) + handlePos.setY(leftRect.center().y()); // adjust Y handle pos + if (handlePos.y() >= leftRect.y() && handlePos.y() <= leftRect.bottom() && handlePos.x() >= leftRect.x()) + return false; // same line and wrong X pos ? + return true; + }; + if (handleId == 2) { - QPoint rightPoint(rightRect.center().toPoint()); + QPointF rightPoint(rightRect.center()); + if ((!rtl && !checkLeftHandle(point)) || (rtl && !checkRtlRightHandle(point))) + return; setSelectionOnFocusObject(point, rightPoint); } else if (handleId == 3) { - QPoint leftPoint(leftRect.center().toPoint()); + QPointF leftPoint(leftRect.center()); + if ((!rtl && !checkRightHandle(point)) || (rtl && !checkRtlLeftHandle(point))) + return; setSelectionOnFocusObject(leftPoint, point); } } -- cgit v1.2.3 From 9b2913377807b3dae107befeec0bc488f4a2cbad Mon Sep 17 00:00:00 2001 From: Nathan Collins Date: Mon, 29 Jan 2018 14:37:57 +0000 Subject: Fix QFileDialog::defaultSuffix on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't prepend the default suffix to the NSSavePanel allowedFileTypes. "If no extension is given by the user, the first item in the allowedFileTypes array will be used as the extension for the save panel." The user expects to get the suffix displayed to them in the drop down filter, not the default suffix set by the developer. Apply the default suffix if neither the user or the NSSavePanel provide a suffix. Task-number: QTBUG-66066 Change-Id: I64093b9f3178bd2377a7b65d6f23aed6214a4119 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 74148b7cbf..c1c7903766 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -418,6 +418,13 @@ static QString strippedText(QString s) } else { QList result; QString filename = QString::fromNSString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C); + const QString defaultSuffix = mOptions->defaultSuffix(); + const QFileInfo fileInfo(filename); + // If neither the user or the NSSavePanel have provided a suffix, use + // the default suffix (if it exists). + if (fileInfo.suffix().isEmpty() && !defaultSuffix.isEmpty()) { + filename.append('.').append(defaultSuffix); + } result << QUrl::fromLocalFile(filename.remove(QLatin1String("___qt_very_unlikely_prefix_"))); return result; } @@ -445,10 +452,7 @@ static QString strippedText(QString s) [mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead? if (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) { - QStringList ext = [self acceptableExtensionsForSave]; - const QString defaultSuffix = mOptions->defaultSuffix(); - if (!ext.isEmpty() && !defaultSuffix.isEmpty()) - ext.prepend(defaultSuffix); + const QStringList ext = [self acceptableExtensionsForSave]; [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)]; } else { [mOpenPanel setAllowedFileTypes:nil]; // delegate panel:shouldEnableURL: does the file filtering for NSOpenPanel -- cgit v1.2.3 From 1f0c22844811d71fae69ee6b103bbfc5e750ca90 Mon Sep 17 00:00:00 2001 From: Dominik Haumann Date: Mon, 29 Jan 2018 19:38:49 +0100 Subject: Fix window activation in QWindowsWindow::setCustomMargins() Currently, code paths that call QWindowsWindow:setCustomMargins() automatically also activate the window (=give the window focus). The reason for this is the call of SetWindowPos (Windows API) without the flag SWP_NOACTIVATE. From the Windows API documentation about SetWindowPos() about the flag SWP_NOACTIVATE: Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter). It seems the flag SWP_NOACTIVATE is accidentally missing in the call of SetWindowPos() in setCustomMargins(), especially since the flag is present in pretty much all other calls of SetWindowPos(). The obvious fix is to add the flag SWP_NOACTIVATE to the call of SetWindowPos() in setCustomMargins(). So far, this issue exists for a long time, an was possibly introduced with commit f5fd5346038, where setCustomMargins() was initially added. Change-Id: Id3f058f8762df17eb3f033ab0b3e1791283937fc Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 402009c70d..c1aeecf0ab 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2401,7 +2401,7 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) newFrame.moveTo(topLeft); qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins << currentFrameGeometry << "->" << newFrame; - SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED); + SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE); } } -- cgit v1.2.3 From 756ebcd93a028bd9c731acddbea09de67c2410e3 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 1 Feb 2018 14:37:32 +0100 Subject: QGtk3Menu::showPopup(): fix off by one error in the y-coordinate QRect::bottom() != QRect::y() + QRect::height() Change-Id: I83ae19ab588fb9651354999679f5d3c9e294a97e Reviewed-by: Friedemann Kleint --- src/plugins/platformthemes/gtk3/qgtk3menu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp index f48e00ab8e..99407a21de 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp @@ -448,7 +448,8 @@ void QGtk3Menu::showPopup(const QWindow *parentWindow, const QRect &targetRect, if (index != -1) gtk_menu_set_active(GTK_MENU(m_menu), index); - m_targetPos = targetRect.bottomLeft(); + m_targetPos = QPoint(targetRect.x(), targetRect.y() + targetRect.height()); + if (parentWindow) m_targetPos = parentWindow->mapToGlobal(m_targetPos); -- cgit v1.2.3 From 57f4521c99df1e4e2c1fd321a41019ae4e0c17b1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 2 Feb 2018 08:06:04 +0100 Subject: Fix QXcbWindow::mapFrom/ToGlobal() Call the base class implementations to avoid returning an unmapped values for non-embedded windows. Task-number: QTBUG-55251 Change-Id: Ib05fd530498dd4d72d3d4ef37caf4e2f0ebcd2e4 Reviewed-by: Friedemann Kleint Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c4649ac818..37d6336a72 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2157,7 +2157,7 @@ bool QXcbWindow::isEmbedded() const QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const { if (!m_embedded) - return pos; + return QPlatformWindow::mapToGlobal(pos); QPoint ret; xcb_translate_coordinates_cookie_t cookie = @@ -2177,7 +2177,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const { if (!m_embedded) - return pos; + return QPlatformWindow::mapFromGlobal(pos); QPoint ret; xcb_translate_coordinates_cookie_t cookie = -- cgit v1.2.3 From 1ffc6ba402114a3443df5309dec186fd337e5b66 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 2 Feb 2018 08:50:15 +0100 Subject: macOS: fix menu positioning on high-DPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The target position is passed in physical native pixels, so call QPlatformScreen::availableGeometry() and QPlatformWindow::mapToGlobal() instead of QScreen::availableSize() and QWindow::mapToGlobal(). The latter two operate on logical pixels. Task-number: QTBUG-55251 Change-Id: I281f47baee727bc0f4738fd6d6cdf12c9f462b0f Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoamenu.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 8bdd0512de..e41c70b8ca 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -46,6 +46,7 @@ #include #include #include "qcocoaapplication.h" +#include "qcocoaintegration.h" #include "qcocoamenuloader.h" #include "qcocoamenubar.h" #include "qcocoawindow.h" @@ -573,8 +574,9 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, [popupCell setMenu:m_nativeMenu]; [popupCell selectItem:nsItem]; - int availableHeight = screen->availableSize().height(); - const QPoint &globalPos = parentWindow->mapToGlobal(pos); + QCocoaScreen *cocoaScreen = static_cast(screen->handle()); + int availableHeight = cocoaScreen->availableGeometry().height(); + const QPoint &globalPos = cocoaWindow->mapToGlobal(pos); int menuHeight = m_nativeMenu.size.height; if (globalPos.y() + menuHeight > availableHeight) { // Maybe we need to fix the vertical popup position but we don't know the -- cgit v1.2.3 From fef6b31b994befac0ee14391572ebc2b9b33e104 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 1 Feb 2018 14:40:46 +0100 Subject: GTK: fix menu positioning on high-DPI The target position is passed in physical native pixels, so call QPlatformWindow::mapToGlobal() instead of QWindow::mapToGlobal(). The latter operates on logical pixels. Task-number: QTBUG-55251 Change-Id: I789128a0a345d4113fced82ed1b215fe14044634 Reviewed-by: Friedemann Kleint --- src/plugins/platformthemes/gtk3/qgtk3menu.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp index 99407a21de..cdd1abaf7d 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp @@ -41,6 +41,7 @@ #include #include +#include #undef signals #include @@ -450,8 +451,9 @@ void QGtk3Menu::showPopup(const QWindow *parentWindow, const QRect &targetRect, m_targetPos = QPoint(targetRect.x(), targetRect.y() + targetRect.height()); - if (parentWindow) - m_targetPos = parentWindow->mapToGlobal(m_targetPos); + QPlatformWindow *pw = parentWindow ? parentWindow->handle() : nullptr; + if (pw) + m_targetPos = pw->mapToGlobal(m_targetPos); gtk_menu_popup(GTK_MENU(m_menu), NULL, NULL, qt_gtk_menu_position_func, this, 0, gtk_get_current_event_time()); } -- cgit v1.2.3 From 36171af399e24095a0836e05a519a19e161a278e Mon Sep 17 00:00:00 2001 From: Adam Treat Date: Sat, 2 Dec 2017 10:36:12 -0500 Subject: Make use of our egl convenience code for QNX QPA This fixes various problems that occur because the current egl context assumes OpenGL ES 2.0 and does not support newer versions of ES. Task-number: QTBUG-64306 Change-Id: I81466ba5cf028b47ca5a2ebcdc702167aff655a2 Reviewed-by: James McDonnell --- src/plugins/platforms/qnx/qnx.pro | 4 +- src/plugins/platforms/qnx/qqnxeglwindow.cpp | 130 +++++++------- src/plugins/platforms/qnx/qqnxeglwindow.h | 16 +- src/plugins/platforms/qnx/qqnxglcontext.cpp | 206 ++-------------------- src/plugins/platforms/qnx/qqnxglcontext.h | 30 +--- src/plugins/platforms/qnx/qqnxintegration.cpp | 53 +++++- src/plugins/platforms/qnx/qqnxnativeinterface.cpp | 2 +- src/plugins/platforms/qnx/qqnxscreen.h | 10 +- src/plugins/platforms/qnx/qqnxwindow.h | 3 +- 9 files changed, 159 insertions(+), 295 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 15d33200e5..96bfa1dd19 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -71,14 +71,14 @@ HEADERS = main.h \ LIBS += -lscreen -qtConfig(opengles2) { +qtConfig(egl) { SOURCES += qqnxglcontext.cpp \ qqnxeglwindow.cpp HEADERS += qqnxglcontext.h \ qqnxeglwindow.h - QMAKE_USE += opengl_es2 egl + QMAKE_USE += egl } qtConfig(qqnx_pps) { diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp index 33ce0f924c..48766fc435 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp @@ -56,18 +56,12 @@ QT_BEGIN_NAMESPACE QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) : QQnxWindow(window, context, needRootWindow), - m_platformOpenGLContext(0), m_newSurfaceRequested(true), + m_eglDisplay(EGL_NO_DISPLAY), m_eglSurface(EGL_NO_SURFACE) { initWindow(); - // Set window usage - const int val = SCREEN_USAGE_OPENGL_ES2; - const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &val); - if (Q_UNLIKELY(result != 0)) - qFatal("QQnxEglWindow: failed to set window alpha usage, errno=%d", errno); - m_requestedBufferSize = shouldMakeFullScreen() ? screen()->geometry().size() : window->geometry().size(); } @@ -77,14 +71,58 @@ QQnxEglWindow::~QQnxEglWindow() destroyEGLSurface(); } -void QQnxEglWindow::createEGLSurface() +bool QQnxEglWindow::isInitialized() const { + return m_eglSurface != EGL_NO_SURFACE; +} + +void QQnxEglWindow::ensureInitialized(QQnxGLContext* context) +{ + if (m_newSurfaceRequested.testAndSetOrdered(true, false)) { + const QMutexLocker locker(&m_mutex); // Set geomety must not reset the requestedBufferSize till + // the surface is created + + if (m_requestedBufferSize != bufferSize() || m_eglSurface == EGL_NO_SURFACE) { + if (m_eglSurface != EGL_NO_SURFACE) { + context->doneCurrent(); + destroyEGLSurface(); + } + createEGLSurface(context); + } else { + // Must've been a sequence of unprocessed changes returning us to the original size. + resetBuffers(); + } + } +} + +void QQnxEglWindow::createEGLSurface(QQnxGLContext *context) +{ + if (context->format().renderableType() != QSurfaceFormat::OpenGLES) { + qFatal("QQnxEglWindow: renderable type is not OpenGLES"); + return; + } + + // Set window usage + int usage = SCREEN_USAGE_OPENGL_ES2; +#if _SCREEN_VERSION >= _SCREEN_MAKE_VERSION(1, 0, 0) + if (context->format().majorVersion() == 3) + usage |= SCREEN_USAGE_OPENGL_ES3; +#endif + + const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &usage); + if (Q_UNLIKELY(result != 0)) + qFatal("QQnxEglWindow: failed to set window usage, errno=%d", errno); + if (!m_requestedBufferSize.isValid()) { qWarning("QQNX: Trying to create 0 size EGL surface. " "Please set a valid window size before calling QOpenGLContext::makeCurrent()"); return; } + m_eglDisplay = context->eglDisplay(); + m_eglConfig = context->eglConfig(); + m_format = context->format(); + // update the window's buffers before we create the EGL surface setBufferSize(m_requestedBufferSize); @@ -94,24 +132,27 @@ void QQnxEglWindow::createEGLSurface() EGL_NONE }; - qEglWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay() - << platformOpenGLContext()->getEglConfig(); + qEglWindowDebug() << "Creating EGL surface from" << this << context + << window()->surfaceType() << window()->type(); // Create EGL surface - m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay(), - platformOpenGLContext()->getEglConfig(), - (EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs); - if (m_eglSurface == EGL_NO_SURFACE) { - const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface"); - qWarning("QQNX: failed to create EGL surface, err=%d", error); - } + EGLSurface eglSurface = eglCreateWindowSurface( + m_eglDisplay, + m_eglConfig, + (EGLNativeWindowType) nativeHandle(), + eglSurfaceAttrs); + + if (eglSurface == EGL_NO_SURFACE) + qWarning("QQNX: failed to create EGL surface, err=%d", eglGetError()); + + m_eglSurface = eglSurface; } void QQnxEglWindow::destroyEGLSurface() { // Destroy EGL surface if it exists if (m_eglSurface != EGL_NO_SURFACE) { - EGLBoolean eglResult = eglDestroySurface(platformOpenGLContext()->getEglDisplay(), m_eglSurface); + EGLBoolean eglResult = eglDestroySurface(m_eglDisplay, m_eglSurface); if (Q_UNLIKELY(eglResult != EGL_TRUE)) qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError()); } @@ -119,40 +160,8 @@ void QQnxEglWindow::destroyEGLSurface() m_eglSurface = EGL_NO_SURFACE; } -void QQnxEglWindow::swapEGLBuffers() +EGLSurface QQnxEglWindow::surface() const { - qEglWindowDebug(); - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); - - // Post EGL surface to window - eglResult = eglSwapBuffers(m_platformOpenGLContext->getEglDisplay(), m_eglSurface); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError()); - - windowPosted(); -} - -EGLSurface QQnxEglWindow::getSurface() -{ - if (m_newSurfaceRequested.testAndSetOrdered(true, false)) { - const QMutexLocker locker(&m_mutex); //Set geomety must not reset the requestedBufferSize till - //the surface is created - - if ((m_requestedBufferSize != bufferSize()) || (m_eglSurface == EGL_NO_SURFACE)) { - if (m_eglSurface != EGL_NO_SURFACE) { - platformOpenGLContext()->doneCurrent(); - destroyEGLSurface(); - } - createEGLSurface(); - } else { - // Must've been a sequence of unprocessed changes returning us to the original size. - resetBuffers(); - } - } - return m_eglSurface; } @@ -169,35 +178,24 @@ void QQnxEglWindow::setGeometry(const QRect &rect) // that test. const QMutexLocker locker(&m_mutex); m_requestedBufferSize = newGeometry.size(); - if (m_platformOpenGLContext != 0 && bufferSize() != newGeometry.size()) + if (isInitialized() && bufferSize() != newGeometry.size()) m_newSurfaceRequested.testAndSetRelease(false, true); } QQnxWindow::setGeometry(newGeometry); } -void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext) -{ - // This function does not take ownership of the platform gl context. - // It is owned by the frontend QOpenGLContext - m_platformOpenGLContext = platformOpenGLContext; -} - int QQnxEglWindow::pixelFormat() const { - if (!m_platformOpenGLContext) //The platform GL context was not set yet - return -1; - - const QSurfaceFormat format = m_platformOpenGLContext->format(); // Extract size of color channels from window format - const int redSize = format.redBufferSize(); + const int redSize = m_format.redBufferSize(); if (Q_UNLIKELY(redSize == -1)) qFatal("QQnxWindow: red size not defined"); - const int greenSize = format.greenBufferSize(); + const int greenSize = m_format.greenBufferSize(); if (Q_UNLIKELY(greenSize == -1)) qFatal("QQnxWindow: green size not defined"); - const int blueSize = format.blueBufferSize(); + const int blueSize = m_format.blueBufferSize(); if (Q_UNLIKELY(blueSize == -1)) qFatal("QQnxWindow: blue size not defined"); diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h index 183be11ddc..3a3840f13c 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.h +++ b/src/plugins/platforms/qnx/qqnxeglwindow.h @@ -53,13 +53,10 @@ public: QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow); ~QQnxEglWindow(); - void createEGLSurface(); - void destroyEGLSurface(); - void swapEGLBuffers(); - EGLSurface getSurface(); + EGLSurface surface() const; - void setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext); - QQnxGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; } + bool isInitialized() const; + void ensureInitialized(QQnxGLContext *context); void setGeometry(const QRect &rect) override; @@ -68,6 +65,9 @@ protected: void resetBuffers() override; private: + void createEGLSurface(QQnxGLContext *context); + void destroyEGLSurface(); + QSize m_requestedBufferSize; // This mutex is used to protect access to the m_requestedBufferSize @@ -78,9 +78,11 @@ private: // QQnxGLContext::makeCurrent() mutable QMutex m_mutex; - QQnxGLContext *m_platformOpenGLContext; QAtomicInt m_newSurfaceRequested; + EGLDisplay m_eglDisplay; + EGLConfig m_eglConfig; EGLSurface m_eglSurface; + QSurfaceFormat m_format; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp index d35a4f0bba..d4493943e2 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.cpp +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -59,117 +59,13 @@ QT_BEGIN_NAMESPACE EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY; -QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) - : QPlatformOpenGLContext(), - m_glContext(glContext), - m_currentEglSurface(EGL_NO_SURFACE) +QQnxGLContext::QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share) + : QEGLPlatformContext(format, share, ms_eglDisplay) { - qGLContextDebug(); - QSurfaceFormat format = m_glContext->format(); - - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); - - // Get colour channel sizes from window format - int alphaSize = format.alphaBufferSize(); - int redSize = format.redBufferSize(); - int greenSize = format.greenBufferSize(); - int blueSize = format.blueBufferSize(); - - // Check if all channels are don't care - if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) { - // Set colour channels based on depth of window's screen - QQnxScreen *screen = static_cast(glContext->screen()->handle()); - int depth = screen->depth(); - if (depth == 32) { - // SCREEN_FORMAT_RGBA8888 - alphaSize = 8; - redSize = 8; - greenSize = 8; - blueSize = 8; - } else { - // SCREEN_FORMAT_RGB565 - alphaSize = 0; - redSize = 5; - greenSize = 6; - blueSize = 5; - } - } else { - // Choose best match based on supported pixel formats - if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) { - // SCREEN_FORMAT_RGB565 - alphaSize = 0; - redSize = 5; - greenSize = 6; - blueSize = 5; - } else { - // SCREEN_FORMAT_RGBA8888 - alphaSize = 8; - redSize = 8; - greenSize = 8; - blueSize = 8; - } - } - - // Update colour channel sizes in window format - format.setAlphaBufferSize(alphaSize); - format.setRedBufferSize(redSize); - format.setGreenBufferSize(greenSize); - format.setBlueBufferSize(blueSize); - - // Select EGL config based on requested window format - m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format); - if (Q_UNLIKELY(m_eglConfig == 0)) - qFatal("QQnxGLContext: failed to find EGL config"); - - QQnxGLContext *glShareContext = static_cast(m_glContext->shareHandle()); - m_eglShareContext = glShareContext ? glShareContext->m_eglContext : EGL_NO_CONTEXT; - - m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, m_eglShareContext, - contextAttrs(format)); - if (Q_UNLIKELY(m_eglContext == EGL_NO_CONTEXT)) { - checkEGLError("eglCreateContext"); - qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError()); - } - - // Query/cache window format of selected EGL config - m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig); } QQnxGLContext::~QQnxGLContext() { - qGLContextDebug(); - - // Cleanup EGL context if it exists - if (m_eglContext != EGL_NO_CONTEXT) - eglDestroyContext(ms_eglDisplay, m_eglContext); -} - -EGLenum QQnxGLContext::checkEGLError(const char *msg) -{ - static const char *errmsg[] = - { - "EGL function succeeded", - "EGL is not initialized, or could not be initialized, for the specified display", - "EGL cannot access a requested resource", - "EGL failed to allocate resources for the requested operation", - "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list", - "EGLConfig argument does not name a valid EGLConfig", - "EGLContext argument does not name a valid EGLContext", - "EGL current surface of the calling thread is no longer valid", - "EGLDisplay argument does not name a valid EGLDisplay", - "EGL arguments are inconsistent", - "EGLNativePixmapType argument does not refer to a valid native pixmap", - "EGLNativeWindowType argument does not refer to a valid native window", - "EGL one or more argument values are invalid", - "EGLSurface argument does not name a valid surface configured for rendering", - "EGL power management event has occurred", - }; - EGLenum error = eglGetError(); - fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]); - return error; } void QQnxGLContext::initializeContext() @@ -178,16 +74,12 @@ void QQnxGLContext::initializeContext() // Initialize connection to EGL ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (Q_UNLIKELY(ms_eglDisplay == EGL_NO_DISPLAY)) { - checkEGLError("eglGetDisplay"); - qFatal("QQnxGLContext: failed to obtain EGL display"); - } + if (Q_UNLIKELY(ms_eglDisplay == EGL_NO_DISPLAY)) + qFatal("QQnxGLContext: failed to obtain EGL display: %x", eglGetError()); EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) { - checkEGLError("eglInitialize"); + if (Q_UNLIKELY(eglResult != EGL_TRUE)) qFatal("QQnxGLContext: failed to initialize EGL display, err=%d", eglGetError()); - } } void QQnxGLContext::shutdownContext() @@ -198,98 +90,32 @@ void QQnxGLContext::shutdownContext() eglTerminate(ms_eglDisplay); } -bool QQnxGLContext::makeCurrent(QPlatformSurface *surface) +EGLSurface QQnxGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - qGLContextDebug(); - - Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface); - - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQnxGLContext: failed to set EGL API, err=%d", eglGetError()); - - QQnxEglWindow *platformWindow = dynamic_cast(surface); - if (!platformWindow) - return false; - - platformWindow->setPlatformOpenGLContext(this); - - if (m_currentEglSurface == EGL_NO_SURFACE || m_currentEglSurface != platformWindow->getSurface()) { - m_currentEglSurface = platformWindow->getSurface(); - doneCurrent(); - } - - eglResult = eglMakeCurrent(ms_eglDisplay, m_currentEglSurface, m_currentEglSurface, m_eglContext); - if (eglResult != EGL_TRUE) { - checkEGLError("eglMakeCurrent"); - qWarning("QQNX: failed to set current EGL context, err=%d", eglGetError()); - return false; - } - return (eglResult == EGL_TRUE); + QQnxEglWindow *window = static_cast(surface); + window->ensureInitialized(this); + return window->surface(); } -void QQnxGLContext::doneCurrent() +bool QQnxGLContext::makeCurrent(QPlatformSurface *surface) { qGLContextDebug(); - - // set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); - - // clear curent EGL context and unbind EGL surface - eglResult = eglMakeCurrent(ms_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQNX: failed to clear current EGL context, err=%d", eglGetError()); + return QEGLPlatformContext::makeCurrent(surface); } void QQnxGLContext::swapBuffers(QPlatformSurface *surface) { qGLContextDebug(); - QQnxEglWindow *platformWindow = dynamic_cast(surface); - if (!platformWindow) - return; - - platformWindow->swapEGLBuffers(); -} -QFunctionPointer QQnxGLContext::getProcAddress(const char *procName) -{ - qGLContextDebug(); + QEGLPlatformContext::swapBuffers(surface); - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (Q_UNLIKELY(eglResult != EGL_TRUE)) - qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); - - // Lookup EGL extension function pointer - QFunctionPointer result = static_cast(eglGetProcAddress(procName)); - if (!result) - result = reinterpret_cast(dlsym(RTLD_DEFAULT, procName)); - return result; -} - -bool QQnxGLContext::isSharing() const -{ - return m_eglShareContext != EGL_NO_CONTEXT; -} - -EGLDisplay QQnxGLContext::getEglDisplay() { - return ms_eglDisplay; + QQnxEglWindow *platformWindow = static_cast(surface); + platformWindow->windowPosted(); } -EGLint *QQnxGLContext::contextAttrs(const QSurfaceFormat &format) +void QQnxGLContext::doneCurrent() { - qGLContextDebug(); - - // Choose EGL settings based on OpenGL version -#if defined(QT_OPENGL_ES_2) - static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, format.version().first, EGL_NONE }; - return attrs; -#else - return 0; -#endif + QEGLPlatformContext::doneCurrent(); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h index 6e5408e8bf..19179a80e2 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.h +++ b/src/plugins/platforms/qnx/qqnxglcontext.h @@ -46,49 +46,31 @@ #include #include +#include QT_BEGIN_NAMESPACE class QQnxWindow; -class QQnxGLContext : public QPlatformOpenGLContext +class QQnxGLContext : public QEGLPlatformContext { public: - QQnxGLContext(QOpenGLContext *glContext); + QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share); virtual ~QQnxGLContext(); - static EGLenum checkEGLError(const char *msg); - static void initializeContext(); static void shutdownContext(); - void requestSurfaceChange(); - bool makeCurrent(QPlatformSurface *surface) override; - void doneCurrent() override; void swapBuffers(QPlatformSurface *surface) override; - QFunctionPointer getProcAddress(const char *procName) override; - - virtual QSurfaceFormat format() const override { return m_windowFormat; } - bool isSharing() const override; + void doneCurrent() override; - static EGLDisplay getEglDisplay(); - EGLConfig getEglConfig() const { return m_eglConfig;} - EGLContext getEglContext() const { return m_eglContext; } +protected: + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override; private: //Can be static because different displays returne the same handle static EGLDisplay ms_eglDisplay; - - QSurfaceFormat m_windowFormat; - QOpenGLContext *m_glContext; - - EGLConfig m_eglConfig; - EGLContext m_eglContext; - EGLContext m_eglShareContext; - EGLSurface m_currentEglSurface; - - static EGLint *contextAttrs(const QSurfaceFormat &format); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 072510e052..bffe7ee34b 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -313,7 +313,58 @@ QPlatformBackingStore *QQnxIntegration::createPlatformBackingStore(QWindow *wind QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { qIntegrationDebug(); - return new QQnxGLContext(context); + + // Get color channel sizes from window format + QSurfaceFormat format = context->format(); + int alphaSize = format.alphaBufferSize(); + int redSize = format.redBufferSize(); + int greenSize = format.greenBufferSize(); + int blueSize = format.blueBufferSize(); + + // Check if all channels are don't care + if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) { + // Set color channels based on depth of window's screen + QQnxScreen *screen = static_cast(context->screen()->handle()); + int depth = screen->depth(); + if (depth == 32) { + // SCREEN_FORMAT_RGBA8888 + alphaSize = 8; + redSize = 8; + greenSize = 8; + blueSize = 8; + } else { + // SCREEN_FORMAT_RGB565 + alphaSize = 0; + redSize = 5; + greenSize = 6; + blueSize = 5; + } + } else { + // Choose best match based on supported pixel formats + if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) { + // SCREEN_FORMAT_RGB565 + alphaSize = 0; + redSize = 5; + greenSize = 6; + blueSize = 5; + } else { + // SCREEN_FORMAT_RGBA8888 + alphaSize = 8; + redSize = 8; + greenSize = 8; + blueSize = 8; + } + } + + // Update color channel sizes in window format + format.setAlphaBufferSize(alphaSize); + format.setRedBufferSize(redSize); + format.setGreenBufferSize(greenSize); + format.setBlueBufferSize(blueSize); + context->setFormat(format); + + QQnxGLContext *ctx = new QQnxGLContext(context->format(), context->shareHandle()); + return ctx; } #endif diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index 468fe9cd91..3eebb9c742 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -98,7 +98,7 @@ void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resour void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { if (resource == "eglcontext" && context) - return static_cast(context->handle())->getEglContext(); + return static_cast(context->handle())->eglContext(); return 0; } diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index 8a498434aa..a6d5623d04 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -49,10 +49,14 @@ #include -// For pre-7.0 SDPs, map some screen property names to the old +#if !defined(_SCREEN_VERSION) +#define _SCREEN_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch)) +#define _SCREEN_VERSION _SCREEN_MAKE_VERSION(0, 0, 0) +#endif + +// For pre-1.0.0 screen, map some screen property names to the old // names. -#include -#if _NTO_VERSION < 700 +#if _SCREEN_VERSION < _SCREEN_MAKE_VERSION(1, 0, 0) const int SCREEN_PROPERTY_FLAGS = SCREEN_PROPERTY_KEY_FLAGS; const int SCREEN_PROPERTY_FOCUS = SCREEN_PROPERTY_KEYBOARD_FOCUS; const int SCREEN_PROPERTY_MODIFIERS = SCREEN_PROPERTY_KEY_MODIFIERS; diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index e248e04462..223ea6e349 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -112,12 +112,13 @@ public: bool shouldMakeFullScreen() const; + void windowPosted(); + protected: virtual int pixelFormat() const = 0; virtual void resetBuffers() = 0; void initWindow(); - void windowPosted(); screen_context_t m_screenContext; -- cgit v1.2.3 From af18215a955040b7a56a2eb9281ba57dcb459f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Mon, 12 Feb 2018 13:36:45 +0200 Subject: Fix build failure when QtNetwork module is not build Affected plugins: tuiotouch, vnc Change-Id: Iabf72e3da0a25de0de2a861c69a29b3887ca81c3 Reviewed-by: Jesus Fernandez --- src/plugins/generic/generic.pro | 2 +- src/plugins/platforms/platforms.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro index e323f32d2c..70e433f89d 100644 --- a/src/plugins/generic/generic.pro +++ b/src/plugins/generic/generic.pro @@ -11,7 +11,7 @@ qtConfig(tslib) { SUBDIRS += tslib } -qtConfig(udpsocket) { +qtHaveModule(network):qtConfig(udpsocket) { SUBDIRS += tuiotouch } diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 9414f01ef0..e61887618f 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -36,7 +36,7 @@ qtConfig(directfb) { qtConfig(linuxfb): SUBDIRS += linuxfb -qtConfig(vnc): SUBDIRS += vnc +qtHaveModule(network):qtConfig(vnc): SUBDIRS += vnc freebsd { SUBDIRS += bsdfb -- cgit v1.2.3