Bug 197686

Summary: Alternate shortcut Escape (Esc) is set but becomes disabled by KMenu activity
Product: [Applications] kgoldrunner Reporter: Ian Wadham <iandw.au>
Component: generalAssignee: Ian Wadham <iandw.au>
Status: RESOLVED UPSTREAM    
Severity: normal CC: cfeck, johannesobermayr, kde-games-bugs
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: Testcase: QMenuBar does not clear focus

Description Ian Wadham 2009-06-24 03:48:10 UTC
Version:           KDE 4.3 SVN (using Devel)
Installed from:    Compiled sources

In KGoldrunner, of which I am author/maintainer, the Pause action has shortcut P (as in KStandardGameAction) and alternate shortcut Escape, set by KShortcut::setAlternate and KAction::setShortcut.  Both work at first, but then Escape becomes disabled after using the menus.  Both have been working fine until at least KDE 4.1.  Here is a set of actions that reproduces the bug 100%, for me and for two other developers:

1. Click on any menu, e.g. "Game", but don't click a menu item.

2. Without letting go of the mouse button, move to an adjacent menu, e.g. "Move", and let it drop down, still without selecting a menu item.

3. After you dismiss the dropped down menu (click somewhere else or ... yes ... press Esc), KGoldrunner's Esc shortcut has been lost.  Esc does not work any more in KGoldrunner till you quit the application and restart.

Another sequence that causes the problem for Johannes Obermayr, but not for me, is as follows:

1. Press "P" or "Esc" for pause
2. Go to menu "Settings -> Configure Shortcuts..."
3. Set for "Pause -> Alternate": "Custom: None"
4. Close this dialog
5. Go to menu "Settings -> Configure Shortcuts..." again
6. Set for "Pause -> Alternate": "Default: Esc"
7. Close this dialog
8. Pressing "Esc" for resume -> won't work ...
9. Closing KGoldrunner and starting it again -> "Esc" works again

It is likely (but I do not know for sure) that Johannes is building with more recent libraries than me.  I am using Qt 4.4.0 and kdelibs from the end of November 2008, just before the KDE 4.2 release.
Comment 1 Ian Wadham 2009-06-24 03:53:21 UTC
Added Johannes Obermayr to CC list.
Comment 2 Ian Wadham 2009-06-24 04:26:20 UTC
See also bug 197686, which may be related.
Comment 3 Ian Wadham 2009-06-24 04:29:04 UTC
Oops! It is bug 197687 that may be related.
Comment 4 Johannes Obermayr 2009-06-25 20:39:50 UTC
"My" 2nd problem is now "fixed" (v4.2.93). Maybe it was a problem in OpenSuSE 11.1...
I am using Qt 4.5.1 and KDE from http://download.opensuse.org/repositories/KDE:/KDE4:/UNSTABLE:/Desktop/openSUSE_11.1/x86_64/ on my "main" computer.
Should I test the other two computers (OpenSuSE i586)?
Comment 5 Ian Wadham 2009-07-15 03:27:47 UTC
Can somebody look at this before KDE 4.3.release?  The Esc (Pause) shortcut becomes disabled unpredictably. This can be a serious impediment to gameplay and, when it happens, deletes a feature that has been in KGoldrunner for years.  The one reproducible case is:

1. Click on any menu, e.g. "Game", but don't click a menu item.

2. Without letting go of the mouse button, move to an adjacent menu, e.g.
"Move", and let it drop down, still without selecting a menu item.

3. After you dismiss the dropped down menu (click somewhere else or ... yes ...
press Esc), KGoldrunner's Esc shortcut has been lost.  Esc does not work any
more in KGoldrunner till you quit the application and restart.

Other cases seem to be related to use of dialogs or KMessageBox, possibly including use of a menu, but I have been unable to pin them down.  Bug 197687 may be related.  Something down there in the KDE 4 basement seems to be grabbing the Esc shortcut and then not releasing it.
Comment 6 Christoph Feck 2009-10-05 17:34:55 UTC
This bug is caused by no other widget available receiving focus, so the menu effectively keeps "selected".

The following patch for KGoldrunner fixes the issue. It may have to be discussed with kdegames maintainers if this, or a similar fix, needs to be added to libkdegames.

Index: kgoldrunner/src/kgrcanvas.cpp
===================================================================
--- kgoldrunner/src/kgrcanvas.cpp       (revision 1031618)
+++ kgoldrunner/src/kgrcanvas.cpp       (working copy)
@@ -73,6 +73,8 @@
 {
     resizeCount = 0;           // IDW

+    setFocusPolicy(Qt::WheelFocus);
+
     kDebug() << "Called KGrCanvas::KGrCanvas ..." << this->size();
     m = new QCursor();         // For handling the mouse.
Comment 7 Ian Wadham 2009-10-06 13:25:42 UTC
Thank you very much for spending time on this, Christoph, it has been "bugging" me for ages ...

The fix works, but it should not AFAICS.  KGrCanvas is a graphics widget and is not designed to receive keystrokes.  It inherits from KGameCanvas (in libkdegames), which inherits from QWidget, and there is no keyPressEvent() implemented.  So having a focus policy for KGrCanvas should be unnecessary.

All keystrokes are handled in KGoldrunner by actions, which are set up in kgoldrunner.cpp which inherits from KXmlGuiWindow.  Maybe it should be the main window which receives all the keystrokes ... and that is what it appears to do, all except for Esc, but only after you hover over the menus without selecting.

I think maybe the setFocusPolicy() fix works because KGrCanvas can then get the keyboard focus but it cannot handle keypress events, so the Esc goes to its parent (the main window), which is where it should have gone in the first place (I am guessing, main window being a black box to me).  I still think the menu code is swallowing Esc somehow.  Note that if you actually make a menu selection, e.g. Help->About KDE, the Esc shortcut for the Pause action remains enabled.

Anyway, I will put setFocusPolicy() in KGrCanvas as a workaround for the time being.  Thanks again for your help, Christoph.
Comment 8 Christoph Feck 2009-10-06 23:57:33 UTC
I could reproduce with a pure Qt application (attached), so the problem is not in KDE. The question is not wether your central widget wants to process key events or not, but wether Qt finds a focusable widget to remove the focus off of the menu bar.

It may actually be a bug in QMenuBar, it could call clearFocus() when detecting that no other widget had focus (it just calls setFocus() on the previously focused widget for certain states).

If you want that fixed upstream, please file a bugreport at Nokia's tasktracker.
Comment 9 Christoph Feck 2009-10-06 23:59:09 UTC
Created attachment 37414 [details]
Testcase: QMenuBar does not clear focus

See comment in source for instructions how the reproduce the bug.
Comment 10 Ian Wadham 2009-10-22 08:31:24 UTC
This bug was reported to Nokia Task Tracker and has today been accepted as task 262507.  A workaround has been committed to trunk/KDE/kdegames/kgoldrunner/src and also to the KDE 4.3.x branch.  Thanks very much for the workaround, Christoph!