Saturday, 19 May 2018

Re: [Rpcemu] RPCEmu 0.9.0 / PipeDream bug

Keyboard patch: Fixes handling of F10 (Windows) and potential stuck keys when a menu is open (all platforms but possibly only an issue on Windows).
Tested on Windows 10/64-bit only. I won't be providing a binary (for various reasons) so you'll either have to patch the source and recompile or wait for an official release.

diff -r b0e396f600d9 src/qt5/main_window.cpp
--- a/src/qt5/main_window.cpp    Sat May 05 21:00:45 2018 +0100
+++ b/src/qt5/main_window.cpp    Sat May 19 18:33:56 2018 +0100
@@ -421,6 +421,8 @@
 void
 MainWindow::keyPressEvent(QKeyEvent *event)
 {
+    if (!accepting_kbd_input()) return ; // Block keyboard input (to non-GUI elements) in problematic cases
+
     // Special case, handle windows menu key as being menu mouse button
     if(Qt::Key_Menu == event->key()) {
         emit this->emulator.mouse_press_signal(Qt::MidButton);
@@ -485,6 +487,8 @@
 void
 MainWindow::keyReleaseEvent(QKeyEvent *event)
 {
+    if (!accepting_kbd_input()) return ; // Block keyboard input (to non-GUI elements) in problematic cases
+
     // Special case, handle windows menu key as being menu mouse button
     if(Qt::Key_Menu == event->key()) {
         emit this->emulator.mouse_release_signal(Qt::MidButton);
@@ -501,6 +505,22 @@
     }
 }
 
+// Check if accepting keyboard input
+bool
+MainWindow::accepting_kbd_input()
+{
+    // Not accepting if any menus open (solves potential 'stuck key' issues)
+    QList<QWidget *> menus = menuBar()->findChildren<QWidget *>() ;
+    QList<QWidget *>::const_iterator iter = menus.constBegin() ;
+    QList<QWidget *>::const_iterator iter_end = menus.constEnd() ;
+    while(iter < iter_end)
+    {
+        if ((*(iter++))->isVisible()) return false ;
+    }
+
+    return true ;
+}
+
 void
 MainWindow::menu_reset()
 {
@@ -1208,8 +1228,8 @@
 /**
  * windows pre event handler used by us to modify some default behaviour
  *
- * Disable the use of the virtual menu key (alt) that otherwise goes off
- * every time someone presses alt in the emulated OS
+ * Disable the use of ALT and F10 on the host which select the menubar
+ * every time they're pressed in the emulated OS
  *
  * @param eventType unused
  * @param message window event MSG struct
@@ -1223,21 +1243,21 @@
     Q_UNUSED(eventType);
 
     MSG *msg = static_cast<MSG*>(message);
+   
+    // Handle 'alt' and F10 key presses directly that would otherwise select the menu
+    // Fake the key press and release and tell windows/qt to not handle it
+    if((msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP) &&
+        (msg->wParam == VK_MENU || msg->wParam == VK_F10))
+    {
+        BYTE scanCode = (BYTE) (msg->lParam >> 16) ;
 
-    // Handle 'alt' key presses that would select the menu
-    // Fake 'alt' key press and release and then tell windows/qt to
-    // not handle it
-    if((msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP)
-        && (msg->wParam == VK_MENU))
-    {
         // Use the code from the qt key press and release handlers
-        // 0x38 is the windows native keycode for alt
         if(msg->message == WM_SYSKEYDOWN) {
-            held_keys.insert(held_keys.end(), 0x38);
-            emit this->emulator.key_press_signal(0x38);
+            held_keys.insert(held_keys.end(), scanCode);
+            emit this->emulator.key_press_signal(scanCode);
         } else {
-            held_keys.remove(0x38);
-            emit this->emulator.key_release_signal(0x38);
+            held_keys.remove(scanCode);
+            emit this->emulator.key_release_signal(scanCode);
         }
         return true;
     }
@@ -1245,4 +1265,4 @@
     // Anything else should be handled by the regular qt and windows handlers
     return false;
 }
-

No comments:

Post a Comment