diff options
| -rw-r--r-- | src/keyboard.c | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index e1124a4facd..5a2c7e811bc 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -188,7 +188,8 @@ Lisp_Object last_command; | |||
| 188 | Lisp_Object this_command; | 188 | Lisp_Object this_command; |
| 189 | 189 | ||
| 190 | #ifdef MULTI_FRAME | 190 | #ifdef MULTI_FRAME |
| 191 | /* The frame in which the last input event occurred. | 191 | /* The frame in which the last input event occurred, or Qmacro if the |
| 192 | last event came from a macro. | ||
| 192 | command_loop_1 will select this frame before running the | 193 | command_loop_1 will select this frame before running the |
| 193 | command bound to an event sequence, and read_key_sequence will | 194 | command bound to an event sequence, and read_key_sequence will |
| 194 | toss the existing prefix if the user starts typing at a | 195 | toss the existing prefix if the user starts typing at a |
| @@ -1099,6 +1100,17 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1099 | 1100 | ||
| 1100 | if (!NILP (Vexecuting_macro)) | 1101 | if (!NILP (Vexecuting_macro)) |
| 1101 | { | 1102 | { |
| 1103 | /* We set this to Qmacro; since that's not a frame, nobody will | ||
| 1104 | try to switch frames on us, and the selected window will | ||
| 1105 | remain unchanged. | ||
| 1106 | |||
| 1107 | Since this event came from a macro, it would be misleading to | ||
| 1108 | leave Vlast_event_frame set to whereever the last real event | ||
| 1109 | came from. Normally, command_loop_1 selects | ||
| 1110 | Vlast_event_frame after each command is read, but events read | ||
| 1111 | from a macro should never cause a new frame to be selected. */ | ||
| 1112 | Vlast_event_frame = Qmacro; | ||
| 1113 | |||
| 1102 | if (executing_macro_index >= Flength (Vexecuting_macro)) | 1114 | if (executing_macro_index >= Flength (Vexecuting_macro)) |
| 1103 | { | 1115 | { |
| 1104 | XSET (c, Lisp_Int, -1); | 1116 | XSET (c, Lisp_Int, -1); |
| @@ -1860,10 +1872,19 @@ format_modifiers (modifiers, buf) | |||
| 1860 | { | 1872 | { |
| 1861 | char *p = buf; | 1873 | char *p = buf; |
| 1862 | 1874 | ||
| 1863 | if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } | 1875 | /* Events with the `up' modifier should always be turned into |
| 1864 | if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; } | 1876 | click or drag events. */ |
| 1877 | if (modifiers & up_modifier) | ||
| 1878 | abort (); | ||
| 1879 | |||
| 1880 | if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; } | ||
| 1881 | if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } | ||
| 1882 | if (modifiers & hyper_modifier) { *p++ = 'H'; *p++ = '-'; } | ||
| 1883 | if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; } | ||
| 1865 | if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; } | 1884 | if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; } |
| 1866 | if (modifiers & up_modifier) { *p++ = 'U'; *p++ = '-'; } | 1885 | if (modifiers & super_modifier) { strcpy (p, "super-"); p += 6; } |
| 1886 | if (modifiers & down_modifier) { strcpy (p, "down-"); p += 5; } | ||
| 1887 | if (modifiers & drag_modifier) { strcpy (p, "drag-"); p += 5; } | ||
| 1867 | *p = '\0'; | 1888 | *p = '\0'; |
| 1868 | 1889 | ||
| 1869 | return p - buf; | 1890 | return p - buf; |
| @@ -1872,6 +1893,8 @@ format_modifiers (modifiers, buf) | |||
| 1872 | 1893 | ||
| 1873 | /* Given a symbol whose name begins with modifiers ("C-", "M-", etc), | 1894 | /* Given a symbol whose name begins with modifiers ("C-", "M-", etc), |
| 1874 | return a symbol with the modifiers placed in the canonical order. | 1895 | return a symbol with the modifiers placed in the canonical order. |
| 1896 | Canonical order is alphabetical, except for down and drag, which | ||
| 1897 | always come last. | ||
| 1875 | 1898 | ||
| 1876 | Fdefine_key calls this to make sure that (for example) C-M-foo | 1899 | Fdefine_key calls this to make sure that (for example) C-M-foo |
| 1877 | and M-C-foo end up being equivalent in the keymap. */ | 1900 | and M-C-foo end up being equivalent in the keymap. */ |
| @@ -1895,29 +1918,70 @@ reorder_modifiers (symbol) | |||
| 1895 | if (! (name->size >= 4 && name->data[1] == '-' && name->data[3] == '-')) | 1918 | if (! (name->size >= 4 && name->data[1] == '-' && name->data[3] == '-')) |
| 1896 | return symbol; | 1919 | return symbol; |
| 1897 | 1920 | ||
| 1898 | for (i = 0; i + 1 < name->size && name->data[i + 1] == '-'; i += 2) | 1921 | for (i = 0; i+1 < name->data[i]; ) |
| 1899 | switch (name->data[i]) | 1922 | switch (name->data[i]) |
| 1900 | { | 1923 | { |
| 1901 | case 'M': | 1924 | case 'A': |
| 1902 | not_canonical |= (modifiers & (meta_modifier|ctrl_modifier | 1925 | if (name->data[i] != '-') goto no_more_modifiers; |
| 1903 | |shift_modifier|up_modifier)); | 1926 | not_canonical |= (modifiers & ~(alt_modifier - 1)); |
| 1904 | modifiers |= meta_modifier; | 1927 | modifiers |= alt_modifier; |
| 1928 | i += 2; | ||
| 1905 | break; | 1929 | break; |
| 1906 | 1930 | ||
| 1907 | case 'C': | 1931 | case 'C': |
| 1908 | not_canonical |= (modifiers & | 1932 | if (name->data[i] != '-') goto no_more_modifiers; |
| 1909 | (ctrl_modifier|shift_modifier|up_modifier)); | 1933 | not_canonical |= (modifiers & ~(ctrl_modifier - 1)); |
| 1910 | modifiers |= ctrl_modifier; | 1934 | modifiers |= ctrl_modifier; |
| 1935 | i += 2; | ||
| 1936 | break; | ||
| 1937 | |||
| 1938 | case 'H': | ||
| 1939 | if (name->data[i] != '-') goto no_more_modifiers; | ||
| 1940 | not_canonical |= (modifiers & ~(hyper_modifier - 1)); | ||
| 1941 | modifiers |= hyper_modifier; | ||
| 1942 | i += 2; | ||
| 1943 | break; | ||
| 1944 | |||
| 1945 | case 'M': | ||
| 1946 | if (name->data[i] != '-') goto no_more_modifiers; | ||
| 1947 | not_canonical |= (modifiers & ~(meta_modifier - 1)); | ||
| 1948 | modifiers |= meta_modifier; | ||
| 1949 | i += 2; | ||
| 1911 | break; | 1950 | break; |
| 1912 | 1951 | ||
| 1913 | case 'S': | 1952 | case 'S': |
| 1914 | not_canonical |= (modifiers & (shift_modifier|up_modifier)); | 1953 | if (name->data[i] != '-') goto no_more_modifiers; |
| 1954 | not_canonical |= (modifiers & ~(shift_modifier - 1)); | ||
| 1915 | modifiers |= shift_modifier; | 1955 | modifiers |= shift_modifier; |
| 1956 | i += 2; | ||
| 1957 | break; | ||
| 1958 | |||
| 1959 | case 's': | ||
| 1960 | if (i + 6 > name->size | ||
| 1961 | || strncmp (name->data + i, "super-", 6)) | ||
| 1962 | goto no_more_modifiers; | ||
| 1963 | not_canonical |= (modifiers & ~(super_modifier - 1)); | ||
| 1964 | modifiers |= super_modifier; | ||
| 1965 | i += 6; | ||
| 1916 | break; | 1966 | break; |
| 1917 | 1967 | ||
| 1918 | case 'U': | 1968 | case 'd': |
| 1919 | not_canonical |= (modifiers & (up_modifier)); | 1969 | if (i + 5 > name->size) |
| 1920 | modifiers |= up_modifier; | 1970 | goto no_more_modifiers; |
| 1971 | if (! strncmp (name->data + i, "drag-", 5)) | ||
| 1972 | { | ||
| 1973 | not_canonical |= (modifiers & ~(drag_modifier - 1)); | ||
| 1974 | modifiers |= drag_modifier; | ||
| 1975 | i += 5; | ||
| 1976 | } | ||
| 1977 | else if (! strncmp (name->data + i, "down-", 5)) | ||
| 1978 | { | ||
| 1979 | not_canonical |= (modifiers & ~(down_modifier - 1)); | ||
| 1980 | modifiers |= down_modifier; | ||
| 1981 | i += 5; | ||
| 1982 | } | ||
| 1983 | else | ||
| 1984 | goto no_more_modifiers; | ||
| 1921 | break; | 1985 | break; |
| 1922 | 1986 | ||
| 1923 | default: | 1987 | default: |
| @@ -1933,7 +1997,7 @@ reorder_modifiers (symbol) | |||
| 1933 | use intern here; we have to use Fintern, which expects a genuine | 1997 | use intern here; we have to use Fintern, which expects a genuine |
| 1934 | Lisp_String, and keeps a reference to it. */ | 1998 | Lisp_String, and keeps a reference to it. */ |
| 1935 | { | 1999 | { |
| 1936 | char *new_mods = (char *) alloca (sizeof ("C-M-S-U-")); | 2000 | char *new_mods = (char *) alloca (sizeof ("A-C-H-M-S-super-U-down-drag-")); |
| 1937 | int len = format_modifiers (modifiers, new_mods); | 2001 | int len = format_modifiers (modifiers, new_mods); |
| 1938 | Lisp_Object new_name = make_uninit_string (len + name->size - i); | 2002 | Lisp_Object new_name = make_uninit_string (len + name->size - i); |
| 1939 | 2003 | ||
| @@ -2712,10 +2776,14 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2712 | /* Never change last_event_buffer for using a menu. */ | 2776 | /* Never change last_event_buffer for using a menu. */ |
| 2713 | buf = last_event_buffer; | 2777 | buf = last_event_buffer; |
| 2714 | else if (XTYPE (key) == Lisp_Int || XTYPE (key) == Lisp_Symbol) | 2778 | else if (XTYPE (key) == Lisp_Int || XTYPE (key) == Lisp_Symbol) |
| 2715 | buf = (XBUFFER | 2779 | { |
| 2716 | (XWINDOW | 2780 | buf = ((XTYPE (Vlast_event_frame) == Lisp_Frame) |
| 2717 | (FRAME_SELECTED_WINDOW | 2781 | ? (XBUFFER |
| 2718 | (XFRAME (Vlast_event_frame)))->buffer)); | 2782 | (XWINDOW |
| 2783 | (FRAME_SELECTED_WINDOW | ||
| 2784 | (XFRAME (Vlast_event_frame)))->buffer)) | ||
| 2785 | : last_event_buffer); | ||
| 2786 | } | ||
| 2719 | else if (EVENT_HAS_PARAMETERS (key)) | 2787 | else if (EVENT_HAS_PARAMETERS (key)) |
| 2720 | { | 2788 | { |
| 2721 | Lisp_Object window = EVENT_WINDOW (key); | 2789 | Lisp_Object window = EVENT_WINDOW (key); |
| @@ -3605,7 +3673,8 @@ Polling is automatically disabled in all other cases."); | |||
| 3605 | 3673 | ||
| 3606 | #ifdef MULTI_FRAME | 3674 | #ifdef MULTI_FRAME |
| 3607 | DEFVAR_LISP ("last-event-frame", &Vlast_event_frame, | 3675 | DEFVAR_LISP ("last-event-frame", &Vlast_event_frame, |
| 3608 | "*The frame in which the most recently read event occurred."); | 3676 | "*The frame in which the most recently read event occurred.\n\ |
| 3677 | If the last event came from a keyboard macro, this is set to `macro'."); | ||
| 3609 | Vlast_event_frame = Qnil; | 3678 | Vlast_event_frame = Qnil; |
| 3610 | #endif | 3679 | #endif |
| 3611 | 3680 | ||