Commit: patch 9.1.0058: Cannot map Super Keys in GTK UI

9 views
Skip to first unread message

Christian Brabandt

unread,
Jan 25, 2024, 5:00:08 PM1/25/24
to vim...@googlegroups.com
patch 9.1.0058: Cannot map Super Keys in GTK UI

Commit: https://github.com/vim/vim/commit/92e90a1e102825aa9149262cacfc991264db05df
Author: Casey Tucker <dctu...@hotmail.com>
Date: Thu Jan 25 22:44:00 2024 +0100

patch 9.1.0058: Cannot map Super Keys in GTK UI

Problem: Cannot map Super Keys in GTK UI
(Casey Tucker)
Solution: Enable Super Key mappings in GTK using <D-Key>
(Casey Tucker)

As a developer who works in both Mac and Linux using the same keyboard,
it can be frustrating having to remember different key combinations or
having to rely on system utilities to remap keys.

This change allows `<D-z>` `<D-x>` `<D-c>` `<D-v>` etc. to be recognized
by the `map` commands, along with the `<D-S-...>` shifted variants.

```vimrc
if has('gui_gtk')
nnoremap <D-z> u
nnoremap <D-S-Z> <C-r>
vnoremap <D-x> "+d
vnoremap <D-c> "+y
cnoremap <D-v> <C-R>+
inoremap <D-v> <C-o>"+gP
nnoremap <D-v> "+P
vnoremap <D-v> "-d"+P
nnoremap <D-s> :w<CR>
inoremap <D-s> <C-o>:w<CR>
nnoremap <D-w> :q<CR>
nnoremap <D-q> :qa<CR>
nnoremap <D-t> :tabe<CR>
nnoremap <D-S-T> :vs#<CR><C-w>T
nnoremap <D-a> ggVG
vnoremap <D-a> <ESC>ggVG
inoremap <D-a> <ESC>ggVG
nnoremap <D-f> /
nnoremap <D-g> n
nnoremap <D-S-G> N
vnoremap <D-x> "+x
endif
```

closes: #12698

Signed-off-by: Casey Tucker <dctu...@hotmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 9b706ba20..88cf642ca 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt* For Vim version 9.1. Last change: 2024 Jan 23
+*builtin.txt* For Vim version 9.1. Last change: 2024 Jan 25


VIM REFERENCE MANUAL by Bram Moolenaar
@@ -3470,7 +3470,7 @@ getcharmod() *getcharmod()*
32 mouse double click
64 mouse triple click
96 mouse quadruple click (== 32 + 64)
- 128 command (Macintosh only)
+ 128 command (Mac) or super (GTK)
Only the modifiers that have not been included in the
character itself are obtained. Thus Shift-a results in "A"
without a modifier. Returns 0 if no modifiers are used.
diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt
index 185796f63..120d65dc8 100644
--- a/runtime/doc/intro.txt
+++ b/runtime/doc/intro.txt
@@ -1,4 +1,4 @@
-*intro.txt* For Vim version 9.1. Last change: 2023 Nov 18
+*intro.txt* For Vim version 9.1. Last change: 2024 Jan 25


VIM REFERENCE MANUAL by Bram Moolenaar
@@ -475,7 +475,7 @@ notation meaning equivalent decimal value(s) ~
<C-...> control-key *control* *ctrl* *<C-*
<M-...> alt-key or meta-key *meta* *alt* *<M-*
<A-...> same as <M-...> *<A-*
-<D-...> command-key (Macintosh only) *<D-*
+<D-...> command-key (Mac) / super (GTK) *<D-*
<t_xx> key with "xx" entry in termcap
-----------------------------------------------------------------------

diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 7d4d53048..cf83ffc0c 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1,4 +1,4 @@
-*map.txt* For Vim version 9.1. Last change: 2024 Jan 04
+*map.txt* For Vim version 9.1. Last change: 2024 Jan 25


VIM REFERENCE MANUAL by Bram Moolenaar
@@ -21,9 +21,10 @@ manual.
1.9 Using mappings |map-typing|
1.10 Mapping alt-keys |:map-alt-keys|
1.11 Mapping meta-keys |:map-meta-keys|
- 1.12 Mapping in modifyOtherKeys mode |modifyOtherKeys|
- 1.13 Mapping with Kitty keyboard protocol |kitty-keyboard-protocol|
- 1.14 Mapping an operator |:map-operator|
+ 1.12 Mapping super-keys or command keys |:map-super-keys|
+ 1.13 Mapping in modifyOtherKeys mode |modifyOtherKeys|
+ 1.14 Mapping with Kitty keyboard protocol |kitty-keyboard-protocol|
+ 1.15 Mapping an operator |:map-operator|
2. Abbreviations |abbreviations|
3. Local mappings and functions |script-local|
4. User-defined commands |user-commands|
@@ -985,8 +986,17 @@ For the Meta modifier the "T" character is used. For example, to map Meta-b
in Insert mode: >
:imap <T-b> terrible

+1.12 MAPPING SUPER-KEYS or COMMAND-KEYS *:map-super-keys* *:map-cmd-key*

-1.12 MAPPING IN modifyOtherKeys mode *modifyOtherKeys*
+The Super modifier is available in GUI mode (when |gui_running| is 1) for
+GVim on Linux and MacVim on Mac OS. If you're on a Mac, this represents the
+Command key, on Linux with the GTK GUI it represents the Super key.
+The character "D" is used for the Super / Command modifier.
+
+For example, to map Command-b in Insert mode: >
+ :imap <D-b> barritone
+
+1.13 MAPPING IN modifyOtherKeys mode *modifyOtherKeys*

Xterm and a few other terminals can be put in a mode where keys with modifiers
are sent with a special escape code. Vim recognizes these codes and can then
@@ -1048,7 +1058,7 @@ When the 'esckeys' option is off, then modifyOtherKeys will be disabled in
Insert mode to avoid every key with a modifier causing Insert mode to end.


-1.13 MAPPING WITH KITTY KEYBOARD PROTOCOL *kitty-keyboard-protocol*
+1.14 MAPPING WITH KITTY KEYBOARD PROTOCOL *kitty-keyboard-protocol*

If the value of 'term' contains "kitty" then Vim will send out an escape
sequence to enable the Kitty keyboard protocol. This can be changed with the
@@ -1075,7 +1085,7 @@ translated). The meaning of {value}:
previous state is unknown


-1.14 MAPPING AN OPERATOR *:map-operator*
+1.15 MAPPING AN OPERATOR *:map-operator*

An operator is used before a {motion} command. To define your own operator
you must create a mapping that first sets the 'operatorfunc' option and then
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 809c6fd33..9a89916e0 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -2873,6 +2873,7 @@ $quote eval.txt /*$quote*
:map-arguments map.txt /*:map-arguments*
:map-buffer map.txt /*:map-buffer*
:map-cmd map.txt /*:map-cmd*
+:map-cmd-key map.txt /*:map-cmd-key*
:map-commands map.txt /*:map-commands*
:map-expression map.txt /*:map-expression*
:map-local map.txt /*:map-local*
@@ -2885,6 +2886,7 @@ $quote eval.txt /*$quote*
:map-special map.txt /*:map-special*
:map-special-chars map.txt /*:map-special-chars*
:map-special-keys map.txt /*:map-special-keys*
+:map-super-keys map.txt /*:map-super-keys*
:map-undo map.txt /*:map-undo*
:map-unique map.txt /*:map-unique*
:map-verbose map.txt /*:map-verbose*
diff --git a/src/edit.c b/src/edit.c
index 672028bbb..e9a994f6b 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -2023,7 +2023,7 @@ insert_special(
* Only use mod_mask for special keys, to avoid things like <S-Space>,
* unless 'allow_modmask' is TRUE.
*/
-#ifdef MACOS_X
+#if defined(MACOS_X) || defined(FEAT_GUI_GTK)
// Command-key never produces a normal key
if (mod_mask & MOD_MASK_CMD)
allow_modmask = TRUE;
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 87838b948..4dfa5ff3c 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -1119,11 +1119,14 @@ modifiers_gdk2vim(guint state)
if (state & GDK_MOD1_MASK)
modifiers |= MOD_MASK_ALT;
#if GTK_CHECK_VERSION(2,10,0)
- if (state & GDK_SUPER_MASK)
+ if (state & GDK_META_MASK)
modifiers |= MOD_MASK_META;
-#endif
+ if (state & GDK_SUPER_MASK)
+ modifiers |= MOD_MASK_CMD;
+#else
if (state & GDK_MOD4_MASK)
- modifiers |= MOD_MASK_META;
+ modifiers |= MOD_MASK_CMD;
+#endif

return modifiers;
}
diff --git a/src/gui_xim.c b/src/gui_xim.c
index c9b1c6cb4..c124e8b71 100644
--- a/src/gui_xim.c
+++ b/src/gui_xim.c
@@ -1063,6 +1063,9 @@ xim_reset(void)
int
xim_queue_key_press_event(GdkEventKey *event, int down)
{
+#ifdef FEAT_GUI_GTK
+ if (event->state & GDK_SUPER_MASK) return FALSE;
+#endif
if (down)
{
// Workaround GTK2 XIM 'feature' that always converts keypad keys to
diff --git a/src/keymap.h b/src/keymap.h
index 6fddc7f56..29e2a055c 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -500,8 +500,8 @@ enum key_extra
#define MOD_MASK_2CLICK 0x20 // use MOD_MASK_MULTI_CLICK
#define MOD_MASK_3CLICK 0x40 // use MOD_MASK_MULTI_CLICK
#define MOD_MASK_4CLICK 0x60 // use MOD_MASK_MULTI_CLICK
-#ifdef MACOS_X
-# define MOD_MASK_CMD 0x80
+#if defined(MACOS_X) || defined(FEAT_GUI_GTK)
+# define MOD_MASK_CMD 0x80 // aka SUPER
#endif

#define MOD_MASK_MULTI_CLICK (MOD_MASK_2CLICK|MOD_MASK_3CLICK|MOD_MASK_4CLICK)
diff --git a/src/misc2.c b/src/misc2.c
index 169eb5197..57ee287a4 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -817,7 +817,7 @@ static struct modmasktable
{MOD_MASK_MULTI_CLICK, MOD_MASK_2CLICK, (char_u)'2'},
{MOD_MASK_MULTI_CLICK, MOD_MASK_3CLICK, (char_u)'3'},
{MOD_MASK_MULTI_CLICK, MOD_MASK_4CLICK, (char_u)'4'},
-#ifdef MACOS_X
+#if defined(MACOS_X) || defined(FEAT_GUI_GTK)
{MOD_MASK_CMD, MOD_MASK_CMD, (char_u)'D'},
#endif
// 'A' must be the last one
@@ -1130,7 +1130,11 @@ simplify_key(int key, int *modifiers)
int key0;
int key1;

- if (!(*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT)))
+ if (!(*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT
+#ifdef FEAT_GUI_GTK
+ | MOD_MASK_CMD
+#endif
+ )))
return key;

// TAB is a special case
@@ -1582,6 +1586,9 @@ may_remove_shift_modifier(int modifiers, int key)
{
if ((modifiers == MOD_MASK_SHIFT
|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
+#ifdef FEAT_GUI_GTK
+ || modifiers == (MOD_MASK_SHIFT | MOD_MASK_CMD)
+#endif
|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
&& ((key >= '!' && key <= '/')
|| (key >= ':' && key <= 'Z')
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index e81173d2b..e361f3e65 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -247,6 +247,24 @@ func Test_map_meta_multibyte()
iunmap <M-á>
endfunc

+func Test_map_super_quotes()
+ if has('gui_gtk') || has('gui_gtk3') || has("macos")
+ imap <D-"> foo
+ call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
+ call assert_equal("-foo-", getline('$'))
+ set nomodified
+ iunmap <D-">
+ endif
+endfunc
+
+func Test_map_super_multibyte()
+ if has('gui_gtk') || has('gui_gtk3') || has("macos")
+ imap <D-á> foo
+ call assert_match('i <D-á>\s*foo', execute('imap'))
+ iunmap <D-á>
+ endif
+endfunc
+
func Test_abbr_after_line_join()
new
abbr foo bar
diff --git a/src/version.c b/src/version.c
index 8f13f3f18..10a70e3c0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 58,
/**/
57,
/**/
Reply all
Reply to author
Forward
0 new messages