Qt keyboard fixups

Make ASCII control characters ^[, ^\, ^], ^^, and ^_ work on Qt,
at least partly.  Mainly for ^[ to be treated as ESC, which works
if you're aborting a count on the map but doesn't cancel out of
menus [yet?].  I didn't attempt to make ^@ send NUL.

Also, fix the hardcoded macros (activated by F1: rest 100 turns,
F2: search 20 times, and Tab: ^A to do-again).  The first two sent
'n' before the count so wouldn't work as intended with number_pad
off, and the third was executing twice as if Tab sent two ^A's
instead of just one.  Resting and searching might have been getting
duplicated too; I don't know how to simulate the relevant keys.
(I temporarily swapped definitions for F2 and Tab to test the
number_pad fix but hadn't done that earlier when I discovered the
Tab bug.)
This commit is contained in:
PatR
2020-08-30 16:44:39 -07:00
parent 0902d83d52
commit 3cd21e1d4f
2 changed files with 64 additions and 54 deletions
+2 -1
View File
@@ -1,4 +1,4 @@
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.291 $ $NHDT-Date: 1598661087 2020/08/29 00:31:27 $ NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.292 $ $NHDT-Date: 1598831076 2020/08/30 23:44:36 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -392,6 +392,7 @@ Qt: tombstone showed newly constructed date instead of the value set up at
stared at or ignored prior --More-- for long enough on 31 December stared at or ignored prior --More-- for long enough on 31 December
Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu
entry checkboxes internally but didn't redraw the menu to show that entry checkboxes internally but didn't redraw the menu to show that
Qt: fix the F1/F2/Tab macro keys to not require that number_pad be On
Qt+QSX: fix control key Qt+QSX: fix control key
Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's
'O' command to "Game->Run-time options" and entry "Game->Qt settings" 'O' command to "Game->Run-time options" and entry "Game->Qt settings"
+62 -53
View File
@@ -46,7 +46,7 @@ extern int qt_compact_mode;
namespace nethack_qt_ { namespace nethack_qt_ {
// XXX Should be from Options // XXX Should be from Options [or from Qt Settings (aka Preferences)].
// //
// XXX Hmm. Tricky part is that perhaps some macros should only be active // XXX Hmm. Tricky part is that perhaps some macros should only be active
// XXX when a key is about to be gotten. For example, the user could // XXX when a key is about to be gotten. For example, the user could
@@ -55,13 +55,13 @@ namespace nethack_qt_ {
// //
static struct key_macro_rec { static struct key_macro_rec {
int key; int key;
int state; uint state;
const char* macro; const char *macro, *numpad_macro;
} key_macro[]={ } key_macro[]={
{ Qt::Key_F1, 0, "n100." }, // Rest (x100) { Qt::Key_F1, 0U, "100.", "n100." }, // Rest (x100)
{ Qt::Key_F2, 0, "n20s" }, // Search (x20) { Qt::Key_F2, 0U, "20s", "n20s" }, // Search (x20)
{ Qt::Key_Tab, 0, "\001" }, { Qt::Key_Tab, 0U, "\001", "\001" }, // ^A (Do-again)
{ 0, 0, 0 } { 0, 0U, (const char *) 0, (const char *) 0 }
}; };
NetHackQtBind::NetHackQtBind(int& argc, char** argv) : NetHackQtBind::NetHackQtBind(int& argc, char** argv) :
@@ -75,8 +75,9 @@ NetHackQtBind::NetHackQtBind(int& argc, char** argv) :
{ {
QPixmap pm("nhsplash.xpm"); QPixmap pm("nhsplash.xpm");
if ( iflags.wc_splash_screen && !pm.isNull() ) { if ( iflags.wc_splash_screen && !pm.isNull() ) {
splash = new QFrame(NULL, splash = new QFrame(NULL, (Qt::FramelessWindowHint
Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint ); | Qt::X11BypassWindowManagerHint
| Qt::WindowStaysOnTopHint));
QVBoxLayout *vb = new QVBoxLayout(splash); QVBoxLayout *vb = new QVBoxLayout(splash);
QLabel *lsplash = new QLabel(splash); QLabel *lsplash = new QLabel(splash);
vb->addWidget(lsplash); vb->addWidget(lsplash);
@@ -534,19 +535,25 @@ char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, C
message = question; message = question;
} }
if (qt_settings->ynInMessages() && WIN_MESSAGE!=WIN_ERR) { if (qt_settings->ynInMessages() && WIN_MESSAGE != WIN_ERR) {
// Similar to X11 windowport `slow' feature. // Similar to X11 windowport `slow' feature.
int result = -1; int result = -1;
#ifdef USE_POPUPS #ifdef USE_POPUPS
if (choices) { if (choices) {
if (!strcmp(choices,"ynq")) if (!strcmp(choices, "ynq"))
result = QMessageBox::information (NetHackQtBind::mainWidget(),"NetHack",question,"&Yes","&No","&Quit",0,2); result = QMessageBox::information (NetHackQtBind::mainWidget(),
else if (!strcmp(choices,"yn")) "NetHack", question,
result = QMessageBox::information(NetHackQtBind::mainWidget(),"NetHack",question,"&Yes", "&No",0,1); "&Yes", "&No", "&Quit", 0, 2);
else if (!strcmp(choices, "yn"))
result = QMessageBox::information(NetHackQtBind::mainWidget(),
"NetHack", question,
"&Yes", "&No", 0, 1);
else if (!strcmp(choices, "rl")) else if (!strcmp(choices, "rl"))
result = QMessageBox::information(NetHackQtBind::mainWidget(),"NetHack",question,"&Right", "&Left",0,1); result = QMessageBox::information(NetHackQtBind::mainWidget(),
"NetHack", question,
"&Right", "&Left", 0, 1);
if (result >= 0 && result < strlen(choices)) { if (result >= 0 && result < strlen(choices)) {
char yn_resp = choices[result]; char yn_resp = choices[result];
@@ -686,46 +693,48 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event)
{ {
// Ignore Alt-key navigation to menubar, it's annoying when you // Ignore Alt-key navigation to menubar, it's annoying when you
// use Alt-Direction to move around. // use Alt-Direction to move around.
if ( main && event->type()==QEvent::KeyRelease && main==receiver if (main && receiver == main && event->type() == QEvent::KeyRelease
&& ((QKeyEvent*)event)->key() == Qt::Key_Alt ) && ((QKeyEvent *) event)->key() == Qt::Key_Alt)
return true; return true;
bool result=QApplication::notify(receiver,event); bool result = QApplication::notify(receiver, event);
if (event->type()==QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {
QKeyEvent* key_event=(QKeyEvent*)event; QKeyEvent *key_event = (QKeyEvent *) event;
if (!key_event->isAccepted()) { if (!key_event->isAccepted()) {
const int k=key_event->key(); Qt::KeyboardModifiers mod = key_event->modifiers();
bool macro=false; const int k = key_event->key();
for (int i=0; !macro && key_macro[i].key; i++) { for (int i = 0; key_macro[i].key; i++) {
if (key_macro[i].key==k if (key_macro[i].key == k
&& ((key_macro[i].state&key_event->modifiers()) == (unsigned int) key_macro[i].state)) && ((key_macro[i].state & mod) == key_macro[i].state)) {
{ // matched macro; put its expansion into the input buffer
keybuffer.Put(key_macro[i].macro); keybuffer.Put(!::iflags.num_pad ? key_macro[i].macro
macro=true; : key_macro[i].numpad_macro);
} key_event->accept();
} qApp->exit();
QString key=key_event->text(); return true;
QChar ch = !key.isEmpty() ? key.at(0) : 0; }
if (ch > 128) ch = 0; }
if ( ch == 0 && (key_event->modifiers() & Qt::ControlModifier) ) { QString key = key_event->text();
// On Mac, ascii control codes are not sent, force them. QChar ch = !key.isEmpty() ? key.at(0) : 0;
if ( k>=Qt::Key_A && k<=Qt::Key_Z ) if (ch > 128)
ch = k - Qt::Key_A + 1; ch = 0;
} // on OSX, ascii control codes are not sent, force them
if (!macro && ch != 0) { if ((mod & Qt::ControlModifier) != 0) {
bool alt = (key_event->modifiers()&Qt::AltModifier) || if (ch == 0 && k >= Qt::Key_A && k <= Qt::Key_Underscore)
(k >= Qt::Key_0 && k <= Qt::Key_9 && (key_event->modifiers()&Qt::ControlModifier)); ch = (QChar) (k - (Qt::Key_A - 1));
keybuffer.Put(key_event->key(),ch.cell() + (alt ? 128 : 0), }
key_event->modifiers()); // if we have a valid character, queue it up
key_event->accept(); if (ch != 0) {
result=true; bool alt = ((mod & Qt::AltModifier) != 0
} || (k >= Qt::Key_0 && k <= Qt::Key_9
&& (mod & Qt::ControlModifier) != 0));
if (ch != 0 || macro) { keybuffer.Put(k, ch.cell() + (alt ? 128 : 0), (uint) mod);
qApp->exit(); key_event->accept();
} qApp->exit();
} result = true;
}
}
} }
return result; return result;
} }