Avoid setting the active window to null when there is a FocusIn queued.
This commit is contained in:
parent
4f1a6ac732
commit
78264f333e
@ -483,6 +483,11 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||||||
printXcbEvent("Unhandled XCB event", event);
|
printXcbEvent("Unhandled XCB event", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QXcbConnection::addPeekFunc(PeekFunc f)
|
||||||
|
{
|
||||||
|
m_peekFuncs.append(f);
|
||||||
|
}
|
||||||
|
|
||||||
void QXcbConnection::processXcbEvents()
|
void QXcbConnection::processXcbEvents()
|
||||||
{
|
{
|
||||||
while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection()))
|
while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection()))
|
||||||
@ -498,6 +503,15 @@ void QXcbConnection::processXcbEvents()
|
|||||||
if (!response_type) {
|
if (!response_type) {
|
||||||
handleXcbError((xcb_generic_error_t *)event);
|
handleXcbError((xcb_generic_error_t *)event);
|
||||||
} else {
|
} else {
|
||||||
|
QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
|
||||||
|
while (it != m_peekFuncs.end()) {
|
||||||
|
// These callbacks return true if the event is what they were
|
||||||
|
// waiting for, remove them from the list in that case.
|
||||||
|
if ((*it)(event))
|
||||||
|
it = m_peekFuncs.erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
handleXcbEvent(event);
|
handleXcbEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,6 +520,12 @@ void QXcbConnection::processXcbEvents()
|
|||||||
|
|
||||||
eventqueue.clear();
|
eventqueue.clear();
|
||||||
|
|
||||||
|
// Indicate with a null event that the event the callbacks are waiting for
|
||||||
|
// is not in the queue currently.
|
||||||
|
Q_FOREACH (PeekFunc f, m_peekFuncs)
|
||||||
|
f(0);
|
||||||
|
m_peekFuncs.clear();
|
||||||
|
|
||||||
xcb_flush(xcb_connection());
|
xcb_flush(xcb_connection());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +284,9 @@ public:
|
|||||||
|
|
||||||
QXcbWindow *platformWindowFromId(xcb_window_t id);
|
QXcbWindow *platformWindowFromId(xcb_window_t id);
|
||||||
|
|
||||||
|
typedef bool (*PeekFunc)(xcb_generic_event_t *);
|
||||||
|
void addPeekFunc(PeekFunc f);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void processXcbEvents();
|
void processXcbEvents();
|
||||||
|
|
||||||
@ -335,6 +338,8 @@ private:
|
|||||||
QVector<xcb_generic_event_t *> eventqueue;
|
QVector<xcb_generic_event_t *> eventqueue;
|
||||||
|
|
||||||
WindowMapper m_mapper;
|
WindowMapper m_mapper;
|
||||||
|
|
||||||
|
QVector<PeekFunc> m_peekFuncs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
|
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
|
||||||
|
@ -1087,9 +1087,23 @@ void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
|
|||||||
QWindowSystemInterface::handleWindowActivated(window());
|
QWindowSystemInterface::handleWindowActivated(window());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool focusInPeeker(xcb_generic_event_t *event)
|
||||||
|
{
|
||||||
|
if (!event) {
|
||||||
|
// FocusIn event is not in the queue, proceed with FocusOut normally.
|
||||||
|
QWindowSystemInterface::handleWindowActivated(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uint response_type = event->response_type & ~0x80;
|
||||||
|
return response_type == XCB_FOCUS_IN;
|
||||||
|
}
|
||||||
|
|
||||||
void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
|
void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
|
||||||
{
|
{
|
||||||
QWindowSystemInterface::handleWindowActivated(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.
|
||||||
|
connection()->addPeekFunc(focusInPeeker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbWindow::updateSyncRequestCounter()
|
void QXcbWindow::updateSyncRequestCounter()
|
||||||
|
@ -161,6 +161,8 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous)
|
|||||||
Q_UNUSED(previous);
|
Q_UNUSED(previous);
|
||||||
Q_Q(QApplication);
|
Q_Q(QApplication);
|
||||||
QWindow *wnd = QGuiApplicationPrivate::active_window;
|
QWindow *wnd = QGuiApplicationPrivate::active_window;
|
||||||
|
if (inPopupMode()) // some delayed focus event to ignore
|
||||||
|
return;
|
||||||
QWidget *tlw = qt_tlw_for_window(wnd);
|
QWidget *tlw = qt_tlw_for_window(wnd);
|
||||||
q->setActiveWindow(tlw);
|
q->setActiveWindow(tlw);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user