diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-02-23 09:27:52 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-02-23 09:27:52 +0100 |
commit | efb46ea7ccf6fe8f89a8228bb5afe34c51901824 (patch) | |
tree | ea83ffeb690c735cbf2a9508e56a20ce2378fcc9 /src | |
parent | cdc30acbdebdfb185df0a871537dd22411eae4f4 (diff) | |
parent | 5cfd5fd9d7ece7e1eb3c4d2be8ec342b376acf38 (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I01dfc41e18333ac55954296cef8f01475adab27e
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml | 3 | ||||
-rw-r--r-- | src/gui/kernel/qplatformintegration.cpp | 9 | ||||
-rw-r--r-- | src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp | 2 | ||||
-rw-r--r-- | src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoascreen.mm | 29 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 70 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.h | 9 | ||||
-rw-r--r-- | src/plugins/platformthemes/gtk3/qgtk3menu.cpp | 3 | ||||
-rw-r--r-- | src/plugins/sqldrivers/psql/qsql_psql.cpp | 16 | ||||
-rw-r--r-- | src/testlib/3rdparty/qt_attribution.json | 6 |
12 files changed, 75 insertions, 76 deletions
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 @@ <signal name="NewOverlayIcon"> </signal> + <signal name="NewMenu"> + </signal> + <signal name="NewToolTip"> </signal> 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<int> 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 " <signal name=\"NewIcon\"/>\n" " <signal name=\"NewAttentionIcon\"/>\n" " <signal name=\"NewOverlayIcon\"/>\n" +" <signal name=\"NewMenu\"/>\n" " <signal name=\"NewToolTip\"/>\n" " <signal name=\"NewStatus\">\n" " <arg type=\"s\" name=\"status\"/>\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<CGImageRef> 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<CGImageRef> 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+<physical x key>, @@ -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<struct xkb_state, XKBStateDeleter>; }; 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<QGtk3Menu *>(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 <tglx@linutronix.de> Copyright (C) 2008-2011, Red Hat, Inc., Ingo Molnar |