diff --git a/configure.json b/configure.json index e6d054d64a..62cebbe8c1 100644 --- a/configure.json +++ b/configure.json @@ -214,8 +214,7 @@ "compile": [ "verifyspec" ], "detectPkgConfig": [ "cross_compile", "machineTuple" ], "library": [ "pkg-config" ], - "getPkgConfigVariable": [ "pkg-config" ], - "subarch": [ "architecture" ] + "getPkgConfigVariable": [ "pkg-config" ] }, "testTypeAliases": { @@ -451,21 +450,6 @@ "type": "x86SimdAlways", "test": "x86_simd" }, - "mips_dsp": { - "label": "MIPS DSP instructions", - "type": "subarch", - "subarch": "dsp" - }, - "mips_dspr2": { - "label": "MIPS DSPr2 instructions", - "type": "subarch", - "subarch": "dspr2" - }, - "neon": { - "label": "NEON instructions", - "type": "subarch", - "subarch": "neon" - }, "posix_fallocate": { "label": "POSIX fallocate()", "type": "compile", @@ -1015,7 +999,7 @@ }, "mips_dsp": { "label": "DSP", - "condition": "arch.mips && tests.mips_dsp", + "condition": "arch.mips && subarch.dsp", "output": [ "privateConfig", { "type": "define", "name": "QT_COMPILER_SUPPORTS_MIPS_DSP", "value": 1 } @@ -1023,7 +1007,7 @@ }, "mips_dspr2": { "label": "DSPr2", - "condition": "arch.mips && tests.mips_dspr2", + "condition": "arch.mips && subarch.dspr2", "output": [ "privateConfig", { "type": "define", "name": "QT_COMPILER_SUPPORTS_MIPS_DSPR2", "value": 1 } @@ -1031,7 +1015,7 @@ }, "neon": { "label": "NEON", - "condition": "(arch.arm || arch.arm64) && tests.neon", + "condition": "(arch.arm || arch.arm64) && subarch.neon", "output": [ "privateConfig", { "type": "define", "name": "QT_COMPILER_SUPPORTS_NEON", "value": 1 } diff --git a/configure.pri b/configure.pri index a67860fba0..7185647e44 100644 --- a/configure.pri +++ b/configure.pri @@ -366,12 +366,6 @@ defineTest(qtConfTest_detectPkgConfig) { return(true) } -defineTest(qtConfTest_subarch) { - subarch = $$eval($${1}.subarch) - contains($${currentConfig}.tests.architecture.subarch, $${subarch}): return(true) - return(false) -} - defineTest(qtConfTest_buildParts) { parts = $$config.input.make isEmpty(parts) { @@ -914,6 +908,7 @@ defineTest(qtConfOutput_sanitizer) { defineTest(qtConfOutput_architecture) { arch = $$qtConfEvaluate("tests.architecture.arch") + subarch = $$qtConfEvaluate('tests.architecture.subarch') buildabi = $$qtConfEvaluate("tests.architecture.buildabi") $$qtConfEvaluate("features.cross_compile") { @@ -924,7 +919,7 @@ defineTest(qtConfOutput_architecture) { "host_build {" \ " QT_CPU_FEATURES.$$host_arch = $$qtConfEvaluate('tests.host_architecture.subarch')" \ "} else {" \ - " QT_CPU_FEATURES.$$arch = $$qtConfEvaluate('tests.architecture.subarch')" \ + " QT_CPU_FEATURES.$$arch = $$subarch" \ "}" publicPro = \ "host_build {" \ @@ -939,7 +934,7 @@ defineTest(qtConfOutput_architecture) { } else { privatePro = \ - "QT_CPU_FEATURES.$$arch = $$qtConfEvaluate('tests.architecture.subarch')" + "QT_CPU_FEATURES.$$arch = $$subarch" publicPro = \ "QT_ARCH = $$arch" \ "QT_BUILDABI = $$buildabi" @@ -950,9 +945,11 @@ defineTest(qtConfOutput_architecture) { $${currentConfig}.output.privatePro += $$privatePro export($${currentConfig}.output.privatePro) - # setup QT_ARCH variable used by qtConfEvaluate + # setup QT_ARCH and QT_CPU_FEATURES variables used by qtConfEvaluate QT_ARCH = $$arch export(QT_ARCH) + QT_CPU_FEATURES.$$arch = $$subarch + export(QT_CPU_FEATURES.$$arch) } defineTest(qtConfOutput_qreal) { diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index d5dcda22ac..98fff59ea1 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1270,6 +1270,12 @@ defineReplace(qtConfEvaluateSingleExpression) { isEmpty(QT_ARCH): \ qtConfCheckFeature(architecture) contains(QT_ARCH, $$var): result = true + } else: contains(e, "^subarch\..*") { + var = $$replace(e, "^subarch\.", "") + result = false + isEmpty(QT_ARCH): \ + qtConfCheckFeature(architecture) + contains(QT_CPU_FEATURES.$$QT_ARCH, $$var): result = true } else: contains(e, "^input\..*") { result = $$eval(config.$$e) } else: contains(e, "^var\..*") { diff --git a/mkspecs/win32-clang-msvc/qmake.conf b/mkspecs/win32-clang-msvc/qmake.conf index 0041788ef9..ba9704e069 100644 --- a/mkspecs/win32-clang-msvc/qmake.conf +++ b/mkspecs/win32-clang-msvc/qmake.conf @@ -12,7 +12,8 @@ QMAKE_CC = clang-cl QMAKE_CXX = $$QMAKE_CC QMAKE_CFLAGS += -Wno-microsoft-enum-value -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS + +QMAKE_CXXFLAGS += -Wno-microsoft-enum-value # Precompiled headers are not supported yet by clang CONFIG -= precompile_header diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 9c289a05f9..ed131c6823 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -16,7 +16,7 @@ QMAKE_CFLAGS += -fno-keep-inline-dllexport QMAKE_CFLAGS_WARN_ON += -Wextra QMAKE_CXX = $${CROSS_COMPILE}g++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS +QMAKE_CXXFLAGS += -fno-keep-inline-dllexport QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON QMAKE_LINK = $${CROSS_COMPILE}g++ diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index 6acb07f8aa..3cb0d58824 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -16,9 +16,9 @@ QMAKE_COMPILER += intel_icl QMAKE_CFLAGS_OPTIMIZE_FULL = -O3 QMAKE_CC = icl -QMAKE_CFLAGS = -nologo -Zc:wchar_t -Qprec -Zm200 -Qdiag-disable:1744,1738,809,3373 -QMAKE_CFLAGS_WARN_ON = -W3 -Qdiag-disable:673 -QMAKE_CFLAGS_WARN_OFF = -W0 -Qdiag-disable:673 +QMAKE_CFLAGS += -Qprec -Zm200 +QMAKE_CFLAGS_WARN_ON = -W3 -Qdiag-disable:673,809,1738,1744,3373 +QMAKE_CFLAGS_WARN_OFF = -W0 QMAKE_CFLAGS_DEBUG = $$QMAKE_CFLAGS_OPTIMIZE_DEBUG -Zi -MDd QMAKE_CFLAGS_UTF8_SOURCE = -Qoption,cpp,--unicode_source_kind,UTF-8 QMAKE_CFLAGS_LTCG = -Qipo @@ -43,7 +43,7 @@ QMAKE_CFLAGS_AESNI = -QxSSE2 QMAKE_CFLAGS_SHANI = -QxSSE4.2 QMAKE_CXX = $$QMAKE_CC -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS /Zc:forScope +QMAKE_CXXFLAGS += -Qprec -Zm200 -Zc:forScope QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF QMAKE_CXXFLAGS_CXX11 = -Qstd=c++11 diff --git a/mkspecs/win32-msvc/qmake.conf b/mkspecs/win32-msvc/qmake.conf index 5c38330add..08f085127a 100644 --- a/mkspecs/win32-msvc/qmake.conf +++ b/mkspecs/win32-msvc/qmake.conf @@ -5,4 +5,9 @@ # include(../common/msvc-desktop.conf) + +QMAKE_CFLAGS += + +QMAKE_CXXFLAGS += + load(qt_config) diff --git a/src/3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml b/src/3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml index 1cbd78a9c3..cf043748f6 100644 --- a/src/3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml +++ b/src/3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml @@ -85,6 +85,9 @@ + + + diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 448d670209..866ce08a28 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -446,12 +446,13 @@ Qt::KeyboardModifiers QPlatformIntegration::queryKeyboardModifiers() const /*! Should be used to obtain a list of possible shortcuts for the given key - event. As that needs system functionality it cannot be done in qkeymapper. + event. Shortcuts should be encoded as int(Qt::Key + Qt::KeyboardModifiers). - One example for more than 1 possibility is the key combination of Shift+5. + One example for more than one possibility is the key combination of Shift+5. That one might trigger a shortcut which is set as "Shift+5" as well as one - using %. These combinations depend on the currently set keyboard layout - which cannot be obtained by Qt functionality. + using %. These combinations depend on the currently set keyboard layout. + + \note This function should be called only from key event handlers. */ QList QPlatformIntegration::possibleKeys(const QKeyEvent *) const { diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp index 8480c15fb7..2153924ec8 100644 --- a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp @@ -126,6 +126,7 @@ QDBusTrayIcon::QDBusTrayIcon() connect(this, SIGNAL(tooltipChanged()), m_adaptor, SIGNAL(NewToolTip())); connect(this, SIGNAL(iconChanged()), m_adaptor, SIGNAL(NewIcon())); connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewAttentionIcon())); + connect(this, SIGNAL(menuChanged()), m_adaptor, SIGNAL(NewMenu())); connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewTitle())); connect(&m_attentionTimer, SIGNAL(timeout()), this, SLOT(attentionTimerExpired())); m_attentionTimer.setSingleShot(true); @@ -268,6 +269,7 @@ void QDBusTrayIcon::updateMenu(QPlatformMenu * menu) connect(m_menu, SIGNAL(updated(uint,int)), m_menuAdaptor, SIGNAL(LayoutUpdated(uint,int))); dBusConnection()->registerTrayIconMenu(this); + emit menuChanged(); } } diff --git a/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h index 3f8fca7ac0..f2bb156b1d 100644 --- a/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h +++ b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h @@ -129,6 +129,7 @@ class QStatusNotifierItemAdaptor: public QDBusAbstractAdaptor " \n" " \n" " \n" +" \n" " \n" " \n" " \n" @@ -191,6 +192,7 @@ Q_SIGNALS: // SIGNALS void NewAttentionIcon(); void NewIcon(); void NewOverlayIcon(); + void NewMenu(); void NewStatus(const QString &status); void NewTitle(); void NewToolTip(); diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 049cecff54..c963f33270 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -233,25 +233,28 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height windowSize.setHeight(windowRect.height()); } - QPixmap windowPixmap(windowSize * devicePixelRatio()); + const qreal dpr = devicePixelRatio(); + QPixmap windowPixmap(windowSize * dpr); windowPixmap.fill(Qt::transparent); for (uint i = 0; i < displayCount; ++i) { const CGRect bounds = CGDisplayBounds(displays[i]); - int w = (width < 0 ? bounds.size.width : width) * devicePixelRatio(); - int h = (height < 0 ? bounds.size.height : height) * devicePixelRatio(); - QRect displayRect = QRect(x, y, w, h); - displayRect = displayRect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y)); - QCFType image = CGDisplayCreateImageForRect(displays[i], - CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height())); - QPixmap pix(w, h); - pix.fill(Qt::transparent); - CGRect rect = CGRectMake(0, 0, w, h); - QMacCGContext ctx(&pix); - qt_mac_drawCGImage(ctx, &rect, image); + // Calculate the position and size of the requested area + QPoint pos(qAbs(bounds.origin.x - x), qAbs(bounds.origin.y - y)); + QSize size(qMin(pos.x() + width, qRound(bounds.size.width)), + qMin(pos.y() + height, qRound(bounds.size.height))); + pos *= dpr; + size *= dpr; + + // Take the whole screen and crop it afterwards, because CGDisplayCreateImageForRect + // has a strange behavior when mixing highDPI and non-highDPI displays + QCFType cgImage = CGDisplayCreateImage(displays[i]); + const QImage image = qt_mac_toQImage(cgImage); + + // Draw into windowPixmap only the requested size QPainter painter(&windowPixmap); - painter.drawPixmap(0, 0, pix); + painter.drawImage(windowPixmap.rect(), image, QRect(pos, size)); } return windowPixmap; } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index ee25d6a12f..1e3bb69069 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -112,6 +112,7 @@ Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events") Q_LOGGING_CATEGORY(lcQpaXcb, "qt.qpa.xcb") // for general (uncategorized) XCB logging Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker") +Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard") // this event type was added in libxcb 1.10, // but we support also older version diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 0a7f878ed8..4a9958f334 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -92,6 +92,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen) Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents) Q_DECLARE_LOGGING_CATEGORY(lcQpaXcb) Q_DECLARE_LOGGING_CATEGORY(lcQpaPeeker) +Q_DECLARE_LOGGING_CATEGORY(lcQpaKeyboard) class QXcbVirtualDesktop; class QXcbScreen; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 2ed66394c9..20b5fe039a 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1267,27 +1267,32 @@ static bool isLatin(xkb_keysym_t sym) return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z')); } -void QXcbKeyboard::checkForLatinLayout() +void QXcbKeyboard::checkForLatinLayout() const { - m_hasLatinLayout = false; const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(xkb_keymap); const xcb_keycode_t minKeycode = connection()->setup()->min_keycode; const xcb_keycode_t maxKeycode = connection()->setup()->max_keycode; - struct xkb_state *kb_state = xkb_state_new(xkb_keymap); + + ScopedXKBState state(xkb_state_new(xkb_keymap)); for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) { - xkb_state_update_mask(kb_state, 0, 0, 0, 0, 0, layout); + xkb_state_update_mask(state.get(), 0, 0, 0, 0, 0, layout); for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) { - xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code); + xkb_keysym_t sym = xkb_state_key_get_one_sym(state.get(), code); // if layout can produce any of these latin letters (chosen // arbitrarily) then it must be a latin key based layout - if (sym == XK_q || sym == XK_a || sym == XK_e) { - m_hasLatinLayout = true; - xkb_state_unref(kb_state); + if (sym == XK_q || sym == XK_a || sym == XK_e) return; - } } } - xkb_state_unref(kb_state); + // This means that lookupLatinKeysym() will not find anything and latin + // key shortcuts might not work. This is a bug in the affected desktop + // environment. Usually can be solved via system settings by adding e.g. 'us' + // layout to the list of seleced layouts, or by using command line, "setxkbmap + // -layout rus,en". The position of latin key based layout in the list of the + // selected layouts is irrelevant. Properly functioning desktop environments + // handle this behind the scenes, even if no latin key based layout has been + // explicitly listed in the selected layouts. + qCWarning(lcQpaKeyboard, "no keyboard layouts with latin keys present"); } xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const @@ -1310,39 +1315,13 @@ xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const break; } } - // If user layouts don't contain any layout that results in a latin key, we query a - // key from "US" layout, this allows for latin-key-based shorcuts to work even when - // users have only one (non-latin) layout set. - // But don't do this if using keymap obtained through the core protocol, as the key - // codes may not match up with those expected by the XKB keymap. - xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); - xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); - if (sym == XKB_KEY_NoSymbol && !m_hasLatinLayout && !m_keymap_is_core) { - if (!latin_keymap) { - const struct xkb_rule_names names = { xkb_names.rules, xkb_names.model, "us", 0, 0 }; - latin_keymap = xkb_keymap_new_from_names(xkb_context, &names, (xkb_keymap_compile_flags)0); - static bool printFailure = true; - if (!latin_keymap && printFailure) { - // print message about failure to compile US keymap only once, - // no need to do this on every key press. - printFailure = false; - printKeymapError("Qt: Failed to compile US keymap, shortcut handling with " - "non-Latin keyboard layouts may not be fully functional!"); - } - } - if (latin_keymap) { - struct xkb_state *latin_state = xkb_state_new(latin_keymap); - if (latin_state) { - xkb_state_update_mask(latin_state, 0, latchedMods, lockedMods, 0, 0, 0); - sym = xkb_state_key_get_one_sym(latin_state, keycode); - xkb_state_unref(latin_state); - } else { - qWarning("QXcbKeyboard: failed to create a state for US keymap!"); - } - } - } + if (sym == XKB_KEY_NoSymbol) return sym; + + xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); + xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); + // Check for uniqueness, consider the following setup: // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active). // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+, @@ -1353,18 +1332,18 @@ xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const // generate the same shortcut event in this case. const xcb_keycode_t minKeycode = connection()->setup()->min_keycode; const xcb_keycode_t maxKeycode = connection()->setup()->max_keycode; - struct xkb_state *kb_state = xkb_state_new(xkb_keymap); + ScopedXKBState state(xkb_state_new(xkb_keymap)); for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) { - xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, prevLayout); + xkb_state_update_mask(state.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout); for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) { - xkb_keysym_t prevSym = xkb_state_key_get_one_sym(kb_state, code); + xkb_keysym_t prevSym = xkb_state_key_get_one_sym(state.get(), code); if (prevSym == sym) { sym = XKB_KEY_NoSymbol; break; } } } - xkb_state_unref(kb_state); + return sym; } @@ -1563,7 +1542,6 @@ QXcbKeyboard::~QXcbKeyboard() xkb_state_unref(xkb_state); xkb_keymap_unref(xkb_keymap); xkb_context_unref(xkb_context); - xkb_keymap_unref(latin_keymap); if (!connection()->hasXKB()) xcb_key_symbols_free(m_key_symbols); clearXKBConfig(); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 7ee8e9e90d..5cb91ed315 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -106,7 +106,7 @@ protected: void updateVModToRModMapping(); xkb_keysym_t lookupLatinKeysym(xkb_keycode_t keycode) const; - void checkForLatinLayout(); + void checkForLatinLayout() const; private: void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state); @@ -119,7 +119,6 @@ private: struct xkb_keymap *xkb_keymap = nullptr; struct xkb_state *xkb_state = nullptr; struct xkb_rule_names xkb_names; - mutable struct xkb_keymap *latin_keymap = nullptr; struct _mod_masks { uint alt; @@ -149,7 +148,11 @@ private: _mod_masks vmod_masks; int core_device_id; #endif - bool m_hasLatinLayout = false; + + struct XKBStateDeleter { + void operator()(struct xkb_state *state) const { return xkb_state_unref(state); } + }; + using ScopedXKBState = std::unique_ptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp index ec4ff68e8d..1bbd463119 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp @@ -411,6 +411,9 @@ static void qt_gtk_menu_position_func(GtkMenu *, gint *x, gint *y, gboolean *pus { QGtk3Menu *menu = static_cast(data); QPoint targetPos = menu->targetPos(); +#if GTK_CHECK_VERSION(3, 10, 0) + targetPos /= gtk_widget_get_scale_factor(menu->handle()); +#endif *x = targetPos.x(); *y = targetPos.y(); *push_in = true; diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index 368b777ca5..f67c78b2bb 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -817,19 +817,21 @@ QSqlRecord QPSQLResult::record() const else f.setName(QString::fromLocal8Bit(PQfname(d->result, i))); const int tableOid = PQftable(d->result, i); - auto &tableName = d->drv_d_func()->oidToTable[tableOid]; // WARNING: We cannot execute any other SQL queries on // the same db connection while forward-only mode is active // (this would discard all results of forward-only query). // So we just skip this... - if (tableName.isEmpty() && !isForwardOnly()) { - QSqlQuery qry(driver()->createResult()); - if (qry.exec(QStringLiteral("SELECT relname FROM pg_class WHERE pg_class.oid = %1") - .arg(tableOid)) && qry.next()) { - tableName = qry.value(0).toString(); + if (tableOid != InvalidOid && !isForwardOnly()) { + auto &tableName = d->drv_d_func()->oidToTable[tableOid]; + if (tableName.isEmpty()) { + QSqlQuery qry(driver()->createResult()); + if (qry.exec(QStringLiteral("SELECT relname FROM pg_class WHERE pg_class.oid = %1") + .arg(tableOid)) && qry.next()) { + tableName = qry.value(0).toString(); + } } + f.setTableName(tableName); } - f.setTableName(tableName); int ptype = PQftype(d->result, i); f.setType(qDecodePSQLType(ptype)); int len = PQfsize(d->result, i); diff --git a/src/testlib/3rdparty/qt_attribution.json b/src/testlib/3rdparty/qt_attribution.json index 49d12580bd..47625634e5 100644 --- a/src/testlib/3rdparty/qt_attribution.json +++ b/src/testlib/3rdparty/qt_attribution.json @@ -32,12 +32,12 @@ Copyright (c) 2003, 2006 Massachusetts Institute of Technology" "Id": "linuxperf", "Name": "Linux Performance Events", "QDocModule": "qttestlib", - "QtUsage": "Used on Linux and Android in the Qt Test module.", + "QtUsage": "Used on Linux and Android in the Qt Test module. Note that this is a copy of the respective Linux header, and the clarifications of the Linux Syscall Note apply.", "Files": "linux_perf_event_p.h", "Description": "Allows access to the Linux kernel's performance events.", - "License": "GNU General Public License v2.0 only", - "LicenseId": "GPL-2.0", + "License": "GNU General Public License v2.0 only with Linux Syscall Note", + "LicenseId": "GPL-2.0 WITH Linux-syscall-note", "LicenseFile": "LINUX_LICENSE.txt", "Copyright": "Copyright (C) 2008-2009, Thomas Gleixner Copyright (C) 2008-2011, Red Hat, Inc., Ingo Molnar diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 7ffc2797cc..0b691ada83 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -21,8 +21,9 @@ windows # QTBUG-66247 [ioHttpRedirect] windows +# QTBUG-66602 [ioHttpRedirectMultipartPost] -linux +* [ioHttpRedirectPolicy] b2qt 64bit linux diff --git a/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp b/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp index 465dabca0e..8d7e70f8c9 100644 --- a/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp +++ b/tests/benchmarks/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp @@ -50,6 +50,10 @@ public slots: private slots: void benchmarkRecord_data() { generic_data(); } void benchmarkRecord(); + void benchFieldName_data() { generic_data(); } + void benchFieldName(); + void benchFieldIndex_data() { generic_data(); } + void benchFieldIndex(); private: void generic_data(const QString &engine = QString()); @@ -188,4 +192,33 @@ void tst_QSqlRecord::benchmarkRecord() tst_Databases::safeDropTables(db, QStringList() << tableName); } +void tst_QSqlRecord::benchFieldName() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) { + QSqlQuery qry(db); + QVERIFY_SQL(qry, exec("SELECT GENERATE_SERIES(1,5000) AS r")); + QBENCHMARK { + while (qry.next()) + qry.value("r"); + } + } +} + +void tst_QSqlRecord::benchFieldIndex() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + if (tst_Databases::getDatabaseType(db) == QSqlDriver::PostgreSQL) { + QSqlQuery qry(db); + QVERIFY_SQL(qry, exec("SELECT GENERATE_SERIES(1,5000) AS r")); + qry = db.exec("SELECT GENERATE_SERIES(1,5000) AS r"); + QBENCHMARK { + while (qry.next()) + qry.value(0); + } + } +} + #include "tst_qsqlrecord.moc" diff --git a/tests/manual/filetest/main.cpp b/tests/manual/filetest/main.cpp index c278fd87ce..22c74af327 100644 --- a/tests/manual/filetest/main.cpp +++ b/tests/manual/filetest/main.cpp @@ -94,7 +94,7 @@ static inline std::string permissions(const QFileInfo &fi) return result; } -static int ls(int argCount, char **args) +static int ls(int argCount, const char **args, bool recursive = false) { for (int i = 0 ; i < argCount; ++i) { const QFileInfo fi(QString::fromLocal8Bit(args[i])); @@ -112,6 +112,16 @@ static int ls(int argCount, char **args) std::cout << " [dir]"; std::cout << std::endl; + + if (recursive && fi.isDir()) { + QDir dir(fi.fileName()); + const QStringList entries = dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot); + for (const QString &s : entries) { + QByteArray encoded = QFile::encodeName(s); + const char *ptr = encoded.constData(); + ls(1, &ptr, false); + } + } } return 0; } @@ -205,7 +215,7 @@ int main(int argc, char *argv[]) QCoreApplication a(argc, argv); Q_UNUSED(a) if (argc >= 3 && !qstrcmp(argv[1], "ls")) - return ls(argc -2, argv + 2); + return ls(argc -2, const_cast(argv + 2), true); if (argc >= 3 && !qstrcmp(argv[1], "stat")) return stat(argc -2, argv + 2); diff --git a/tests/manual/shortcuts/main.cpp b/tests/manual/shortcuts/main.cpp index 55ade1040a..849f8728b3 100644 --- a/tests/manual/shortcuts/main.cpp +++ b/tests/manual/shortcuts/main.cpp @@ -31,106 +31,202 @@ #include #include #include +#include class ShortcutTester : public QWidget { public: ShortcutTester() { setupLayout(); - setFixedWidth(200); } protected: void setupLayout() { QVBoxLayout *layout = new QVBoxLayout(this); - - QKeySequence sq1(Qt::AltModifier + Qt::ShiftModifier + Qt::Key_G); - QPushButton *b1 = new QPushButton(sq1.toString()); - b1->setShortcut(sq1); - - QKeySequence sq2(Qt::AltModifier + Qt::Key_G); - QPushButton *b2 = new QPushButton(sq2.toString()); - b2->setShortcut(sq2); - - QKeySequence sq3(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_R); - QPushButton *b3 = new QPushButton(sq3.toString()); - b3->setShortcut(sq3); - - QKeySequence sq4(Qt::ControlModifier + Qt::Key_R); - QPushButton *b4 = new QPushButton(sq4.toString()); - b4->setShortcut(sq4); - - QKeySequence sq5(Qt::ControlModifier + Qt::Key_Return); - QPushButton *b5 = new QPushButton(sq5.toString()); - b5->setShortcut(sq5); - - QKeySequence sq6(Qt::ControlModifier + Qt::ShiftModifier + Qt::AltModifier + Qt::Key_R); - QPushButton *b6 = new QPushButton(sq6.toString()); - b6->setShortcut(sq6); - - QKeySequence sq7(Qt::ShiftModifier + Qt::Key_5); - QPushButton *b7 = new QPushButton(sq7.toString()); - b7->setShortcut(sq7); - - QKeySequence sq8(Qt::ControlModifier + Qt::Key_Q); - QPushButton *b8 = new QPushButton(sq8.toString()); - b8->setShortcut(sq8); - - QKeySequence sq9(Qt::ControlModifier + Qt::Key_Plus); - QPushButton *b9 = new QPushButton(sq9.toString()); - b9->setShortcut(sq9); - - QKeySequence sq10(Qt::ControlModifier + Qt::Key_Y); - QPushButton *b10 = new QPushButton(sq10.toString()); - b10->setShortcut(sq10); - - QKeySequence sq11(Qt::ShiftModifier + Qt::Key_Comma); - QPushButton *b11 = new QPushButton(sq11.toString()); - b11->setShortcut(sq11); - - QKeySequence sq12(Qt::ControlModifier + Qt::Key_Slash); - QPushButton *b12 = new QPushButton(sq12.toString()); - b12->setShortcut(sq12); - - QKeySequence sq13(Qt::ControlModifier + Qt::Key_BracketRight); - QPushButton *b13 = new QPushButton(sq13.toString()); - b13->setShortcut(sq13); - - // LATIN SMALL LETTER O WITH STROKE - QKeySequence sq14(QString(QChar(ushort(0xf8)))); - QPushButton *b14 = new QPushButton(sq14.toString()); - b14->setShortcut(sq14); - - // CYRILLIC SMALL LETTER ZHE - QKeySequence sq15(QString(QChar(ushort(0x436)))); - QPushButton *b15 = new QPushButton(sq15.toString()); - b15->setShortcut(sq15); + setLayout(layout); QLabel *testPurpose = new QLabel(); testPurpose->setWordWrap(true); testPurpose->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding); - testPurpose->setText("This test come in handy to verify shortcuts under different" - " keyboard layouts - qwerty, dvorak, non-latin (russian, arabic), etc."); + testPurpose->setText("This test come in handy to verify shortcuts under different " + "keyboard layouts - qwerty, dvorak, non-latin (russian, arabic), etc."); layout->addWidget(testPurpose); - layout->addWidget(b1); - layout->addWidget(b2); - layout->addWidget(b3); - layout->addWidget(b4); - layout->addWidget(b5); - layout->addWidget(b6); - layout->addWidget(b7); - layout->addWidget(b8); - layout->addWidget(b9); - layout->addWidget(b10); - layout->addWidget(b11); - layout->addWidget(b12); - layout->addWidget(b13); - layout->addWidget(new QLabel("Norwegian layout")); - layout->addWidget(b14); - layout->addWidget(new QLabel("Russian layout")); - layout->addWidget(b15); - setLayout(layout); + QKeySequence altShiftG(Qt::AltModifier + Qt::ShiftModifier + Qt::Key_G); + QPushButton *_altShiftG = new QPushButton(altShiftG.toString()); + _altShiftG->setShortcut(altShiftG); + layout->addWidget(_altShiftG); + + QKeySequence altG(Qt::AltModifier + Qt::Key_G); + QPushButton *_altG = new QPushButton(altG.toString()); + _altG->setShortcut(altG); + layout->addWidget(_altG); + + QKeySequence ctrlShiftR(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_R); + QPushButton *_ctrlShiftR = new QPushButton(ctrlShiftR.toString()); + _ctrlShiftR->setShortcut(ctrlShiftR); + layout->addWidget(_ctrlShiftR); + + QKeySequence ctrlR(Qt::ControlModifier + Qt::Key_R); + QPushButton *_ctrlR = new QPushButton(ctrlR.toString()); + _ctrlR->setShortcut(ctrlR); + layout->addWidget(_ctrlR); + + QKeySequence ctrlReturn(Qt::ControlModifier + Qt::Key_Return); + QPushButton *_ctrlReturn = new QPushButton(ctrlReturn.toString()); + _ctrlReturn->setShortcut(ctrlReturn); + layout->addWidget(_ctrlReturn); + + QKeySequence ctrlEnter(Qt::ControlModifier + Qt::Key_Enter); + QPushButton *_ctrlEnter = new QPushButton(ctrlEnter.toString()); + _ctrlEnter->setShortcut(ctrlEnter); + layout->addWidget(_ctrlEnter); + + QKeySequence ctrlShiftAltR(Qt::ControlModifier + Qt::ShiftModifier + Qt::AltModifier + Qt::Key_R); + QPushButton *_ctrlShiftAltR = new QPushButton(ctrlShiftAltR.toString()); + _ctrlShiftAltR->setShortcut(ctrlShiftAltR); + layout->addWidget(_ctrlShiftAltR); + + QKeySequence shift5(Qt::ShiftModifier + Qt::Key_5); + QPushButton *_shift5 = new QPushButton(shift5.toString()); + _shift5->setShortcut(shift5); + layout->addWidget(_shift5); + + QKeySequence shiftPercent(Qt::ShiftModifier + Qt::Key_Percent); + QPushButton *_shiftPercent = new QPushButton(shiftPercent.toString()); + _shiftPercent->setShortcut(shiftPercent); + layout->addWidget(_shiftPercent); + + QKeySequence percent(Qt::Key_Percent); + QPushButton *_percent = new QPushButton(percent.toString()); + _percent->setShortcut(percent); + layout->addWidget(_percent); + + QKeySequence key5(Qt::Key_5); + QPushButton *_key5 = new QPushButton(key5.toString()); + _key5->setShortcut(key5); + layout->addWidget(_key5); + + QKeySequence keyQ(Qt::Key_Q); + QPushButton *_keyQ = new QPushButton(keyQ.toString()); + _keyQ->setShortcut(keyQ); + layout->addWidget(_keyQ); + + QKeySequence ctrlPercent(Qt::ControlModifier + Qt::Key_Percent); + QPushButton *_ctrlPercent = new QPushButton(ctrlPercent.toString()); + _ctrlPercent->setShortcut(ctrlPercent); + layout->addWidget(_ctrlPercent); + + QKeySequence ctrlShift5(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_5); + QPushButton *_ctrlShift5 = new QPushButton(ctrlShift5.toString()); + _ctrlShift5->setShortcut(ctrlShift5); + layout->addWidget(_ctrlShift5); + + QKeySequence ctrl5(Qt::ControlModifier + Qt::Key_5); + QPushButton *_ctrl5 = new QPushButton(ctrl5.toString()); + _ctrl5->setShortcut(ctrl5); + layout->addWidget(_ctrl5); + + QKeySequence alt5(Qt::AltModifier + Qt::Key_5); + QPushButton *_alt5 = new QPushButton(alt5.toString()); + _alt5->setShortcut(alt5); + layout->addWidget(_alt5); + + QKeySequence ctrlPlus(Qt::ControlModifier + Qt::Key_Plus); + QPushButton *_ctrlPlus = new QPushButton(ctrlPlus.toString()); + _ctrlPlus->setShortcut(ctrlPlus); + layout->addWidget(_ctrlPlus); + + QKeySequence ctrlShiftPlus(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_Plus); + QPushButton *_ctrlShiftPlus = new QPushButton(ctrlShiftPlus.toString()); + _ctrlShiftPlus->setShortcut(ctrlShiftPlus); + layout->addWidget(_ctrlShiftPlus); + + QKeySequence ctrlY(Qt::ControlModifier + Qt::Key_Y); + QPushButton *_ctrlY = new QPushButton(ctrlY.toString()); + _ctrlY->setShortcut(ctrlY); + layout->addWidget(_ctrlY); + + QKeySequence shiftComma(Qt::ShiftModifier + Qt::Key_Comma); + QPushButton *_shiftComma = new QPushButton(shiftComma.toString()); + _shiftComma->setShortcut(shiftComma); + layout->addWidget(_shiftComma); + + QKeySequence ctrlComma(Qt::ControlModifier + Qt::Key_Comma); + QPushButton *_ctrlComma = new QPushButton(ctrlComma.toString()); + _ctrlComma->setShortcut(ctrlComma); + layout->addWidget(_ctrlComma); + + QKeySequence ctrlSlash(Qt::ControlModifier + Qt::Key_Slash); + QPushButton *_ctrlSlash = new QPushButton(ctrlSlash.toString()); + _ctrlSlash->setShortcut(ctrlSlash); + layout->addWidget(_ctrlSlash); + + QKeySequence ctrlBackslash(Qt::ControlModifier + Qt::Key_Backslash); + QPushButton *_ctrlBackslash = new QPushButton(ctrlBackslash.toString()); + _ctrlBackslash->setShortcut(ctrlBackslash); + layout->addWidget(_ctrlBackslash); + + QKeySequence metaShiftA(Qt::MetaModifier + Qt::ShiftModifier + Qt::Key_A); + QPushButton *_metaShiftA = new QPushButton(metaShiftA.toString()); + _metaShiftA->setShortcut(metaShiftA); + layout->addWidget(_metaShiftA); + + QKeySequence metaShift5(Qt::MetaModifier + Qt::ShiftModifier + Qt::Key_5); + QPushButton *_metaShift5 = new QPushButton(metaShift5.toString()); + _metaShift5->setShortcut(metaShift5); + layout->addWidget(_metaShift5); + + QKeySequence ctrlBracketRigth(Qt::ControlModifier + Qt::Key_BracketRight); + QPushButton *_ctrlBracketRigth = new QPushButton(ctrlBracketRigth.toString()); + _ctrlBracketRigth->setShortcut(ctrlBracketRigth); + layout->addWidget(_ctrlBracketRigth); + + QKeySequence shiftF3(Qt::ShiftModifier + Qt::Key_F3); + QPushButton *_shiftF3 = new QPushButton(shiftF3.toString()); + _shiftF3->setShortcut(shiftF3); + layout->addWidget(_shiftF3); + + QKeySequence ctrlF3(Qt::ControlModifier + Qt::Key_F3); + QPushButton *_ctrlF3 = new QPushButton(ctrlF3.toString()); + _ctrlF3->setShortcut(ctrlF3); + layout->addWidget(_ctrlF3); + + QKeySequence euro(0x20AC); // EURO SIGN e.g. US (with euro on 5) on 3rd keyboard level + QPushButton *_euro = new QPushButton(euro.toString()); + _euro->setShortcut(euro); + layout->addWidget(_euro); + + QKeySequence ctrlEuro(Qt::ControlModifier + 0x20AC); + QPushButton *_ctrlEuro = new QPushButton(ctrlEuro.toString()); + _ctrlEuro->setShortcut(ctrlEuro); + layout->addWidget(_ctrlEuro); + + // with german (neo 2) layout on linux under ISO_Level3_Shift + ISO_Level5_Shift + I + QKeySequence greekPsi(QString(QStringLiteral("\u03A8"))); + QPushButton *_greekPsi = new QPushButton(greekPsi.toString()); + _greekPsi->setShortcut(greekPsi); + layout->addWidget(_greekPsi); + + layout->addWidget(new QLabel("Norwegian layout")); + // LATIN SMALL LETTER O WITH STROKE + QKeySequence norwegianO(QString(QStringLiteral("\u00F8"))); + QPushButton *_norwegianO = new QPushButton(norwegianO.toString()); + _norwegianO->setShortcut(norwegianO); + layout->addWidget(_norwegianO); + + layout->addWidget(new QLabel("Russian layout")); + // CYRILLIC SMALL LETTER ZHE + QKeySequence zhe(QString(QStringLiteral("\u0436"))); + QPushButton *_zhe = new QPushButton(zhe.toString()); + _zhe->setShortcut(zhe); + layout->addWidget(_zhe); + + // for sequence definitons see qplatformtheme.cpp + layout->addWidget(new QLabel("QKeySequence::StandardKey(s)")); + QPushButton *_open = new QPushButton("Open"); + _open->setShortcut(QKeySequence::Open); // Qt::CTRL | Qt::Key_O + layout->addWidget(_open); } }; @@ -138,6 +234,8 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); + qDebug() << qVersion(); + ShortcutTester tester; tester.show(); diff --git a/tests/manual/windowflags/controllerwindow.cpp b/tests/manual/windowflags/controllerwindow.cpp index 4b380d5355..6334ea588f 100644 --- a/tests/manual/windowflags/controllerwindow.cpp +++ b/tests/manual/windowflags/controllerwindow.cpp @@ -59,7 +59,7 @@ ControllerWidget::ControllerWidget(QWidget *parent) QLabel *label = new QLabel(tr("Parent window")); parentWindow->setCentralWidget(label); - previewWindow = new QWindow; + previewWindow = new PreviewWindow; previewWindow->installEventFilter(this); previewWidget = new PreviewWidget; previewWidget->installEventFilter(this); @@ -123,8 +123,8 @@ void ControllerWidget::updatePreview(QWindow *preview) preview->setFlags(flags); if (fixedSizeWindowCheckBox->isChecked()) { - preview->setMinimumSize(QSize(300, 300)); - preview->setMaximumSize(QSize(300, 300)); + preview->setMinimumSize(preview->size()); + preview->setMaximumSize(preview->size()); } else { preview->setMinimumSize(QSize(0, 0)); preview->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); @@ -153,7 +153,7 @@ void ControllerWidget::updatePreview(QWidget *preview) preview->setWindowFlags(flags); QSize fixedSize = fixedSizeWindowCheckBox->isChecked() ? - QSize(300, 300) : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + preview->size() : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); preview->setFixedSize(fixedSize); QPoint pos = preview->pos(); diff --git a/tests/manual/windowflags/previewwindow.cpp b/tests/manual/windowflags/previewwindow.cpp index 19473c9eee..ef3966830b 100644 --- a/tests/manual/windowflags/previewwindow.cpp +++ b/tests/manual/windowflags/previewwindow.cpp @@ -32,9 +32,20 @@ #include #include #include +#include +#include #include "previewwindow.h" +void PreviewWindow::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + QLinearGradient gradient(0, 0, width(), height()); + gradient.setColorAt(0, QColor("#64b3f4")); + gradient.setColorAt(1, QColor("#c2e59c")); + painter.fillRect(QRect(0, 0, width(), height()), gradient); +} + static void formatWindowFlags(QTextStream &str, Qt::WindowFlags flags) { str << "Window flags: " << hex << showbase << unsigned(flags) << noshowbase << dec << ' '; diff --git a/tests/manual/windowflags/previewwindow.h b/tests/manual/windowflags/previewwindow.h index 023ddd910c..8f8fc39211 100644 --- a/tests/manual/windowflags/previewwindow.h +++ b/tests/manual/windowflags/previewwindow.h @@ -30,11 +30,17 @@ #define PREVIEWWINDOW_H #include +#include QT_BEGIN_NAMESPACE class QPlainTextEdit; QT_END_NAMESPACE +class PreviewWindow : public QRasterWindow +{ + void paintEvent(QPaintEvent *event); +}; + class PreviewWidget : public QWidget { Q_OBJECT