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;
}
-
--- 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