From 4d84c25157b18b29cd2a42714e3b352674d28486 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Sun, 26 Oct 2014 22:26:25 +0100 Subject: Don't link to Xlib's Xrender library We don't use this library in XCB plugin. Change-Id: Ifcc2f404b3cbf5601eb094eaac923d2f9e6e981b Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/xcb-plugin.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index 9aaafadcad..f14fcde73f 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -60,7 +60,7 @@ contains(QT_CONFIG, xcb-xlib) { # to support custom cursors with depth > 1 contains(QT_CONFIG, xcb-render) { DEFINES += XCB_USE_RENDER - LIBS += -lxcb-render -lxcb-render-util -lXrender + LIBS += -lxcb-render -lxcb-render-util } # build with session management support -- cgit v1.2.3 From 2b666d9576210aa98700e219dba6b1bd4f93d793 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 23 Oct 2014 14:45:18 +0200 Subject: Fix shortcut handling with non-latin layouts Shortcut handling with non-latin keyboard layouts were broken for checks like: QKeyEvent key = ...; key == QKeySequence::SelectAll In Qt4 this was handled transparently when getting keysym from XLookupString. When ctrl modifier was set, XLookupString performed "keysym transformation" to obtain a latin keysym. Still this did not solve the non-latin shortcut issues for all cases due to some of Xlib assumptions which could not be controled by user. This patch implements XLookupString-like behavior in lookupLatinKeysym(). It is not a 1-to-1 copy of how XLookupString perfoms latin keysym lookup, but it serves our needs just fine. lookupLatinKeysym() also handles the cases that did not work in Qt4 with XLookupString, thanks to libxkbcommon keymap query API. And lookupLatinKeysym() replaces the fragile implementation of "fallback latin key" code path in possibleKeys(). Done-with: Ruslan Nigmatullin Task-number: QTBUG-33182 Task-number: QTBUG-32274 Change-Id: I56a5b624487ca6c2c3768220301a37dac39b439a Reviewed-by: Ruslan Nigmatullin Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 190 +++++++++++++++++++++-------- src/plugins/platforms/xcb/qxcbkeyboard.h | 5 + 2 files changed, 147 insertions(+), 48 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index dae3a79628..260fb46309 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -721,7 +721,7 @@ void QXcbKeyboard::updateKeymap() if (xkb_keymap) { new_state = xkb_state_new(xkb_keymap); } else { - printKeymapError("Failed to compile a keymap!"); + printKeymapError("Qt: Failed to compile a keymap!"); m_config = false; return; } @@ -737,6 +737,8 @@ void QXcbKeyboard::updateKeymap() xkb_state = new_state; if (!connection()->hasXKB()) updateXKBMods(); + + checkForLatinLayout(); } #ifndef QT_NO_XKB @@ -824,37 +826,137 @@ void QXcbKeyboard::updateXKBMods() xkb_mods.mod5 = xkb_keymap_mod_get_index(xkb_keymap, "Mod5"); } +static bool isLatin(xkb_keysym_t sym) +{ + return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z')); +} + +void QXcbKeyboard::checkForLatinLayout() +{ + 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); + for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) { + xkb_state_update_mask(kb_state, 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); + // 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); + return; + } + } + } + xkb_state_unref(kb_state); +} + +xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const +{ + xkb_layout_index_t layout; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(xkb_keymap, keycode); + const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(xkb_state, keycode); + // Look at user layouts in the order in which they are defined in system + // settings to find a latin keysym. + for (layout = 0; layout < layoutCount; ++layout) { + if (layout == currentLayout) + continue; + const xkb_keysym_t *syms; + xkb_level_index_t level = xkb_state_key_get_level(xkb_state, keycode, layout); + if (xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, layout, level, &syms) != 1) + continue; + if (isLatin(syms[0])) { + sym = syms[0]; + 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. + 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) { + 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; + // 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+, + // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained + // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired + // then the obtained key is not unique. This prevents ctrl+ from generating a ctrl+q + // shortcut in the above described setup. We don't want ctrl+ and ctrl+ to + // 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); + for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) { + xkb_state_update_mask(kb_state, 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); + if (prevSym == sym) { + sym = XKB_KEY_NoSymbol; + break; + } + } + } + xkb_state_unref(kb_state); + return sym; +} + QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const { // turn off the modifier bits which doesn't participate in shortcuts Qt::KeyboardModifiers notNeeded = Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier; Qt::KeyboardModifiers modifiers = event->modifiers() &= ~notNeeded; // create a fresh kb state and test against the relevant modifier combinations - // NOTE: it should be possible to query the keymap directly, once it gets - // supported by libxkbcommon - struct xkb_state * kb_state = xkb_state_new(xkb_keymap); + struct xkb_state *kb_state = xkb_state_new(xkb_keymap); if (!kb_state) { - qWarning("QXcbKeyboard: failed to compile xkb keymap"); + qWarning("QXcbKeyboard: failed to compile xkb keymap!"); return QList(); } // get kb state from the master xkb_state and update the temporary kb_state - xkb_layout_index_t baseLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_DEPRESSED); - xkb_layout_index_t latchedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LATCHED); xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LOCKED); 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); - xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, - baseLayout, latchedLayout, lockedLayout); + xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout); - xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, event->nativeScanCode()); + quint32 keycode = event->nativeScanCode(); + xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, keycode); if (sym == XKB_KEY_NoSymbol) { xkb_state_unref(kb_state); return QList(); } QList result; - int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode())); + int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, keycode)); result += (baseQtKey + modifiers); // The base key is _always_ valid, of course xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift"); @@ -866,48 +968,33 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const Q_ASSERT(controlMod < 32); xkb_mod_mask_t depressed; - struct xkb_keymap *fallback_keymap = 0; int qtKey = 0; - //obtain a list of possible shortcuts for the given key event + // obtain a list of possible shortcuts for the given key event for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) { Qt::KeyboardModifiers neededMods = ModsTbl[i]; if ((modifiers & neededMods) == neededMods) { - - depressed = 0; - if (neededMods & Qt::AltModifier) - depressed |= (1 << altMod); - if (neededMods & Qt::ShiftModifier) - depressed |= (1 << shiftMod); - if (neededMods & Qt::ControlModifier) - depressed |= (1 << controlMod); - - // update a keyboard state from a set of explicit masks if (i == 8) { - // Add a fall back key for layouts with non Latin-1 characters - if (baseQtKey > 255) { - struct xkb_rule_names names = { xkb_names.rules, xkb_names.model, "us", 0, 0 }; - fallback_keymap = xkb_keymap_new_from_names(xkb_context, &names, (xkb_keymap_compile_flags)0); - if (!fallback_keymap) - continue; - xkb_state_unref(kb_state); - kb_state = xkb_state_new(fallback_keymap); - if (!kb_state) - continue; - } else + if (isLatin(baseQtKey)) continue; + // add a latin key as a fall back key + sym = lookupLatinKeysym(keycode); } else { - xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, - baseLayout, latchedLayout, lockedLayout); + depressed = 0; + if (neededMods & Qt::AltModifier) + depressed |= (1 << altMod); + if (neededMods & Qt::ShiftModifier) + depressed |= (1 << shiftMod); + if (neededMods & Qt::ControlModifier) + depressed |= (1 << controlMod); + xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout); + sym = xkb_state_key_get_one_sym(kb_state, keycode); } - sym = xkb_state_key_get_one_sym(kb_state, event->nativeScanCode()); - if (sym == XKB_KEY_NoSymbol) continue; Qt::KeyboardModifiers mods = modifiers & ~neededMods; - qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode())); - - if (qtKey == baseQtKey || qtKey == 0) + qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, keycode)); + if (!qtKey || qtKey == baseQtKey) continue; // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +, @@ -926,8 +1013,6 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const } } xkb_state_unref(kb_state); - xkb_keymap_unref(fallback_keymap); - return result; } @@ -1002,6 +1087,8 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) , xkb_context(0) , xkb_keymap(0) , xkb_state(0) + , latin_keymap(0) + , m_hasLatinLayout(false) { memset(&xkb_names, 0, sizeof(xkb_names)); #ifndef QT_NO_XKB @@ -1029,6 +1116,7 @@ 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(); @@ -1324,7 +1412,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, if (type == QEvent::KeyPress) targetWindow->updateNetWmUserTime(time); - // It is crucial the order of xkb_state_key_get_one_sym & xkb_state_update_key operations is not reversed! xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code); QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); @@ -1348,15 +1435,22 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, return; } - Qt::KeyboardModifiers modifiers = translateModifiers(state); - QString string = lookupString(xkb_state, code); int count = string.size(); string.truncate(count); - int qtcode = keysymToQtKey(sym, modifiers, string); - bool isAutoRepeat = false; + // Ιf control modifier is set we should prefer latin character, this is + // used for standard shortcuts in checks like "key == QKeySequence::Copy", + // users can still see the actual X11 keysym with QKeyEvent::nativeVirtualKey + Qt::KeyboardModifiers modifiers = translateModifiers(state); + xcb_keysym_t translatedSym = XKB_KEY_NoSymbol; + if (modifiers & Qt::ControlModifier && !isLatin(sym)) + translatedSym = lookupLatinKeysym(code); + if (translatedSym == XKB_KEY_NoSymbol) + translatedSym = sym; + int qtcode = keysymToQtKey(translatedSym, modifiers, string); + bool isAutoRepeat = false; if (type == QEvent::KeyPress) { if (m_autorepeat_code == code) { isAutoRepeat = true; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index e71165d824..9f1cf165cb 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -91,6 +91,9 @@ protected: void updateVModMapping(); void updateVModToRModMapping(); + xkb_keysym_t lookupLatinKeysym(xkb_keycode_t keycode) const; + void checkForLatinLayout(); + private: bool m_config; xcb_keycode_t m_autorepeat_code; @@ -99,6 +102,7 @@ private: struct xkb_keymap *xkb_keymap; struct xkb_state *xkb_state; struct xkb_rule_names xkb_names; + mutable struct xkb_keymap *latin_keymap; struct _mod_masks { uint alt; @@ -128,6 +132,7 @@ private: _mod_masks vmod_masks; int core_device_id; #endif + bool m_hasLatinLayout; }; QT_END_NAMESPACE -- cgit v1.2.3 From ad1ec8b57dde6f5cbb7a4f66272794a067dc3917 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 28 Oct 2014 16:10:57 +0400 Subject: xcb: Fix setting the alert state for a window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Send a _NET_WM_STATE client message to the root window instead of changing the window property. Task-number: QTBUG-41310 Change-Id: I864af0158ec55796bb3cbc123469709b2be54ec8 Reviewed-by: Martin Gräßlin Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 0c2e9d047c..5d3206b097 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2380,13 +2380,10 @@ void QXcbWindow::setAlertState(bool enabled) { if (m_alertState == enabled) return; - const NetWmStates oldState = netWmStates(); + m_alertState = enabled; - if (enabled) { - setNetWmStates(oldState | NetWmStateDemandsAttention); - } else { - setNetWmStates(oldState & ~NetWmStateDemandsAttention); - } + + changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); } bool QXcbWindow::needsSync() const -- cgit v1.2.3 From 100ed0c01d7678a97e3b7b3a46320d84b3a7096d Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 24 Sep 2014 18:14:22 +0400 Subject: xcb: Fix getting the primary screen from QXcbConnection::screens() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently getting QXcbScreen* for primary screen is too messy and it wrongly uses QXcbConnection::primaryScreen() as an index in QXcbConnection::screens() although QXcbConnection::screens() returns the primary screen as the first item in the list since 3c8eb404877df9c967d81fa9df7d718c538fb407. So to clear the API rename primaryScreen() to primaryScreenNumber(), add QXcbConnection::primaryScreen() that returns correct QXcbScreen* and use it directly. Change-Id: Icb7391aa3e82b32ca48f2bda764dcf7ffd89cc47 Reviewed-by: Uli Schlachter Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 2 +- src/plugins/platforms/xcb/qxcbconnection.cpp | 20 +++++++++++++++----- src/plugins/platforms/xcb/qxcbconnection.h | 5 +++-- src/plugins/platforms/xcb/qxcbdrag.cpp | 2 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 4 +--- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 2 +- src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp | 7 ++----- src/plugins/platforms/xcb/qxcbwmsupport.cpp | 4 ++-- 8 files changed, 26 insertions(+), 20 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 45856f3e6c..8b3893ec2f 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -276,7 +276,7 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME; m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME; - m_screen = connection()->screens().at(connection()->primaryScreen()); + m_screen = connection()->primaryScreen(); int x = 0, y = 0, w = 3, h = 3; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 835c414d85..5510c3b1b4 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -244,7 +244,7 @@ void QXcbConnection::updateScreens() // the first or an exact match. An exact match isn't // always available if primary->output is XCB_NONE // or currently disconnected output. - if (m_primaryScreen == xcbScreenNumber) { + if (m_primaryScreenNumber == xcbScreenNumber) { if (!primaryScreen || (primary && outputs[i] == primary->output)) { primaryScreen = screen; siblings.prepend(siblings.takeLast()); @@ -306,7 +306,7 @@ void QXcbConnection::updateScreens() QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) : m_connection(0) , m_canGrabServer(canGrabServer) - , m_primaryScreen(0) + , m_primaryScreenNumber(0) , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) , m_nativeInterface(nativeInterface) , xfixes_first_event(0) @@ -331,7 +331,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra #ifdef XCB_USE_XLIB dpy = XOpenDisplay(m_displayName.constData()); if (dpy) { - m_primaryScreen = DefaultScreen(dpy); + m_primaryScreenNumber = DefaultScreen(dpy); m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); XSetErrorHandler(nullErrorHandler); @@ -339,7 +339,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_xlib_display = dpy; } #else - m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen); + m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber); #endif //XCB_USE_XLIB if (!m_connection || xcb_connection_has_error(m_connection)) @@ -449,6 +449,16 @@ QXcbConnection::~QXcbConnection() delete m_keyboard; } +QXcbScreen *QXcbConnection::primaryScreen() const +{ + if (!m_screens.isEmpty()) { + Q_ASSERT(m_screens.first()->screenNumber() == primaryScreenNumber()); + return m_screens.first(); + } + + return Q_NULLPTR; +} + void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener) { m_mapper.insert(id, eventListener); @@ -1219,7 +1229,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp() xcb_window_t QXcbConnection::rootWindow() { - return screens().at(primaryScreen())->root(); + return primaryScreen()->root(); } void QXcbConnection::processXcbEvents() diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 4a16e116c6..51c7c91bf6 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -369,7 +369,8 @@ public: QXcbConnection *connection() const { return const_cast(this); } const QList &screens() const { return m_screens; } - int primaryScreen() const { return m_primaryScreen; } + int primaryScreenNumber() const { return m_primaryScreenNumber; } + QXcbScreen *primaryScreen() const; inline xcb_atom_t atom(QXcbAtom::Atom atom) const { return m_allAtoms[atom]; } QXcbAtom::Atom qatom(xcb_atom_t atom) const; @@ -550,7 +551,7 @@ private: bool m_canGrabServer; QList m_screens; - int m_primaryScreen; + int m_primaryScreenNumber; xcb_atom_t m_allAtoms[QXcbAtom::NAtoms]; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 53437f24ae..7037e102e2 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -311,7 +311,7 @@ void QXcbDrag::move(const QMouseEvent *me) return; const QList &screens = connection()->screens(); - QXcbScreen *screen = screens.at(connection()->primaryScreen()); + QXcbScreen *screen = connection()->primaryScreen(); for (int i = 0; i < screens.size(); ++i) { if (screens.at(i)->geometry().contains(globalPos)) { screen = screens.at(i); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index d3533b8e44..52269bafea 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -417,10 +417,8 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const case QPlatformIntegration::StartDragDistance: { // The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but // on a high-resolution screen it makes sense to increase it. - const QList &screens = defaultConnection()->screens(); qreal dpi = 100.0; - if (screens.length() > 0) { - const QXcbScreen *screen = screens.at(defaultConnection()->primaryScreen()); + if (const QXcbScreen *screen = defaultConnection()->primaryScreen()) { if (screen->logicalDpi().first > dpi) dpi = screen->logicalDpi().first; if (screen->logicalDpi().second > dpi) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 0d75a7f032..3058b29f2d 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -367,7 +367,7 @@ void *QXcbNativeInterface::x11Screen() QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) - return reinterpret_cast(defaultConnection->primaryScreen()); + return reinterpret_cast(defaultConnection->primaryScreenNumber()); return 0; } diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp index 9ec4ea80ec..40a50f61ab 100644 --- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp +++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp @@ -59,7 +59,7 @@ QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection) const xcb_atom_t trayAtom = connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_OPCODE); if (!trayAtom) return 0; - const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreen()); + const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreenNumber()); const xcb_atom_t selection = connection->internAtom(netSysTray.constData()); if (!selection) return 0; @@ -145,11 +145,8 @@ QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged() { - const int screen = m_connection->primaryScreen(); - if (screen >= 0 && screen < m_connection->screens().size()) { - const QPlatformScreen *ps = m_connection->screens().at(screen); + if (const QPlatformScreen *ps = m_connection->primaryScreen()) emit systemTrayWindowChanged(ps->screen()); - } } // Client messages with the "MANAGER" atom on the root window indicate creation of a new tray. diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp index 0458be32f6..1be9ab3e05 100644 --- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp +++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp @@ -56,7 +56,7 @@ void QXcbWMSupport::updateNetWMAtoms() { net_wm_atoms.clear(); - xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root(); + xcb_window_t root = connection()->primaryScreen()->root(); int offset = 0; int remaining = 0; do { @@ -90,7 +90,7 @@ void QXcbWMSupport::updateVirtualRoots() if (!isSupportedByWM(atom(QXcbAtom::_NET_VIRTUAL_ROOTS))) return; - xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root(); + xcb_window_t root = connection()->primaryScreen()->root(); int offset = 0; int remaining = 0; do { -- cgit v1.2.3 From 9572dec3d72582bf99266af00a62028518d99852 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 31 Oct 2014 09:10:14 +0100 Subject: Remove unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fixes a compiler warning with clang Change-Id: I99beb7e099477b2b8b53af0e9fd32a7605a6c08a Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qglxintegration.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 84910c4172..5777980093 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -75,7 +75,6 @@ private: void init(QXcbScreen *screen, QPlatformOpenGLContext *share); void init(QXcbScreen *screen, QPlatformOpenGLContext *share, const QVariant &nativeHandle); - QXcbScreen *m_screen; Display *m_display; GLXFBConfig m_config; GLXContext m_context; -- cgit v1.2.3 From dce44534850548eefb8f060e51869fe906ca5ad4 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 30 Oct 2014 10:22:36 +0100 Subject: Prevent a leak of QXcbXSettingsPrivate The private was not deleted. Adding the dtor in turn causes a warning about not having a virtual dtor in the base class, so add that as well. Change-Id: I24a90caf2cf6192a6f17cf5af96b8f77010d9127 Reviewed-by: Shawn Rutledge Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection.h | 1 + src/plugins/platforms/xcb/qxcbxsettings.cpp | 6 ++++++ src/plugins/platforms/xcb/qxcbxsettings.h | 1 + 3 files changed, 8 insertions(+) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 51c7c91bf6..f31ecf8e03 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -324,6 +324,7 @@ private: class QXcbWindowEventListener { public: + virtual ~QXcbWindowEventListener() {} virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; } virtual void handleExposeEvent(const xcb_expose_event_t *) {} diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp index 6f2e60c9be..13d42832db 100644 --- a/src/plugins/platforms/xcb/qxcbxsettings.cpp +++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp @@ -262,6 +262,12 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen) d_ptr->initialized = true; } +QXcbXSettings::~QXcbXSettings() +{ + delete d_ptr; + d_ptr = 0; +} + bool QXcbXSettings::initialized() const { Q_D(const QXcbXSettings); diff --git a/src/plugins/platforms/xcb/qxcbxsettings.h b/src/plugins/platforms/xcb/qxcbxsettings.h index 717fe559c9..3496cedf36 100644 --- a/src/plugins/platforms/xcb/qxcbxsettings.h +++ b/src/plugins/platforms/xcb/qxcbxsettings.h @@ -45,6 +45,7 @@ class QXcbXSettings : public QXcbWindowEventListener Q_DECLARE_PRIVATE(QXcbXSettings) public: QXcbXSettings(QXcbScreen *screen); + ~QXcbXSettings(); bool initialized() const; QVariant setting(const QByteArray &property) const; -- cgit v1.2.3 From a7111c5ddef3072eb73c08f14823343208c18f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 30 Oct 2014 16:53:18 +0100 Subject: Make the -nograb and -dograb arguments actually work on xcb Change-Id: Idc725443e4abe27db3e530f08173897bfcbe1278 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/xcb/qxcbconnection.h | 1 + src/plugins/platforms/xcb/qxcbintegration.cpp | 41 ++++++++++++++++++++------- src/plugins/platforms/xcb/qxcbintegration.h | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 6 ++++ 4 files changed, 38 insertions(+), 11 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index f31ecf8e03..7286b6b89b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -471,6 +471,7 @@ public: QXcbEventReader *eventReader() const { return m_reader; } + bool canGrab() const { return m_canGrabServer; } protected: bool event(QEvent *e) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 52269bafea..cace087613 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -92,11 +92,11 @@ QT_BEGIN_NAMESPACE -#if defined(QT_DEBUG) && defined(Q_OS_LINUX) // Find out if our parent process is gdb by looking at the 'exe' symlink under /proc,. // or, for older Linuxes, read out 'cmdline'. static bool runningUnderDebugger() { +#if defined(QT_DEBUG) && defined(Q_OS_LINUX) const QString parentProc = QLatin1String("/proc/") + QString::number(getppid()); const QFileInfo parentProcExe(parentProc + QLatin1String("/exe")); if (parentProcExe.isSymLink()) @@ -113,12 +113,15 @@ static bool runningUnderDebugger() s += c; } return s == "gdb"; -} +#else + return false; #endif +} QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char **argv) : m_services(new QGenericUnixServices) , m_instanceName(0) + , m_canGrab(true) { qRegisterMetaType(); #ifdef XCB_USE_XLIB @@ -126,16 +129,10 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char #endif m_nativeInterface.reset(new QXcbNativeInterface); - bool canGrab = true; - #if defined(QT_DEBUG) && defined(Q_OS_LINUX) - canGrab = !runningUnderDebugger(); - #endif - static bool canNotGrabEnv = qgetenv("QT_XCB_NO_GRAB_SERVER").length(); - if (canNotGrabEnv) - canGrab = false; - // Parse arguments const char *displayName = 0; + bool noGrabArg = false; + bool doGrabArg = false; if (argc) { int j = 1; for (int i = 1; i < argc; i++) { @@ -146,13 +143,35 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char displayName = argv[++i]; else if (arg == "-name" && i < argc - 1) m_instanceName = argv[++i]; + else if (arg == "-nograb") + noGrabArg = true; + else if (arg == "-dograb") + doGrabArg = true; else argv[j++] = argv[i]; } argc = j; } // argc - m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab, displayName); + bool underDebugger = runningUnderDebugger(); + if (noGrabArg && doGrabArg && underDebugger) { + qWarning() << "Both -nograb and -dograb command line arguments specified. Please pick one. -nograb takes prcedence"; + doGrabArg = false; + } + +#if defined(QT_DEBUG) + if (!noGrabArg && !doGrabArg && underDebugger) { + qDebug("Qt: gdb: -nograb added to command-line options.\n" + "\t Use the -dograb option to enforce grabbing."); + } +#endif + m_canGrab = (!underDebugger && noGrabArg) || (underDebugger && doGrabArg); + + static bool canNotGrabEnv = qEnvironmentVariableIsSet("QT_XCB_NO_GRAB_SERVER"); + if (canNotGrabEnv) + m_canGrab = false; + + m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, displayName); for (int i = 0; i < parameters.size() - 1; i += 2) { #ifdef Q_XCB_DEBUG diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index ffb068ecb3..db6ad541ea 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -117,6 +117,7 @@ private: mutable QByteArray m_wmClass; const char *m_instanceName; + bool m_canGrab; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 5d3206b097..85af8ee1d2 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2170,6 +2170,9 @@ void QXcbWindow::updateSyncRequestCounter() bool QXcbWindow::setKeyboardGrabEnabled(bool grab) { + if (grab && !connection()->canGrab()) + return false; + if (!grab) { xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME); return true; @@ -2185,6 +2188,9 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab) { + if (grab && !connection()->canGrab()) + return false; + if (!grab) { xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME); return true; -- cgit v1.2.3 From 501c510cc3cb6215aed27af7599395480a049667 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 11 Nov 2014 13:48:27 +0100 Subject: Do not apply subpixel gamma-correction on XCB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To match rendering of subpixel antialiased text in Qt 4.8 and other toolkits on X11, we should not apply gamma-correction. This also makes the rendering of subpixel antialiased text closer to normal antialiased text. Task-number: QTBUG-41590 Change-Id: I45ad3448334951353657b878d002eea429858f2d Reviewed-by: Samuel Rødal Reviewed-by: Sérgio Martins Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/xcb/qxcbintegration.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index cace087613..3818494d99 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -427,12 +427,14 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const case QPlatformIntegration::StartDragTime: case QPlatformIntegration::KeyboardAutoRepeatRate: case QPlatformIntegration::PasswordMaskDelay: - case QPlatformIntegration::FontSmoothingGamma: case QPlatformIntegration::StartDragVelocity: case QPlatformIntegration::UseRtlExtensions: case QPlatformIntegration::PasswordMaskCharacter: // TODO using various xcb, gnome or KDE settings break; // Not implemented, use defaults + case QPlatformIntegration::FontSmoothingGamma: + // Match Qt 4.8 text rendering, and rendering of other X11 toolkits. + return qreal(1.0); case QPlatformIntegration::StartDragDistance: { // The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but // on a high-resolution screen it makes sense to increase it. -- cgit v1.2.3