summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-02-23 09:27:52 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-02-23 09:27:52 +0100
commitefb46ea7ccf6fe8f89a8228bb5afe34c51901824 (patch)
treeea83ffeb690c735cbf2a9508e56a20ce2378fcc9 /src
parentcdc30acbdebdfb185df0a871537dd22411eae4f4 (diff)
parent5cfd5fd9d7ece7e1eb3c4d2be8ec342b376acf38 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml3
-rw-r--r--src/gui/kernel/qplatformintegration.cpp9
-rw-r--r--src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp2
-rw-r--r--src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm29
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp70
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h9
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3menu.cpp3
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp16
-rw-r--r--src/testlib/3rdparty/qt_attribution.json6
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