From 3753b15e88f2c8220b887f27be79491c4135a291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 6 Dec 2010 16:13:34 +0100 Subject: Added window focus handling to lighthouse The idea is that QPlatformWindows can request focus handling. And when actual focus shifting is done by windowsystem callbacks/events which are sent to QWindowSystemInterface --- src/gui/kernel/qapplication_p.h | 2 ++ src/gui/kernel/qapplication_qpa.cpp | 7 +++++++ src/gui/kernel/qplatformwindow_qpa.cpp | 19 +++++++++++++++++++ src/gui/kernel/qplatformwindow_qpa.h | 1 + src/gui/kernel/qwidget_qpa.cpp | 8 ++------ src/gui/kernel/qwindowsysteminterface_qpa.cpp | 6 ++++++ src/gui/kernel/qwindowsysteminterface_qpa.h | 1 + src/gui/kernel/qwindowsysteminterface_qpa_p.h | 9 +++++++++ src/plugins/platforms/testlite/qtestlitewindow.cpp | 22 ++++++++++++++++++++++ src/plugins/platforms/testlite/qtestlitewindow.h | 3 +++ 10 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 7b49999..73c4462 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -508,6 +508,8 @@ public: static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e); static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e); + static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e); + static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e); // static void reportScreenCount(int count); diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp index ece035c..a587e8e 100644 --- a/src/gui/kernel/qapplication_qpa.cpp +++ b/src/gui/kernel/qapplication_qpa.cpp @@ -111,6 +111,9 @@ void QApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate case QWindowSystemInterfacePrivate::Leave: QApplicationPrivate::processLeaveEvent(static_cast(e)); break; + case QWindowSystemInterfacePrivate::ActivatedWindow: + QApplicationPrivate::processActivatedEvent(static_cast(e)); + break; case QWindowSystemInterfacePrivate::Close: QApplicationPrivate::processCloseEvent( static_cast(e)); @@ -823,6 +826,10 @@ void QApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::Leave } +void QApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e) +{ + QApplication::setActiveWindow(e->activated.data()); +} void QApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e) { diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 29eaa82..b6b6693 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -41,6 +41,7 @@ #include "qplatformwindow_qpa.h" +#include #include class QPlatformWindowPrivate @@ -171,6 +172,24 @@ void QPlatformWindow::setOpacity(qreal level) } /*! + Reimplement to let Qt be able to request activation/focus for a window + + Some window systems will probably not have callbacks for this functionality, + and then calling QWindowSystemInterface::handleWindowActivated(QWidget *w) + would be sufficient. + + If the window system has some event handling/callbacks then call + QWindowSystemInterface::handleWindowActivated(QWidget *w) when the window system + gives the notification. + + Default implementation calls QWindowSystem::handleWindowActivated(QWidget *w) +*/ +void QPlatformWindow::requestActivateWindow() +{ + QWindowSystemInterface::handleWindowActivated(widget()); +} + +/*! Reimplement to return the glContext associated with the window. */ QPlatformGLContext *QPlatformWindow::glContext() const diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 4f6fedc..abc35d1 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -80,6 +80,7 @@ public: virtual void lower(); virtual void setOpacity(qreal level); + virtual void requestActivateWindow(); virtual QPlatformGLContext *glContext() const; protected: diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index 617d984..1279e0a 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -379,9 +379,8 @@ QWidget *QWidget::keyboardGrabber() void QWidget::activateWindow() { - // XXX -// qDebug() << "QWidget::activateWindow" << this; - QApplication::setActiveWindow(this); //##### + if (platformWindow()) + platformWindow()->requestActivateWindow(); } void QWidgetPrivate::show_sys() @@ -409,9 +408,6 @@ void QWidgetPrivate::show_sys() } if (window) window->setVisible(true); - - if (q->isWindow() && q->windowType() != Qt::Popup && q->windowType() != Qt::ToolTip && !(q->windowFlags() & Qt::X11BypassWindowManagerHint)) - q->activateWindow(); //### QWindowSystemInterface should have callback function for when WS actually activates window. } } diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index bb29cbf..b6177b0 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -82,6 +82,12 @@ void QWindowSystemInterface::handleLeaveEvent(QWidget *tlw) QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } +void QWindowSystemInterface::handleWindowActivated(QWidget *tlw) +{ + QWindowSystemInterfacePrivate::ActivatedWindowEvent *e = new QWindowSystemInterfacePrivate::ActivatedWindowEvent(tlw); + QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); +} + void QWindowSystemInterface::handleGeometryChange(QWidget *tlw, const QRect &newRect) { if (tlw) { diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index 1c79f2a..39c2f79 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -83,6 +83,7 @@ public: static void handleCloseEvent(QWidget *w); static void handleEnterEvent(QWidget *w); static void handleLeaveEvent(QWidget *w); + static void handleWindowActivated(QWidget *w); // Changes to the screen static void handleScreenGeometryChange(int screenIndex); diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h index 78e1f33..3491a1a 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h @@ -54,6 +54,7 @@ public: GeometryChange, Enter, Leave, + ActivatedWindow, Mouse, Wheel, Key, @@ -102,6 +103,14 @@ public: QWeakPointer leave; }; + class ActivatedWindowEvent : public WindowSystemEvent { + public: + ActivatedWindowEvent(QWidget *activatedWindow) + : WindowSystemEvent(ActivatedWindow), activated(activatedWindow) + { } + QWeakPointer activated; + }; + class UserEvent : public WindowSystemEvent { public: UserEvent(QWidget * w, ulong time, EventType t) diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index b52aae9..5f9d387 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -318,6 +318,16 @@ void QTestLiteWindow::handleLeaveEvent() QWindowSystemInterface::handleLeaveEvent(widget()); } +void QTestLiteWindow::handleFocusInEvent() +{ + QWindowSystemInterface::handleWindowActivated(widget()); +} + +void QTestLiteWindow::handleFocusOutEvent() +{ + QWindowSystemInterface::handleWindowActivated(0); +} + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Key event stuff -- not pretty either @@ -694,6 +704,10 @@ void QTestLiteWindow::paintEvent() surface->flush(widget(), QRect(xpos,ypos,width, height), QPoint()); } +void QTestLiteWindow::requestActivateWindow() +{ + XSetInputFocus(xd->display, x_window, XRevertToParent, CurrentTime); +} void QTestLiteWindow::resizeEvent(XConfigureEvent *e) { @@ -1456,6 +1470,14 @@ bool MyDisplay::handleEvent(XEvent *xe) xw->handleLeaveEvent(); break; + case XFocusIn: + xw->handleFocusInEvent(); + break; + + case XFocusOut: + xw->handleFocusOutEvent(); + break; + default: #ifdef MYX11_DEBUG qDebug() << hex << xe->xany.window << "Other X event" << xe->type; diff --git a/src/plugins/platforms/testlite/qtestlitewindow.h b/src/plugins/platforms/testlite/qtestlitewindow.h index dc628f1..69442f1 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.h +++ b/src/plugins/platforms/testlite/qtestlitewindow.h @@ -109,10 +109,13 @@ public: void handleCloseEvent(); void handleEnterEvent(); void handleLeaveEvent(); + void handleFocusInEvent(); + void handleFocusOutEvent(); void resizeEvent(XConfigureEvent *configure_event); void paintEvent(); + void requestActivateWindow(); void setGeometry(const QRect &rect); -- cgit v0.12