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);
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
|
||||||
case XCB_CONFIGURE_NOTIFY:
|
case XCB_CONFIGURE_NOTIFY:
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
|
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:
|
case XCB_CLIENT_MESSAGE:
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
|
||||||
case XCB_ENTER_NOTIFY:
|
case XCB_ENTER_NOTIFY:
|
||||||
|
@ -94,6 +94,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
|
|||||||
, m_window(0)
|
, m_window(0)
|
||||||
, m_context(0)
|
, m_context(0)
|
||||||
, m_syncCounter(0)
|
, m_syncCounter(0)
|
||||||
|
, m_mapped(false)
|
||||||
{
|
{
|
||||||
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0));
|
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0));
|
||||||
|
|
||||||
@ -278,6 +279,7 @@ void QXcbWindow::destroy()
|
|||||||
connection()->removeWindow(m_window);
|
connection()->removeWindow(m_window);
|
||||||
Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
|
Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
|
||||||
}
|
}
|
||||||
|
m_mapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbWindow::setGeometry(const QRect &rect)
|
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_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
|
||||||
|
|
||||||
xcb_flush(xcb_connection());
|
xcb_flush(xcb_connection());
|
||||||
|
|
||||||
|
m_mapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QtMotifWmHints {
|
struct QtMotifWmHints {
|
||||||
@ -877,8 +881,10 @@ void QXcbWindow::propagateSizeHints()
|
|||||||
|
|
||||||
void QXcbWindow::requestActivateWindow()
|
void QXcbWindow::requestActivateWindow()
|
||||||
{
|
{
|
||||||
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
|
if (m_mapped){
|
||||||
connection()->sync();
|
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
|
QPlatformGLContext *QXcbWindow::glContext() const
|
||||||
@ -968,6 +974,12 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
|
|||||||
#endif
|
#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)
|
static Qt::MouseButtons translateMouseButtons(int s)
|
||||||
{
|
{
|
||||||
Qt::MouseButtons ret = 0;
|
Qt::MouseButtons ret = 0;
|
||||||
|
@ -83,6 +83,7 @@ public:
|
|||||||
void handleExposeEvent(const xcb_expose_event_t *event);
|
void handleExposeEvent(const xcb_expose_event_t *event);
|
||||||
void handleClientMessageEvent(const xcb_client_message_event_t *event);
|
void handleClientMessageEvent(const xcb_client_message_event_t *event);
|
||||||
void handleConfigureNotifyEvent(const xcb_configure_notify_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 handleButtonPressEvent(const xcb_button_press_event_t *event);
|
||||||
void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
|
void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
|
||||||
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);
|
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);
|
||||||
@ -127,6 +128,8 @@ private:
|
|||||||
|
|
||||||
bool m_hasReceivedSyncRequest;
|
bool m_hasReceivedSyncRequest;
|
||||||
Qt::WindowState m_windowState;
|
Qt::WindowState m_windowState;
|
||||||
|
|
||||||
|
bool m_mapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10226,18 +10226,26 @@ void tst_QWidget::nativeChildFocus()
|
|||||||
QLineEdit *p2 = new QLineEdit;
|
QLineEdit *p2 = new QLineEdit;
|
||||||
layout->addWidget(p1);
|
layout->addWidget(p1);
|
||||||
layout->addWidget(p2);
|
layout->addWidget(p2);
|
||||||
|
#if 1
|
||||||
p1->setObjectName("p1");
|
p1->setObjectName("p1");
|
||||||
p2->setObjectName("p2");
|
p2->setObjectName("p2");
|
||||||
|
#endif
|
||||||
w.show();
|
w.show();
|
||||||
|
#if 1
|
||||||
w.activateWindow();
|
w.activateWindow();
|
||||||
p1->setFocus();
|
p1->setFocus();
|
||||||
p1->setAttribute(Qt::WA_NativeWindow);
|
p1->setAttribute(Qt::WA_NativeWindow);
|
||||||
p2->setAttribute(Qt::WA_NativeWindow);
|
p2->setAttribute(Qt::WA_NativeWindow);
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
QTest::qWaitForWindowShown(&w);
|
QTest::qWaitForWindowShown(&w);
|
||||||
|
QTest::qWait(10);
|
||||||
|
|
||||||
|
qDebug() << "checking active window:" << QApplication::activeWindow();
|
||||||
QCOMPARE(QApplication::activeWindow(), &w);
|
QCOMPARE(QApplication::activeWindow(), &w);
|
||||||
QCOMPARE(QApplication::focusWidget(), static_cast<QWidget*>(p1));
|
QCOMPARE(QApplication::focusWidget(), static_cast<QWidget*>(p1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QTest::qWait(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QWidget)
|
QTEST_MAIN(tst_QWidget)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user