ui/gtk.c
--- b/gtk.c 2025-12-08 21:46:00.849740777 +0800
+++ a/gtk.c 2025-12-09 07:21:14.029533173 +0800
@@ -114,7 +114,7 @@
# define VTE_CHECK_VERSION(a, b, c) 0
#endif
-#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
+#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK) // | GDK_MOD1_MASK)
static const guint16 *keycode_map;
static size_t keycode_maplen;
@@ -226,7 +226,7 @@
if (s->ptr_owner != NULL &&
s->ptr_owner->window == NULL) {
- grab = _(" - Press Ctrl+Alt+G to release grab");
+ grab = _(" - Press Ctrl+G to release grab");
}
if (is_paused) {
@@ -1169,6 +1169,11 @@
VirtualConsole *vc = opaque;
int keycode, qcode;
+ int handled = 0;
+ int keydown = 0;
+ static int ralt_down = 0;
+ static int lalt_down = 0;
+
#ifdef G_OS_WIN32
/* on windows, we ought to ignore the reserved key event? */
if (key->hardware_keycode == 0xff)
@@ -1198,6 +1203,609 @@
keycode = gd_get_keycode(key);
qcode = gd_map_keycode(keycode);
+ handled = 0;
+ keydown = (key->type == GDK_KEY_PRESS);
+ //printf("%d, %d\n", qcode, keydown);
+ switch (qcode) {
+ case 3: // LALT
+ lalt_down = keydown;
+ return FALSE;
+ case 22: // RALT
+ ralt_down = keydown;
+ return FALSE;
+ case 5: // LCTRL
+ // Escape
+ //qkbd_state_key_event(vc->gfx.kbd, 8, keydown);
+
+ // LATL
+ qkbd_state_key_event(vc->gfx.kbd, 3, keydown);
+ return TRUE;
+ case 23: // 'q'
+ if (lalt_down) {
+ // '0'
+ qkbd_state_key_event(vc->gfx.kbd, 18, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '^'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 24: // 'w'
+ if (lalt_down) {
+ // '1'
+ qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '|'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 48, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 48, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 25: // 'e'
+ if (lalt_down) {
+ // '2'
+ qkbd_state_key_event(vc->gfx.kbd, 10, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '&'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 26: // 'r'
+ if (lalt_down) {
+ // '3'
+ qkbd_state_key_event(vc->gfx.kbd, 11, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '$'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 27: // 't'
+ if (lalt_down) {
+ // '('
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 17, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 17, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '{'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 33, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 33, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 28: // 'y'
+ if (lalt_down) {
+ // ')'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 18, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 18, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '}'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 34, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 34, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 29: // 'u'
+ if (lalt_down) {
+ // '-'
+ qkbd_state_key_event(vc->gfx.kbd, 19, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '='
+ qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+ handled = 1;
+ }
+ break;
+ case 30: // 'i'
+ if (lalt_down) {
+ // '_'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 19, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 19, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '~'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 47, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 47, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 31: // 'o'
+ if (lalt_down) {
+ // '\''
+ qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '\\'
+ qkbd_state_key_event(vc->gfx.kbd, 48, keydown);
+ handled = 1;
+ }
+ break;
+ case 32: // 'p'
+ if (lalt_down) {
+ // ':'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 45, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 45, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // ';'
+ qkbd_state_key_event(vc->gfx.kbd, 45, keydown);
+ handled = 1;
+ }
+ break;
+ case 36: // 'a'
+ if (lalt_down) {
+ // '@'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 10, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 10, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '%'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 37: // 's'
+ if (lalt_down) {
+ // '4'
+ qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '4'
+ qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+ handled = 1;
+ }
+ break;
+ case 38: // 'd'
+ if (lalt_down) {
+ // '5'
+ qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '5'
+ qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+ handled = 1;
+ }
+ break;
+ case 39: // 'f'
+ if (lalt_down) {
+ // '6'
+ qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '6'
+ qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+ handled = 1;
+ }
+ break;
+ case 40: // 'g'
+ if (lalt_down) {
+ // '*'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '['
+ qkbd_state_key_event(vc->gfx.kbd, 33, keydown);
+ handled = 1;
+ }
+ break;
+ case 41: // 'h'
+ if (lalt_down) {
+ // '#'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 11, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 11, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // ']'
+ qkbd_state_key_event(vc->gfx.kbd, 34, keydown);
+ handled = 1;
+ }
+ break;
+ case 42: // 'j'
+ if (lalt_down) {
+ // '+'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '+'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 43: // 'k'
+ if (lalt_down) {
+ // '"'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '"'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 44: // 'l'
+ if (lalt_down) {
+ // '\''
+ qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '`'
+ qkbd_state_key_event(vc->gfx.kbd, 47, keydown);
+ handled = 1;
+ }
+ break;
+ case 49: // 'z'
+ if (lalt_down) {
+ // '!'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '!'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 50: // 'x'
+ if (lalt_down) {
+ // '7'
+ qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '7'
+ qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+ handled = 1;
+ }
+ break;
+ case 51: // 'c'
+ if (lalt_down) {
+ // '8'
+ qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '8'
+ qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+ handled = 1;
+ }
+ break;
+ case 52: // 'v'
+ if (lalt_down) {
+ // '9'
+ qkbd_state_key_event(vc->gfx.kbd, 17, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '<'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 53: // 'b'
+ if (lalt_down) {
+ // '.'
+ qkbd_state_key_event(vc->gfx.kbd, 57, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '>'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 57, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 57, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 54: // 'n'
+ if (lalt_down) {
+ // ','
+ qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // ','
+ qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+ handled = 1;
+ }
+ break;
+ case 55: // 'm'
+ if (lalt_down) {
+ // '?'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+
+ if (ralt_down) {
+ // '?'
+ if (keydown) {
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+ }
+ handled = 1;
+ }
+ break;
+ case 21: // BACKSPACE
+ if (lalt_down) {
+ // TAB
+ qkbd_state_key_event(vc->gfx.kbd, 22, keydown);
+ handled = 1;
+ }
+ break;
+ case 35: // ENTER
+ if (lalt_down) {
+ // Escape
+ qkbd_state_key_event(vc->gfx.kbd, 8, keydown);
+ handled = 1;
+ }
+ break;
+ case 60: // SPACE
+ if (lalt_down) {
+ // Escape
+ //qkbd_state_key_event(vc->gfx.kbd, 8, keydown);
+
+ if (keydown) {
+ // ALT
+ qkbd_state_key_event(vc->gfx.kbd, 3, keydown);
+ // PrintScr
+ qkbd_state_key_event(vc->gfx.kbd, 80, keydown);
+ }
+ else {
+ qkbd_state_key_event(vc->gfx.kbd, 80, keydown);
+ qkbd_state_key_event(vc->gfx.kbd, 3, keydown);
+ }
+
+ // F1
+ //qkbd_state_key_event(vc->gfx.kbd, 62, keydown);
+
+ // WIN
+ //qkbd_state_key_event(vc->gfx.kbd, 117, keydown);
+
+ handled = 1;
+ }
+ break;
+ case 100: // UP
+ if (lalt_down) {
+ // PageUp
+ qkbd_state_key_event(vc->gfx.kbd, 96, keydown);
+ handled = 1;
+ }
+ break;
+ case 101: // DOWN
+ if (lalt_down) {
+ // PageDown
+ qkbd_state_key_event(vc->gfx.kbd, 97, keydown);
+ handled = 1;
+ }
+ break;
+ case 99: // LEFT
+ if (lalt_down) {
+ // HOME
+ qkbd_state_key_event(vc->gfx.kbd, 95, keydown);
+ handled = 1;
+ }
+ break;
+ case 102: // RIGHT
+ if (lalt_down) {
+ // End
+ qkbd_state_key_event(vc->gfx.kbd, 98, keydown);
+ handled = 1;
+ }
+ break;
+ }
+
+ if (handled) {
+ return TRUE;
+ }
+
trace_gd_key_event(vc->label, keycode, qcode,
(key->type == GDK_KEY_PRESS) ? "down" : "up");