summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-01-22 10:19:49 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-01-24 09:08:59 +0100
commitfc663b5f9aae16fe6a03160e3eb148a5f742ac58 (patch)
treecdc95023da9a6f7c5068e31f07cdf0dbfb47fa13 /src/plugins/platforms/xcb
parenta5fa0cf98cdedd6dc3488b590499b0b4387747dc (diff)
Fix focus handling of native child widgets in xcb.
Change-Id: If4d596195624011142bff6853849a23064e478df Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp14
3 files changed, 25 insertions, 2 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index c477c3a1a5..44c730d375 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;
@@ -942,6 +943,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 60cc547979..a8957d5810 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) {
@@ -1483,6 +1486,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);
@@ -1645,7 +1653,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)
@@ -1661,6 +1672,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.