Mercurial > emacs
changeset 1386:5845050f9d5c
* keyboard.c (Vlast_event_frame): Make this variable exist even
when MULTI_FRAME isn't #defined. People might find it
necessary for writing correct programs, even when the programs
don't explicitly use multiple frames.
(read_char, kbd_buffer_store_event, kbd_buffer_get_event): No need
to test MULTI_FRAME before setting Vlast_event_frame.
(syms_of_keyboard): DEFVAR Vlast_event_frame whether or not
MULTI_FRAME is defined.
* keyboard.c: Add switch-frame events.
(Qswitch_frame): New event header symbol.
(head_table): Include Qswitch_frame in the table of event heads.
(kbd_buffer_get_event): Detect when a frame switch has occurred,
and return a frame switch event before the enqueued event.
(make_lispy_switch_frame): New function.
(unread_switch_frame): New variable.
(read_key_sequence): Don't throw away the key sequence if the user
switches frames in the middle of the sequence. Instead, when we
receive a switch-frame event in the middle of a key sequence, save
it, and stuff it into unread_switch_frame when the sequence
is complete.
(read_char): If unread_switch_frame is set, return that value.
(command_loop_1): No need to check Vlast_event_frame and select
new frames here; that's taken care of by switch-frame events now.
(syms_of_keyboard): Initialize and staticpro unread_switch_frame.
* keyboard.c (follow_key, read_key_sequence): Call access_keymap
with T_OK true.
* keyboard.c (apply_modifiers): Copy the value of BASE's
Qevent_kind property to the new symbol.
* keyboard.c (syms_of_keyboard): Qevent_kind should be initialized
to intern ("event-kind"), not intern ("event-type").
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Sun, 11 Oct 1992 06:42:03 +0000 |
parents | a4a205bdd2c1 |
children | 774897fea33a |
files | src/keyboard.c |
diffstat | 1 files changed, 130 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/src/keyboard.c Sun Oct 11 06:40:57 1992 +0000 +++ b/src/keyboard.c Sun Oct 11 06:42:03 1992 +0000 @@ -151,6 +151,11 @@ /* If not Qnil, an object to be read as the next command input. */ Lisp_Object unread_command_char; +/* If not Qnil, this is a switch-frame event which we decided to put + off until the end of a key sequence. This should be read as the + next command input, after any unread_command_char. */ +Lisp_Object unread_switch_frame; + /* Char to use as prefix when a meta character is typed in. This is bound on entry to minibuffer in case ESC is changed there. */ @@ -187,15 +192,16 @@ instead of the actual command. */ Lisp_Object this_command; -#ifdef MULTI_FRAME /* The frame in which the last input event occurred, or Qmacro if the last event came from a macro. command_loop_1 will select this frame before running the command bound to an event sequence, and read_key_sequence will toss the existing prefix if the user starts typing at a - new frame. */ + new frame. + + On a non-multi-frame Emacs, this will be either Qmacro or + selected_frame. */ Lisp_Object Vlast_event_frame; -#endif /* The timestamp of the last input event we received from the X server. X Windows wants this for selection ownership. */ @@ -285,6 +291,8 @@ Lisp_Object Qhthumbleft_part; Lisp_Object Qhthumbright_part; +Lisp_Object Qswitch_frame; + /* Symbols to denote kinds of events. */ Lisp_Object Qfunction_key; Lisp_Object Qmouse_click; @@ -842,12 +850,14 @@ ++num_input_keys; +#if 0 /* This shouldn't be necessary, now that we have switch-frame events. */ #ifdef MULTI_FRAME /* Select the frame that the key sequence came from. */ if (XTYPE (Vlast_event_frame) == Lisp_Frame && XFRAME (Vlast_event_frame) != selected_frame) Fselect_frame (Vlast_event_frame, Qnil); #endif +#endif /* Now we have read a key sequence of length I, or else I is 0 and we found end of file. */ @@ -1136,6 +1146,16 @@ goto from_macro; } + if (!NILP (unread_switch_frame)) + { + c = unread_switch_frame; + unread_switch_frame = Qnil; + + /* This event should make it into this_command_keys, and get echoed + again, so we go to reread, rather than reread_first. */ + goto reread; + } + /* Save outer setjmp data, in case called recursively. */ save_getcjmp (save_jump); @@ -1147,9 +1167,7 @@ if (_setjmp (getcjmp)) { XSET (c, Lisp_Int, quit_char); -#ifdef MULTI_FRAME XSET (Vlast_event_frame, Lisp_Frame, selected_frame); -#endif goto non_reread; } @@ -1462,13 +1480,11 @@ { extern SIGTYPE interrupt_signal (); -#ifdef MULTI_FRAME /* If this results in a quit_char being returned to Emacs as input, set last-event-frame properly. If this doesn't get returned to Emacs as an event, the next event read will set Vlast_event_frame again, so this is safe to do. */ Vlast_event_frame = FRAME_FOCUS_FRAME (event->frame); -#endif last_event_timestamp = event->timestamp; interrupt_signal (); @@ -1509,6 +1525,7 @@ static Lisp_Object make_lispy_event (); static Lisp_Object make_lispy_movement (); static Lisp_Object modify_event_symbol (); +static Lisp_Object make_lispy_switch_frame (); static Lisp_Object kbd_buffer_get_event () @@ -1564,20 +1581,34 @@ mouse movement enabled and available. */ if (kbd_fetch_ptr != kbd_store_ptr) { - if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr = kbd_buffer; - -#ifdef MULTI_FRAME - XSET (Vlast_event_frame, Lisp_Frame, - XFRAME (FRAME_FOCUS_FRAME (kbd_fetch_ptr->frame))); -#endif - - last_event_timestamp = kbd_fetch_ptr->timestamp; - obj = make_lispy_event (kbd_fetch_ptr); - kbd_fetch_ptr->kind = no_event; - kbd_fetch_ptr++; - if (XTYPE (obj) == Lisp_Int) - XSET (obj, Lisp_Int, XINT (obj) & (meta_key ? 0377 : 0177)); + struct input_event *event; + Lisp_Object frame; + + event = ((kbd_fetch_ptr <= kbd_buffer + KBD_BUFFER_SIZE) + ? kbd_fetch_ptr + : kbd_buffer); + + last_event_timestamp = event->timestamp; + XSET (frame, Lisp_Frame, XFRAME (FRAME_FOCUS_FRAME (event->frame))); + + /* If this event is on a different frame, return a switch-frame this + time, and leave the event in the queue for next time. */ + if (! EQ (frame, Vlast_event_frame)) + { + Vlast_event_frame = frame; + obj = make_lispy_switch_frame (frame); + } + else + { + obj = make_lispy_event (event); + if (XTYPE (obj) == Lisp_Int) + XSET (obj, Lisp_Int, XINT (obj) & (meta_key ? 0377 : 0177)); + + /* Wipe out this event, to catch bugs. */ + event->kind = no_event; + + kbd_fetch_ptr = event + 1; + } } else if (do_mouse_tracking && mouse_moved) { @@ -1586,11 +1617,14 @@ unsigned long time; (*mouse_position_hook) (&frame, &x, &y, &time); -#ifdef MULTI_FRAME - XSET (Vlast_event_frame, Lisp_Frame, frame); -#endif - - obj = make_lispy_movement (frame, x, y, time); + + if (frame != XFRAME (Vlast_event_frame)) + { + XSET (Vlast_event_frame, Lisp_Frame, frame); + obj = make_lispy_switch_frame (Vlast_event_frame); + } + else + obj = make_lispy_movement (frame, x, y, time); } else /* We were promised by the above while loop that there was @@ -1898,6 +1932,14 @@ } +/* Construct a switch frame event. */ +static Lisp_Object +make_lispy_switch_frame (frame) + Lisp_Object frame; +{ + return Fcons (Qswitch_frame, Fcons (frame, Qnil)); +} + /* Manipulating modifiers. */ @@ -2122,7 +2164,10 @@ This is like apply_modifiers_uncached, but uses BASE's Qmodifier_cache property, if present. It also builds - Qevent_symbol_elements properties, since it has that info anyway. */ + Qevent_symbol_elements properties, since it has that info anyway. + + apply_modifiers copies the value of BASE's Qevent_kind property to + the modified symbol. */ static Lisp_Object apply_modifiers (modifiers, base) int modifiers; @@ -2131,8 +2176,8 @@ Lisp_Object cache, index, entry; /* The click modifier never figures into cache indices. */ + cache = Fget (base, Qmodifier_cache); XFASTINT (index) = (modifiers & ~click_modifier); - cache = Fget (base, Qmodifier_cache); entry = Fassq (index, cache); if (CONSP (entry)) @@ -2156,6 +2201,9 @@ Fput (new_symbol, Qevent_symbol_elements, Fcons (base, lispy_modifier_list (modifiers))); + /* This symbol is of the same kind as BASE. */ + Fput (new_symbol, Qevent_kind, Fget (new_symbol, Qevent_kind)); + return new_symbol; } } @@ -2710,8 +2758,8 @@ for (i = 0; i < nmaps; i++) if (! NILP (current[i])) { - next[i] = get_keyelt (access_keymap (current[i], - meta_prefix_char)); + next[i] = + get_keyelt (access_keymap (current[i], meta_prefix_char, 1)); /* Note that since we pass the resulting bindings through get_keymap_1, non-prefix bindings for meta-prefix-char @@ -2730,7 +2778,7 @@ { if (! NILP (current[i])) { - defs[i] = get_keyelt (access_keymap (current[i], key)); + defs[i] = get_keyelt (access_keymap (current[i], key, 1)); if (! NILP (defs[i])) first_binding = i; } @@ -2752,7 +2800,7 @@ { if (! NILP (current[i])) { - defs[i] = get_keyelt (access_keymap (current[i], key)); + defs[i] = get_keyelt (access_keymap (current[i], key, 1)); if (! NILP (defs[i])) first_binding = i; } @@ -2843,6 +2891,10 @@ int fkey_start = 0, fkey_end = 0; Lisp_Object fkey_map = Vfunction_key_map; + /* If we receive a ``switch-frame'' event in the middle of a key sequence, + we put it off for later. While we're reading, we keep the event here. */ + Lisp_Object delayed_switch_frame = Qnil; + last_nonmenu_event = Qnil; if (INTERACTIVE) @@ -2935,30 +2987,49 @@ Emacs 18 handles this by returning immediately with a zero, so that's what we'll do. */ if (XTYPE (key) == Lisp_Int && XINT (key) < 0) - return 0; + { + unread_switch_frame = delayed_switch_frame; + return 0; + } Vquit_flag = Qnil; /* Clicks in non-text areas get prefixed by the symbol in their CHAR-ADDRESS field. For example, a click on the mode line is prefixed by the symbol `mode-line'. */ - if (EVENT_HAS_PARAMETERS (key) - && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qmouse_click)) + if (EVENT_HAS_PARAMETERS (key)) { - Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key)); - - if (XTYPE (posn) == Lisp_Symbol) + Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); + if (EQ (kind, Qmouse_click)) { - if (t + 1 >= bufsize) - error ("key sequence too long"); - keybuf[t] = posn; - keybuf[t+1] = key; - mock_input = t + 2; - - goto retry_key; + Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key)); + + if (XTYPE (posn) == Lisp_Symbol) + { + if (t + 1 >= bufsize) + error ("key sequence too long"); + keybuf[t] = posn; + keybuf[t+1] = key; + mock_input = t + 2; + + goto retry_key; + } + } + else if (EQ (kind, Qswitch_frame)) + { + /* If we're at the beginning of a key sequence, go + ahead and return this event. If we're in the + midst of a key sequence, delay it until the end. */ + if (t > 0) + { + delayed_switch_frame = key; + goto retry_key; + } } } +#if 0 /* This shouldn't be necessary any more, now that we have + switch-frame events. */ #ifdef MULTI_FRAME /* What buffer was this event typed/moused at? */ if (used_mouse_menu) @@ -2999,7 +3070,8 @@ goto restart; } -#endif +#endif /* MULTI_FRAME */ +#endif /* 0 */ } first_binding = (follow_key (key, @@ -3087,15 +3159,16 @@ with meta_prefix_char. I hate this. */ if (keybuf[fkey_end] & 0x80) fkey_next = - get_keymap_1 (get_keyelt - (access_keymap (fkey_map, meta_prefix_char)), - 0); + get_keymap_1 + ((get_keyelt + (access_keymap (fkey_map, meta_prefix_char, 1))), + 0); else fkey_next = fkey_map; fkey_next = get_keyelt (access_keymap - (fkey_next, keybuf[fkey_end++] & 0x7f)); + (fkey_next, keybuf[fkey_end++] & 0x7f, 1)); /* If keybuf[fkey_start..fkey_end] is bound in the function key map and it's a suffix of the current @@ -3135,6 +3208,7 @@ ? defs[first_binding] : Qnil); + unread_switch_frame = delayed_switch_frame; return t; } @@ -3773,7 +3847,8 @@ &Qhscrollbar_part, "hscrollbar-part", &Qscrollbar_click, &Qhslider_part, "hslider-part", &Qscrollbar_click, &Qhthumbleft_part, "hthumbleft-part", &Qscrollbar_click, - &Qhthumbright_part,"hthumbright-part", &Qscrollbar_click + &Qhthumbright_part,"hthumbright-part", &Qscrollbar_click, + &Qswitch_frame, "switch-frame", &Qswitch_frame }; syms_of_keyboard () @@ -3802,7 +3877,7 @@ Qvertical_line = intern ("vertical-line"); staticpro (&Qvertical_line); - Qevent_kind = intern ("event-type"); + Qevent_kind = intern ("event-kind"); staticpro (&Qevent_kind); Qevent_symbol_elements = intern ("event-symbol-elements"); staticpro (&Qevent_symbol_elements); @@ -3851,6 +3926,9 @@ mouse_syms = Qnil; staticpro (&mouse_syms); + unread_switch_frame = Qnil; + staticpro (&unread_switch_frame); + defsubr (&Sread_key_sequence); defsubr (&Srecursive_edit); defsubr (&Strack_mouse); @@ -3932,12 +4010,10 @@ "*Number of complete keys read from the keyboard so far."); num_input_keys = 0; -#ifdef MULTI_FRAME DEFVAR_LISP ("last-event-frame", &Vlast_event_frame, "*The frame in which the most recently read event occurred.\n\ If the last event came from a keyboard macro, this is set to `macro'."); Vlast_event_frame = Qnil; -#endif DEFVAR_LISP ("help-char", &help_char, "Character to recognize as meaning Help.\n\