diff --git a/greeter/greeterapp.cpp b/greeter/greeterapp.cpp --- a/greeter/greeterapp.cpp +++ b/greeter/greeterapp.cpp @@ -372,7 +372,6 @@ // this loop is required to make the qml/graphicsscene properly handle the shared keyboard input // ie. "type something into the box of every greeter" foreach (KQuickAddons::QuickViewSharedEngine *view, m_views) { - view->requestActivate(); if (!m_testing) { view->setKeyboardGrabEnabled(true); // TODO - check whether this still works in master! } diff --git a/x11locker.h b/x11locker.h --- a/x11locker.h +++ b/x11locker.h @@ -60,6 +60,7 @@ void setVRoot(Window win, Window vr); void removeVRoot(Window win); int findWindowInfo(Window w); + void fakeFocusIn(WId window); void stayOnTop() override; struct WindowInfo { @@ -69,6 +70,7 @@ QList m_windowInfo; QList m_lockWindows; QList m_allowedWindows; + WId m_focusedLockWindow; }; } diff --git a/x11locker.cpp b/x11locker.cpp --- a/x11locker.cpp +++ b/x11locker.cpp @@ -51,6 +51,7 @@ X11Locker::X11Locker(QObject *parent) : AbstractLocker(parent) , QAbstractNativeEventFilter() + , m_focusedLockWindow(XCB_WINDOW_NONE) { initialize(); } @@ -229,8 +230,12 @@ XDeleteProperty (QX11Info::display(), win, gXA_VROOT); } -static void fakeFocusIn( WId window ) +void X11Locker::fakeFocusIn( WId window ) { + if (window == m_focusedLockWindow) { + return; + } + // We have keyboard grab, so this application will // get keyboard events even without having focus. // Fake FocusIn to make Qt realize it has the active @@ -244,6 +249,8 @@ ev.xfocus.detail = NotifyAncestor; XSendEvent( QX11Info::display(), window, False, NoEventMask, &ev ); XFlush(QX11Info::display()); + + m_focusedLockWindow = window; } template< typename T> @@ -308,6 +315,11 @@ (x>=x_return && x<=x_return+(int)width_return) && (y>=y_return && y<=y_return+(int)height_return) ) { + // We need to do our own focus handling (see comment in fakeFocusIn). + // For now: Focus on clicks inside the window + if (responseType == XCB_BUTTON_PRESS) { + fakeFocusIn(window); + } const int targetX = x - x_return; const int targetY = y - y_return; if (responseType == XCB_KEY_PRESS || responseType == XCB_KEY_RELEASE) { @@ -386,6 +398,10 @@ else qDebug() << "Unknown toplevel for MapNotify"; m_lockWindows.removeAll(xu->event); + if (m_focusedLockWindow == xu->event && !m_lockWindows.empty()) { + // The currently focused window vanished, just focus the first one in the list + fakeFocusIn(m_lockWindows[0]); + } ret = true; } break; @@ -508,8 +524,14 @@ // not yet shown and we have a lock window, so we show our own window m_background->show(); } + + if (m_lockWindows.empty()) { + // Make sure to focus the first window + m_focusedLockWindow = XCB_WINDOW_NONE; + fakeFocusIn(window); + } + m_lockWindows.prepend(window); - fakeFocusIn(window); stayOnTop(); } }