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 <dctucker@hotmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/edit.c b/src/edit.c
index 672028b..e9a994f 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -2023,7 +2023,7 @@
      * 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 87838b9..4dfa5ff 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -1119,11 +1119,14 @@
     if (state & GDK_MOD1_MASK)
 	modifiers |= MOD_MASK_ALT;
 #if GTK_CHECK_VERSION(2,10,0)
+    if (state & GDK_META_MASK)
+	modifiers |= MOD_MASK_META;
     if (state & GDK_SUPER_MASK)
-	modifiers |= MOD_MASK_META;
-#endif
+	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 c9b1c6c..c124e8b 100644
--- a/src/gui_xim.c
+++ b/src/gui_xim.c
@@ -1063,6 +1063,9 @@
     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 6fddc7f..29e2a05 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -500,8 +500,8 @@
 #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 169eb51..57ee287 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -817,7 +817,7 @@
     {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 @@
     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 @@
 {
     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 e81173d..e361f3e 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -247,6 +247,24 @@
   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 8f13f3f..10a70e3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    58,
+/**/
     57,
 /**/
     56,