Prevent XSetInputFocus BadMatch errors.
The BadMatch errors are generated if XSetInputFocus is called before the window has been mapped, so we need to set a flag when we get the map notify event.
This commit is contained in:
parent
ead7c1c33c
commit
f05236a40d
@ -442,6 +442,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
|
||||
case XCB_MAP_NOTIFY:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
|
||||
case XCB_CLIENT_MESSAGE:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
|
||||
case XCB_ENTER_NOTIFY:
|
||||
|
@ -94,6 +94,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
|
||||
, m_window(0)
|
||||
, m_context(0)
|
||||
, m_syncCounter(0)
|
||||
, m_mapped(false)
|
||||
{
|
||||
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0));
|
||||
|
||||
@ -278,6 +279,7 @@ void QXcbWindow::destroy()
|
||||
connection()->removeWindow(m_window);
|
||||
Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
|
||||
}
|
||||
m_mapped = false;
|
||||
}
|
||||
|
||||
void QXcbWindow::setGeometry(const QRect &rect)
|
||||
@ -367,6 +369,8 @@ void QXcbWindow::hide()
|
||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
|
||||
|
||||
xcb_flush(xcb_connection());
|
||||
|
||||
m_mapped = false;
|
||||
}
|
||||
|
||||
struct QtMotifWmHints {
|
||||
@ -877,8 +881,10 @@ void QXcbWindow::propagateSizeHints()
|
||||
|
||||
void QXcbWindow::requestActivateWindow()
|
||||
{
|
||||
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
|
||||
connection()->sync();
|
||||
if (m_mapped){
|
||||
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
|
||||
connection()->sync();
|
||||
}
|
||||
}
|
||||
|
||||
QPlatformGLContext *QXcbWindow::glContext() const
|
||||
@ -968,6 +974,12 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
|
||||
#endif
|
||||
}
|
||||
|
||||
void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
|
||||
{
|
||||
if (event->window == m_window)
|
||||
m_mapped = true;
|
||||
}
|
||||
|
||||
static Qt::MouseButtons translateMouseButtons(int s)
|
||||
{
|
||||
Qt::MouseButtons ret = 0;
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
void handleExposeEvent(const xcb_expose_event_t *event);
|
||||
void handleClientMessageEvent(const xcb_client_message_event_t *event);
|
||||
void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event);
|
||||
void handleMapNotifyEvent(const xcb_map_notify_event_t *event);
|
||||
void handleButtonPressEvent(const xcb_button_press_event_t *event);
|
||||
void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
|
||||
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);
|
||||
@ -127,6 +128,8 @@ private:
|
||||
|
||||
bool m_hasReceivedSyncRequest;
|
||||
Qt::WindowState m_windowState;
|
||||
|
||||
bool m_mapped;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -10226,18 +10226,26 @@ void tst_QWidget::nativeChildFocus()
|
||||
QLineEdit *p2 = new QLineEdit;
|
||||
layout->addWidget(p1);
|
||||
layout->addWidget(p2);
|
||||
#if 1
|
||||
p1->setObjectName("p1");
|
||||
p2->setObjectName("p2");
|
||||
#endif
|
||||
w.show();
|
||||
#if 1
|
||||
w.activateWindow();
|
||||
p1->setFocus();
|
||||
p1->setAttribute(Qt::WA_NativeWindow);
|
||||
p2->setAttribute(Qt::WA_NativeWindow);
|
||||
QApplication::processEvents();
|
||||
QTest::qWaitForWindowShown(&w);
|
||||
QTest::qWait(10);
|
||||
|
||||
qDebug() << "checking active window:" << QApplication::activeWindow();
|
||||
QCOMPARE(QApplication::activeWindow(), &w);
|
||||
QCOMPARE(QApplication::focusWidget(), static_cast<QWidget*>(p1));
|
||||
#endif
|
||||
|
||||
QTest::qWait(1000);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QWidget)
|
||||
|
Loading…
x
Reference in New Issue
Block a user