Handle num lock in chat (#12984)

This commit is contained in:
Jude Melton-Houghton 2022-11-30 10:43:12 -05:00 committed by GitHub
parent 3ff8adf599
commit 055fc69c11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 51 deletions

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#include "gettext.h" #include "gettext.h"
#include "irrlicht_changes/CGUITTFont.h" #include "irrlicht_changes/CGUITTFont.h"
#include "util/string.h"
#include <string> #include <string>
inline u32 clamp_u8(s32 value) inline u32 clamp_u8(s32 value)
@ -436,6 +437,10 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
return true; return true;
} }
// Mac OS sends private use characters along with some keys.
bool has_char = event.KeyInput.Char && !event.KeyInput.Control &&
!iswcntrl(event.KeyInput.Char) && !IS_PRIVATE_USE_CHAR(event.KeyInput.Char);
if (event.KeyInput.Key == KEY_ESCAPE) { if (event.KeyInput.Key == KEY_ESCAPE) {
closeConsoleAtOnce(); closeConsoleAtOnce();
m_close_on_enter = false; m_close_on_enter = false;
@ -445,13 +450,17 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
} }
else if(event.KeyInput.Key == KEY_PRIOR) else if(event.KeyInput.Key == KEY_PRIOR)
{ {
m_chat_backend->scrollPageUp(); if (!has_char) { // no num lock
return true; m_chat_backend->scrollPageUp();
return true;
}
} }
else if(event.KeyInput.Key == KEY_NEXT) else if(event.KeyInput.Key == KEY_NEXT)
{ {
m_chat_backend->scrollPageDown(); if (!has_char) { // no num lock
return true; m_chat_backend->scrollPageDown();
return true;
}
} }
else if(event.KeyInput.Key == KEY_RETURN) else if(event.KeyInput.Key == KEY_RETURN)
{ {
@ -466,53 +475,63 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
} }
else if(event.KeyInput.Key == KEY_UP) else if(event.KeyInput.Key == KEY_UP)
{ {
// Up pressed if (!has_char) { // no num lock
// Move back in history // Up pressed
prompt.historyPrev(); // Move back in history
return true; prompt.historyPrev();
return true;
}
} }
else if(event.KeyInput.Key == KEY_DOWN) else if(event.KeyInput.Key == KEY_DOWN)
{ {
// Down pressed if (!has_char) { // no num lock
// Move forward in history // Down pressed
prompt.historyNext(); // Move forward in history
return true; prompt.historyNext();
return true;
}
} }
else if(event.KeyInput.Key == KEY_LEFT || event.KeyInput.Key == KEY_RIGHT) else if(event.KeyInput.Key == KEY_LEFT || event.KeyInput.Key == KEY_RIGHT)
{ {
// Left/right pressed if (!has_char) { // no num lock
// Move/select character/word to the left depending on control and shift keys // Left/right pressed
ChatPrompt::CursorOp op = event.KeyInput.Shift ? // Move/select character/word to the left depending on control and shift keys
ChatPrompt::CURSOROP_SELECT : ChatPrompt::CursorOp op = event.KeyInput.Shift ?
ChatPrompt::CURSOROP_MOVE; ChatPrompt::CURSOROP_SELECT :
ChatPrompt::CursorOpDir dir = event.KeyInput.Key == KEY_LEFT ? ChatPrompt::CURSOROP_MOVE;
ChatPrompt::CURSOROP_DIR_LEFT : ChatPrompt::CursorOpDir dir = event.KeyInput.Key == KEY_LEFT ?
ChatPrompt::CURSOROP_DIR_RIGHT; ChatPrompt::CURSOROP_DIR_LEFT :
ChatPrompt::CursorOpScope scope = event.KeyInput.Control ? ChatPrompt::CURSOROP_DIR_RIGHT;
ChatPrompt::CURSOROP_SCOPE_WORD : ChatPrompt::CursorOpScope scope = event.KeyInput.Control ?
ChatPrompt::CURSOROP_SCOPE_CHARACTER; ChatPrompt::CURSOROP_SCOPE_WORD :
prompt.cursorOperation(op, dir, scope); ChatPrompt::CURSOROP_SCOPE_CHARACTER;
return true; prompt.cursorOperation(op, dir, scope);
return true;
}
} }
else if(event.KeyInput.Key == KEY_HOME) else if(event.KeyInput.Key == KEY_HOME)
{ {
// Home pressed if (!has_char) { // no num lock
// move to beginning of line // Home pressed
prompt.cursorOperation( // move to beginning of line
ChatPrompt::CURSOROP_MOVE, prompt.cursorOperation(
ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_MOVE,
ChatPrompt::CURSOROP_SCOPE_LINE); ChatPrompt::CURSOROP_DIR_LEFT,
return true; ChatPrompt::CURSOROP_SCOPE_LINE);
return true;
}
} }
else if(event.KeyInput.Key == KEY_END) else if(event.KeyInput.Key == KEY_END)
{ {
// End pressed if (!has_char) { // no num lock
// move to end of line // End pressed
prompt.cursorOperation( // move to end of line
ChatPrompt::CURSOROP_MOVE, prompt.cursorOperation(
ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_MOVE,
ChatPrompt::CURSOROP_SCOPE_LINE); ChatPrompt::CURSOROP_DIR_RIGHT,
return true; ChatPrompt::CURSOROP_SCOPE_LINE);
return true;
}
} }
else if(event.KeyInput.Key == KEY_BACK) else if(event.KeyInput.Key == KEY_BACK)
{ {
@ -530,17 +549,19 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
} }
else if(event.KeyInput.Key == KEY_DELETE) else if(event.KeyInput.Key == KEY_DELETE)
{ {
// Delete or Ctrl-Delete pressed if (!has_char) { // no num lock
// delete character / word to the right // Delete or Ctrl-Delete pressed
ChatPrompt::CursorOpScope scope = // delete character / word to the right
event.KeyInput.Control ? ChatPrompt::CursorOpScope scope =
ChatPrompt::CURSOROP_SCOPE_WORD : event.KeyInput.Control ?
ChatPrompt::CURSOROP_SCOPE_CHARACTER; ChatPrompt::CURSOROP_SCOPE_WORD :
prompt.cursorOperation( ChatPrompt::CURSOROP_SCOPE_CHARACTER;
ChatPrompt::CURSOROP_DELETE, prompt.cursorOperation(
ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_DELETE,
scope); ChatPrompt::CURSOROP_DIR_RIGHT,
return true; scope);
return true;
}
} }
else if(event.KeyInput.Key == KEY_KEY_A && event.KeyInput.Control) else if(event.KeyInput.Key == KEY_KEY_A && event.KeyInput.Control)
{ {
@ -624,7 +645,9 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
bool backwards = event.KeyInput.Shift; bool backwards = event.KeyInput.Shift;
prompt.nickCompletion(names, backwards); prompt.nickCompletion(names, backwards);
return true; return true;
} else if (!iswcntrl(event.KeyInput.Char) && !event.KeyInput.Control) { }
if (has_char) {
prompt.input(event.KeyInput.Char); prompt.input(event.KeyInput.Char);
return true; return true;
} }

@ -41,6 +41,15 @@ class Translations;
(((unsigned int)(x) >= 0x20) && \ (((unsigned int)(x) >= 0x20) && \
( (unsigned int)(x) <= 0x7e)) ( (unsigned int)(x) <= 0x7e))
// Checks whether a value is in a Unicode private use area
#define IS_PRIVATE_USE_CHAR(x) \
(((wchar_t)(x) >= 0xE000 && \
(wchar_t)(x) <= 0xF8FF) || \
((wchar_t)(x) >= 0xF0000 && \
(wchar_t)(x) <= 0xFFFFD) || \
((wchar_t)(x) >= 0x100000 && \
(wchar_t)(x) <= 0x10FFFD)) \
// Checks whether a byte is an inner byte for an utf-8 multibyte sequence // Checks whether a byte is an inner byte for an utf-8 multibyte sequence
#define IS_UTF8_MULTB_INNER(x) \ #define IS_UTF8_MULTB_INNER(x) \
(((unsigned char)(x) >= 0x80) && \ (((unsigned char)(x) >= 0x80) && \