]> granicus.if.org Git - nethack/commitdiff
Qt keyboard fixups
authorPatR <rankin@nethack.org>
Sun, 30 Aug 2020 23:44:39 +0000 (16:44 -0700)
committerPatR <rankin@nethack.org>
Sun, 30 Aug 2020 23:44:39 +0000 (16:44 -0700)
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.)

doc/fixes37.0
win/Qt/qt_bind.cpp

index 6336374f444a569f56640789e52b89bcd262a1d2..a5579a86c224c331d89fa883cf0cc897c6bb349c 100644 (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
 -----------------------------------
@@ -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
 Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu
        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+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's
        'O' command to "Game->Run-time options" and entry "Game->Qt settings"
index ecff16587fbd7db59c96254bec2877d51397d20e..7e849b77be5538158f642240f257256bc7209382 100644 (file)
@@ -46,7 +46,7 @@ extern int qt_compact_mode;
 
 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       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 {
     int key;
-    int state;
-    const charmacro;
+    uint state;
+    const char *macro, *numpad_macro;
 } key_macro[]={
-    { Qt::Key_F1, 0, "n100." }, // Rest (x100)
-    { Qt::Key_F2, 0, "n20s" },  // Search (x20)
-    { Qt::Key_Tab, 0, "\001" },
-    { 0, 0, 0 }
+    { Qt::Key_F1,  0U, "100.", "n100." }, // Rest (x100)
+    { Qt::Key_F2,  0U, "20s",  "n20s"  }, // Search (x20)
+    { Qt::Key_Tab, 0U, "\001", "\001"  }, // ^A (Do-again)
+    { 0, 0U, (const char *) 0, (const char *) 0 }
 };
 
 NetHackQtBind::NetHackQtBind(int& argc, char** argv) :
@@ -75,8 +75,9 @@ NetHackQtBind::NetHackQtBind(int& argc, char** argv) :
 {
     QPixmap pm("nhsplash.xpm");
     if ( iflags.wc_splash_screen && !pm.isNull() ) {
-       splash = new QFrame(NULL,
-           Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint );
+        splash = new QFrame(NULL, (Qt::FramelessWindowHint
+                                   | Qt::X11BypassWindowManagerHint
+                                   | Qt::WindowStaysOnTopHint));
        QVBoxLayout *vb = new QVBoxLayout(splash);
        QLabel *lsplash = new QLabel(splash);
        vb->addWidget(lsplash);
@@ -534,19 +535,25 @@ char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, C
         message = question;
     }
 
-    if (qt_settings->ynInMessages() && WIN_MESSAGE!=WIN_ERR) {
+    if (qt_settings->ynInMessages() && WIN_MESSAGE != WIN_ERR) {
        // Similar to X11 windowport `slow' feature.
 
        int result = -1;
 
 #ifdef USE_POPUPS
         if (choices) {
-            if (!strcmp(choices,"ynq"))
-                result = QMessageBox::information (NetHackQtBind::mainWidget(),"NetHack",question,"&Yes","&No","&Quit",0,2);
-            else if (!strcmp(choices,"yn"))
-                result = QMessageBox::information(NetHackQtBind::mainWidget(),"NetHack",question,"&Yes", "&No",0,1);
+            if (!strcmp(choices, "ynq"))
+                result = QMessageBox::information (NetHackQtBind::mainWidget(),
+                                                   "NetHack", question,
+                                                 "&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"))
-                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)) {
                 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
     // use Alt-Direction to move around.
-    if ( main && event->type()==QEvent::KeyRelease && main==receiver
-           && ((QKeyEvent*)event)->key() == Qt::Key_Alt )
-       return true;
-
-    bool result=QApplication::notify(receiver,event);
-    if (event->type()==QEvent::KeyPress) {
-       QKeyEvent* key_event=(QKeyEvent*)event;
-
-       if (!key_event->isAccepted()) {
-           const int k=key_event->key();
-           bool macro=false;
-           for (int i=0; !macro && key_macro[i].key; i++) {
-               if (key_macro[i].key==k
-                && ((key_macro[i].state&key_event->modifiers()) == (unsigned int) key_macro[i].state))
-               {
-                   keybuffer.Put(key_macro[i].macro);
-                   macro=true;
-               }
-           }
-           QString key=key_event->text();
-           QChar ch = !key.isEmpty() ? key.at(0) : 0;
-           if (ch > 128) ch = 0;
-           if ( ch == 0 && (key_event->modifiers() & Qt::ControlModifier) ) {
-               // On Mac, ascii control codes are not sent, force them.
-               if ( k>=Qt::Key_A && k<=Qt::Key_Z )
-                   ch = k - Qt::Key_A + 1;
-           }
-           if (!macro && ch != 0) {
-               bool alt = (key_event->modifiers()&Qt::AltModifier) ||
-                  (k >= Qt::Key_0 && k <= Qt::Key_9 && (key_event->modifiers()&Qt::ControlModifier));
-               keybuffer.Put(key_event->key(),ch.cell() + (alt ? 128 : 0),
-                   key_event->modifiers());
-               key_event->accept();
-               result=true;
-           }
-
-           if (ch != 0 || macro) {
-               qApp->exit();
-           }
-       }
+    if (main && receiver == main && event->type() == QEvent::KeyRelease
+        && ((QKeyEvent *) event)->key() == Qt::Key_Alt)
+        return true;
+
+    bool result = QApplication::notify(receiver, event);
+    if (event->type() == QEvent::KeyPress) {
+        QKeyEvent *key_event = (QKeyEvent *) event;
+
+        if (!key_event->isAccepted()) {
+            Qt::KeyboardModifiers mod = key_event->modifiers();
+            const int k = key_event->key();
+            for (int i = 0; key_macro[i].key; i++) {
+                if (key_macro[i].key == k
+                    && ((key_macro[i].state & mod) == key_macro[i].state)) {
+                    // matched macro; put its expansion into the input buffer
+                    keybuffer.Put(!::iflags.num_pad ? key_macro[i].macro
+                                  : key_macro[i].numpad_macro);
+                    key_event->accept();
+                    qApp->exit();
+                    return true;
+                }
+            }
+            QString key = key_event->text();
+            QChar ch = !key.isEmpty() ? key.at(0) : 0;
+            if (ch > 128)
+                ch = 0;
+            // on OSX, ascii control codes are not sent, force them
+            if ((mod & Qt::ControlModifier) != 0) {
+                if (ch == 0 && k >= Qt::Key_A && k <= Qt::Key_Underscore)
+                    ch = (QChar) (k - (Qt::Key_A - 1));
+            }
+            // if we have a valid character, queue it up
+            if (ch != 0) {
+                bool alt = ((mod & Qt::AltModifier) != 0
+                            || (k >= Qt::Key_0 && k <= Qt::Key_9
+                                && (mod & Qt::ControlModifier) != 0));
+                keybuffer.Put(k, ch.cell() + (alt ? 128 : 0), (uint) mod);
+                key_event->accept();
+                qApp->exit();
+                result = true;
+            }
+        }
     }
     return result;
 }