diff options
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 8 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 14 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 18 |
5 files changed, 44 insertions, 3 deletions
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index ed34693faa..6933c892a0 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -120,6 +120,8 @@ public: return offset; } + virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; } + QWindow::SurfaceType surfaceType; Qt::WindowFlags windowFlags; QWindow *parentWindow; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 7fc5847167..32de54562a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -258,6 +258,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char , has_randr_extension(false) , has_input_shape(false) , m_buttons(0) + , m_focusWindow(0) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -418,7 +419,7 @@ break; if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \ handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ if (!handled) \ - m_keyboard->handler(platformWindow, e); \ + m_keyboard->handler(m_focusWindow, e); \ } \ } \ break; @@ -943,6 +944,11 @@ void QXcbEventReader::unlock() m_mutex.unlock(); } +void QXcbConnection::setFocusWindow(QXcbWindow *w) +{ + m_focusWindow = w; +} + void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) { xcb_client_message_event_t event; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 68d2b85f78..b499f75b78 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -385,6 +385,9 @@ public: Qt::MouseButtons buttons() const { return m_buttons; } + QXcbWindow *focusWindow() const { return m_focusWindow; } + void setFocusWindow(QXcbWindow *); + private slots: void processXcbEvents(); @@ -511,6 +514,8 @@ private: bool has_input_shape; Qt::MouseButtons m_buttons; + + QXcbWindow *m_focusWindow; }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index b7668e6270..c0ddf5c0ae 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -403,6 +403,9 @@ QXcbWindow::~QXcbWindow() void QXcbWindow::destroy() { + if (connection()->focusWindow() == this) + connection()->setFocusWindow(0); + if (m_syncCounter && m_screen->syncRequestSupported()) Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter)); if (m_window) { @@ -1473,6 +1476,11 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) { + if (window() != QGuiApplication::focusWindow()) { + QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver(); + w->requestActivate(); + } + updateNetWmUserTime(event->time); QPoint local(event->event_x, event->event_y); @@ -1635,7 +1643,10 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) { - QWindowSystemInterface::handleWindowActivated(window()); + QWindow *w = window(); + w = static_cast<QWindowPrivate *>(QObjectPrivate::get(w))->eventReceiver(); + connection()->setFocusWindow(static_cast<QXcbWindow *>(w->handle())); + QWindowSystemInterface::handleWindowActivated(w); } static bool focusInPeeker(xcb_generic_event_t *event) @@ -1651,6 +1662,7 @@ static bool focusInPeeker(xcb_generic_event_t *event) void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) { + connection()->setFocusWindow(0); // Do not set the active window to 0 if there is a FocusIn coming. // There is however no equivalent for XPutBackEvent so register a // callback for QXcbConnection instead. diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 462ebc605b..50b61beb05 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "private/qwindow_p.h" #include "qwidgetwindow_qpa_p.h" #include "private/qwidget_p.h" @@ -60,8 +61,23 @@ extern int openPopupCount; bool qt_replay_popup_mouse_event = false; extern bool qt_try_modal(QWidget *widget, QEvent::Type type); +class QWidgetWindowPrivate : public QWindowPrivate +{ + Q_DECLARE_PUBLIC(QWidgetWindow) +public: + QWindow *eventReceiver() { + Q_Q(QWidgetWindow); + QWindow *w = q; + while (w->parent() && qobject_cast<QWidgetWindow *>(w) && qobject_cast<QWidgetWindow *>(w->parent())) { + w = w->parent(); + } + return w; + } +}; + QWidgetWindow::QWidgetWindow(QWidget *widget) - : m_widget(widget) + : QWindow(*new QWidgetWindowPrivate(), 0) + , m_widget(widget) { updateObjectName(); connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); |