Fix focus handling of native child widgets in xcb.
Change-Id: If4d596195624011142bff6853849a23064e478df
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
(cherry picked from commit fc663b5f9a
)
This commit is contained in:
parent
18f9eb797b
commit
3f99983e76
@ -120,6 +120,8 @@ public:
|
||||
return offset;
|
||||
}
|
||||
|
||||
virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; }
|
||||
|
||||
QWindow::SurfaceType surfaceType;
|
||||
Qt::WindowFlags windowFlags;
|
||||
QWindow *parentWindow;
|
||||
|
@ -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;
|
||||
|
@ -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()))
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user