Qt menu sanity

The Qt menu entries which were executing nethack's help command
(the '?' menu) were doing so because their command keystroke was
a meta-character and such characters are being converted to '?'
to indicate an error in conversion to Latin1 character set.  The
old Qt3 code didn't perform any such conversion.

This fix feels fragile because there are two different places
deciding how to disambiguate partial extended commands (the code
for Qt's '#' handling and a new routine in the core).  Qt menus
now send '#' and enough letters to satisfy '#' handling for any
command which uses M-c or has no regular keystroke nor M-c one.
(If it were to send the full extended command name, the letters
after the unambiguous prefix would be left in the input queue to
be processed as subsequent commands.)

There is a fundamental problem that this doesn't address:  if
the player uses BIND directives in the run-time config file, the
Qt menu bindings will break unless the BINDs are all done before
selecting windowtype.  Qt's menu bindings translate a click on
a menu entry into the keystroke used to invoke the corresponding
command, so using BIND to change that after the menus are set up
will result in the wrong commands being executed.
This commit is contained in:
PatR
2020-08-10 07:24:16 -07:00
parent ef9caca4da
commit 264cbed2cc
4 changed files with 79 additions and 6 deletions

View File

@@ -699,16 +699,24 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) :
if (item[i].name) {
char actchar[32];
char menuitem[BUFSZ];
actchar[0] = '\0';
actchar[0] = actchar[1] = '\0';
if (item[i].funct) {
actchar[0] = cmd_from_func(item[i].funct);
actchar[1] = '\0';
/* M-c won't work */
if ((actchar[0] & 0x7f) != actchar[0])
actchar[0] = '\0';
}
if (actchar[0] && !qt_compact_mode)
Sprintf(menuitem, "%s\t%s", item[i].name,
Sprintf(menuitem, "%.50s\t%.9s", item[i].name,
visctrl(actchar[0]));
else
Sprintf(menuitem, "%s", item[i].name);
if (item[i].funct && !actchar[0]) {
actchar[0] = '#';
(void) cmdname_from_func(item[i].funct,
&actchar[1], FALSE);
}
if (actchar[0]) {
QString name = menuitem;
QAction *action = item[i].menu->addAction(name);
@@ -919,6 +927,12 @@ public:
void NetHackQtMainWindow::doMenuItem(QAction *action)
{
/* this converts meta characters to '?'; menu processing has been
changed to send multi-character "#abc" instead (already needed
for commands that didn't have either a regular keystroke or a
meta shortcut); it must send just enough to disambiguate from
other extended command names, otherwise the remainder would be
left in the queue for subsequent handling as additional commands */
doKeys(action->data().toString());
}
@@ -985,6 +999,8 @@ void NetHackQtMainWindow::doGuidebook(bool)
void NetHackQtMainWindow::doKeys(const QString& k)
{
/* [this should probably be using toLocal8Bit();
toAscii() is not offered as an alternative...] */
keysink.Put(k.toLatin1().constData());
qApp->exit();
}