Bug 348935 - Loose focus after resuming from lock
Summary: Loose focus after resuming from lock
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: core (show other bugs)
Version: 5.4.2
Platform: Ubuntu Linux
: NOR minor
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-06-09 17:35 UTC by Franco Pellegrini
Modified: 2015-11-17 20:52 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In: 5.5


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Franco Pellegrini 2015-06-09 17:35:09 UTC
When coming back from the lock screen, no window has focus. This is particularly annoying when you have several windows of the same application open, and you try to use Alt + ` to cycle them, and end up with the "Show doesktop" coming up.

Reproducible: Always

Steps to Reproduce:
1. Open 2 or more instances of the same application (kate, dolphin, whatever...)
2. Hitting Alt + ` will cycle around the same application windows
3. Hit Ctrl + L to lock your session
4. Unlock your session
5. Hit Alt + `

Actual Results:  
Windows from all applications are faded away to the corners and you get "Show desktop"

Expected Results:  
The app that had the focus before the Lock happened, to retain the focus, so when coming out of the Lock, if you hit Alt + ` you will still have the same results as you had before locking.
Comment 1 Thomas Lübking 2015-06-10 14:57:42 UTC
The problem is more generic, eg. (override_redirect?) games grabbing the input sometimes leave the focus _really_ nowhere (not even the kwin helper window) and as result global shortcuts fail (until a window is activated)

Maybe we need to check whether the focus is somewhere (ideally "else than the helper window") everytime an unmanaged closes and if not do the XCB_FOCUS_IN input selection?
Comment 2 Achim Bohnet 2015-11-02 21:26:08 UTC
I hope it's the same bug:  (kubuntu 15.10: kf5 5.15, plasma5 5.4.2, qt 5.4.2)

Reproduce:
 1) e.g. konsole has keyboard focus (i.a. window deco title bar is dark (sdt breeze) and cursur is solid) and what you typ is shown in konsole window.
 2) lock screen with alt-ctrl-l and login again
 3) konsole window doco title is light grey as all other window titles, konsole cursur is only an 
    outlike rectangular box
 4) start typing -> keyboard in put show up in konsole 

Expected result: 

After lock screen ends, window deco title bar of the last active app is black as before screenlock  and konsole was informed that it has keyboard focus (-> cursor outline changes back to a block).

Right now it's a mixture.  Keyboard input still finds the last application that had keyboard focus before the screen was locked (that right) but app shows no visual indication  that this is the case: ight title bar and cursor of inactive input window (that's wrong)

Same with kate:  no blicking cursor after lock screen ends, light window deco title bar.

kwin_x11 -replace shows:

QXcbConnection: XCB error: 8 (BadMatch), sequence: 1777, resource id: 104857606, major code: 42 (SetInputFocus), minor code: 0
OpenGL vendor string:                   Intel Open Source Technology Center
OpenGL renderer string:                 Mesa DRI Intel(R) Sandybridge Mobile 
OpenGL version string:                  3.0 Mesa 11.0.2
OpenGL shading language version string: 1.30
Driver:                                 Intel
GPU class:                              SandyBridge
OpenGL version:                         3.0
GLSL version:                           1.30
Mesa version:                           11.0.2
X server version:                       1.17.2
Linux kernel version:                   4.2
Requires strict binding:                yes
GLSL shaders:                           yes
Texture NPOT support:                   yes
Virtual Machine:                        no
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2034, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2035, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2036, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2037, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2038, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2039, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2044, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2054, resource id: 0, major code: 14 (GetGeometry), minor code: 0
QXcbConnection: XCB error: 9 (BadDrawable), sequence: 2064, resource id: 0, major code: 14 (GetGeometry), minor code: 0

and between lockscreen start and end kwin writes to .xsession-error:

QXcbConnection: XCB error: 3 (BadWindow), sequence: 10555, resource id: 127926870, major code: 3 (GetWindowAttributes), minor code: 0

Achim
Comment 3 Thomas Lübking 2015-11-02 22:41:25 UTC
patch is to detect "invalid" input windows (it's typically rootWindow()) on unmanaged unmaps and imitate the xcb_focus_in event.


diff --git a/events.cpp b/events.cpp
index a7a3a98..93c5942 100644
--- a/events.cpp
+++ b/events.cpp
@@ -1524,6 +1524,18 @@ bool Unmanaged::windowEvent(xcb_generic_event_t *e)
         // It's of course still possible that we miss the destroy in which case non-fatal
         // X errors are reported to the event loop and logged by Qt.
         QTimer::singleShot(1, this, SLOT(release()));
+        Xcb::CurrentInput currentInput;
+        if (currentInput.isNull() || currentInput->focus == XCB_WINDOW_NONE ||
+            currentInput->focus == XCB_INPUT_FOCUS_POINTER_ROOT ||
+            currentInput->focus == rootWindow()) {
+            AbstractClient *c = workspace()->mostRecentlyActivatedClient();
+            if (c != NULL)
+                workspace()->requestFocus(c, true);
+            else if (workspace()->activateNextClient(NULL))
+                ; // ok, activated
+            else
+                workspace()->focusToNull();
+        }
         break;
     }
     case XCB_CONFIGURE_NOTIFY:
Comment 4 Achim Bohnet 2015-11-03 15:22:19 UTC
Thx Thomas!!!  Fixed here with our patch from comment #3

I've applied the patch to the kwin 5.4.2 Package in kubuntu and after kwin_x11 --replace, the visual indicators of keyboard focus are there again after lock screen ends.  Tried with konsole, kate and chromium.  Thx again!!

Achim
Comment 5 Thomas Lübking 2015-11-04 21:50:16 UTC
Alternative patch (testing the input on every tooltip close isn't exactly a great solution)
XCB_NOTIFY_DETAIL_INFERIOR doesn't seem to make any sense to me, though. "currentInput->focus == rootWindow()" so how the ford can the event->detail be some inferior (ie. subwindow)??

diff --git a/events.cpp b/events.cpp
index a7a3a98..a4c70df 100644
--- a/events.cpp
+++ b/events.cpp
@@ -484,10 +484,10 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
     case XCB_FOCUS_IN: {
         const auto *event = reinterpret_cast<xcb_focus_in_event_t*>(e);
         if (event->event == rootWindow()
-                && (event->detail == XCB_NOTIFY_DETAIL_NONE || event->detail == XCB_NOTIFY_DETAIL_POINTER_ROOT)) {
+                && (event->detail == XCB_NOTIFY_DETAIL_NONE || event->detail == XCB_NOTIFY_DETAIL_POINTER_ROOT || event->detail == XCB_NOTIFY_DETAIL_INFERIOR)) {
             Xcb::CurrentInput currentInput;
             updateXTime(); // focusToNull() uses xTime(), which is old now (FocusIn has no timestamp)
-            if (!currentInput.isNull() && (currentInput->focus == XCB_WINDOW_NONE || currentInput->focus == XCB_INPUT_FOCUS_POINTER_ROOT)) {
+            if (!currentInput.isNull() && (currentInput->focus == XCB_WINDOW_NONE || currentInput->focus == XCB_INPUT_FOCUS_POINTER_ROOT || currentInput->focus == rootWindow())) {
                 //kWarning( 1212 ) << "X focus set to None/PointerRoot, reseting focus" ;
                 AbstractClient *c = mostRecentlyActivatedClient();
                 if (c != NULL)
Comment 6 Martin Flöser 2015-11-05 07:29:17 UTC
could we do something from the lock screen? Like actively restoring the focus to the window which used to be the active before lock?
Comment 7 Thomas Lübking 2015-11-05 08:14:25 UTC
Probably.
However that doesn't cover other cases ("I use xscreensaver to lock my screen", "Focus nowhere after fragging stroggs", ...)

The WM should simply not leave the focus nowhere (also to keep global shortcuts usable), broken client or not.

Testing whether the focus is on the rootWindow() (instead of XCB_INPUT_FOCUS_POINTER_ROOT) is explainable as we likely just missed the reversion for the grab (and the focus should not be there), but I'm unsure about the matching XCB_NOTIFY_DETAIL_INFERIOR - could be that this is specific to the reversion...
Comment 8 Thomas Lübking 2015-11-17 20:52:35 UTC
Git commit 37a64dcf5f7cebbb44886561d309e59112ef6afd by Thomas Lübking.
Committed on 17/11/2015 at 20:29.
Pushed by luebking into branch 'master'.

catch lost FOCUS_POINTER_ROOT FOCUS_IN events

it seems we can "loose" focus reversions when the closing client hold a grab
(eg. the screenlocker or some games) thus we catch the typical pattern
(though we don't want the focus on the root anyway)
FIXED-IN: 5.5
REVIEW: 126033

M  +5    -2    events.cpp

http://commits.kde.org/kwin/37a64dcf5f7cebbb44886561d309e59112ef6afd