mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Fix C-g handling with multiple ttys.
src/sysdep.c (init_sys_modes): Disable interrupt and quit keys on secondary terminals. Added a big fat comment about this. lib-src/emacsclient.c (init_signals): Don't pass SIGINT and SIGQUIT to Emacs. src/keyboard.c (interrupt_signal): Exit Emacs if there are no frames on the controlling tty. Otherwise set internal_last_event_frame to the controlling tty's top frame. src/term.c (ring_bell, tty_ring_bell): Don't look at updating_frame. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-52
This commit is contained in:
parent
8f1ce42333
commit
4ca927b4e0
5 changed files with 85 additions and 38 deletions
|
|
@ -133,14 +133,12 @@ THINGS TO DO
|
|||
the fly in write_glyphs, which might be problematic, as color
|
||||
approximation is currently done in lisp (term/tty-colors.el).)
|
||||
|
||||
** frame-creation-function should always create a frame that is on the
|
||||
same display as the selected frame. Maybe frame-creation-function
|
||||
should simply be removed and make-frame changed to do the right
|
||||
thing.
|
||||
|
||||
** Fix interactive use of temacs. There are face-related SEGVs, most
|
||||
likely because of changes in realize_default_face, realize_face.
|
||||
|
||||
** Very strange bug: visible-bell does not work on secondary
|
||||
terminals. This might be something xterm (konsole) specific.
|
||||
|
||||
** Allow opening an X session after -nw.
|
||||
|
||||
** Find out the best way to support suspending Emacs with multiple
|
||||
|
|
@ -149,7 +147,7 @@ THINGS TO DO
|
|||
extend emacsclient to handle suspend/resume. A `kill -STOP' almost
|
||||
works right now.)
|
||||
|
||||
** Exiting Emacs while there are emacsclient frames don't restore the
|
||||
** Exiting Emacs while there are emacsclient frames doesn't restore the
|
||||
ttys to their default states.
|
||||
|
||||
** Move baud_rate to struct display.
|
||||
|
|
@ -182,9 +180,6 @@ THINGS TO DO
|
|||
why raw terminal support is broken again. I really do need to
|
||||
understand input.)
|
||||
|
||||
** Make sure C-g goes to the right frame with ttys. This is hard, as
|
||||
SIGINT doesn't have a tty parameter. :-(
|
||||
|
||||
** I have seen a case when Emacs with multiple ttys fell into a loop
|
||||
eating 100% of CPU time. Strace showed this loop:
|
||||
|
||||
|
|
@ -212,7 +207,8 @@ THINGS TO DO
|
|||
about face problems. This can even lock up Emacs (if the recursive
|
||||
frame sets single_kboard). Update: the face problems are caused by
|
||||
bugs in term.el, not in multi-tty. The lockup is caused by
|
||||
single_kboard mode.
|
||||
single_kboard mode, and is not easily solvable. The best thing to
|
||||
do is to simply refuse to create a tty frame of type `eterm'.
|
||||
|
||||
DIARY OF CHANGES
|
||||
----------------
|
||||
|
|
@ -520,4 +516,26 @@ DIARY OF CHANGES
|
|||
|
||||
(Fixed.)
|
||||
|
||||
-- frame-creation-function should always create a frame that is on the
|
||||
same display as the selected frame. Maybe frame-creation-function
|
||||
should simply be removed and make-frame changed to do the right
|
||||
thing.
|
||||
|
||||
(Done, with a nice hack. frame-creation-function is now frame-local.)
|
||||
|
||||
-- Fix C-g on raw ttys.
|
||||
|
||||
(Done. I disabled the interrupt/quit keys on all secondary
|
||||
terminals, so Emacs sees C-g as normal input. This looks like an
|
||||
overkill, because emacsclient has extra code to pass SIGINT to
|
||||
Emacs, so C-g should remain the interrupt/quit key on emacsclient
|
||||
frames. See the next entry why implementing this distinction would
|
||||
be a bad idea.)
|
||||
|
||||
-- Make sure C-g goes to the right frame with ttys. This is hard, as
|
||||
SIGINT doesn't have a tty parameter. :-(
|
||||
|
||||
(Done, the previous change fixes this as a pleasant side effect.)
|
||||
|
||||
|
||||
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
|
||||
|
|
|
|||
|
|
@ -299,8 +299,14 @@ init_signals (void)
|
|||
{
|
||||
/* Set up signal handlers. */
|
||||
signal (SIGWINCH, pass_signal_to_emacs);
|
||||
|
||||
/* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
|
||||
deciding which terminal the signal came from. C-g is now a
|
||||
normal input event on secondary terminals. */
|
||||
#if 0
|
||||
signal (SIGINT, pass_signal_to_emacs);
|
||||
signal (SIGQUIT, pass_signal_to_emacs);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10279,6 +10279,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
|
|||
{
|
||||
/* Must preserve main program's value of errno. */
|
||||
int old_errno = errno;
|
||||
struct display *display;
|
||||
|
||||
#if defined (USG) && !defined (POSIX_SIGNALS)
|
||||
/* USG systems forget handlers when they are used;
|
||||
|
|
@ -10287,24 +10288,27 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
|
|||
signal (SIGQUIT, interrupt_signal);
|
||||
#endif /* USG */
|
||||
|
||||
if (! tty_list)
|
||||
/* See if we have a display on our controlling terminal. */
|
||||
display = get_named_tty_display (NULL);
|
||||
if (!display)
|
||||
{
|
||||
/* If there are no tty frames, exit Emacs.
|
||||
|
||||
Emacs should exit on SIGINT if and only if there are no
|
||||
frames on its controlling tty and the signal came from there.
|
||||
We can check for the first condition, but (alas) not for the
|
||||
second. The best we can do is that we only exit if we are
|
||||
sure that the SIGINT was from the controlling tty, i.e., if
|
||||
there are no termcap frames.
|
||||
*/
|
||||
/* If there are no frames there, let's pretend that we are a
|
||||
well-behaving UN*X program and quit. */
|
||||
Fkill_emacs (Qnil);
|
||||
|
||||
errno = old_errno;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, the SIGINT was probably generated by C-g. */
|
||||
|
||||
/* Set internal_last_event_frame to the top frame of the
|
||||
controlling tty, if we have a frame there. We disable the
|
||||
interrupt key on secondary ttys, so the SIGINT must have come
|
||||
from the controlling tty. */
|
||||
internal_last_event_frame = display->display_info.tty->top_frame;
|
||||
|
||||
handle_interrupt ();
|
||||
handle_interrupt ();
|
||||
|
||||
}
|
||||
|
||||
errno = old_errno;
|
||||
}
|
||||
|
|
@ -10437,7 +10441,7 @@ handle_interrupt ()
|
|||
}
|
||||
|
||||
if (waiting_for_input && !echoing)
|
||||
quit_throw_to_read_char ();
|
||||
quit_throw_to_read_char ();
|
||||
}
|
||||
|
||||
/* Handle a C-g by making read_char return C-g. */
|
||||
|
|
@ -10700,7 +10704,8 @@ init_keyboard ()
|
|||
only if the current session was a tty session. Now an Emacs
|
||||
session may have multiple display types, so we always handle
|
||||
SIGINT. There is special code in interrupt_signal to exit
|
||||
Emacs on SIGINT when there are no termcap frames. */
|
||||
Emacs on SIGINT when there are no termcap frames on the
|
||||
controlling terminal. */
|
||||
signal (SIGINT, interrupt_signal);
|
||||
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
|
||||
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
|
||||
|
|
|
|||
33
src/sysdep.c
33
src/sysdep.c
|
|
@ -1453,11 +1453,34 @@ nil means don't delete them until `list-processes' is run. */);
|
|||
tty.main.c_cflag &= ~PARENB;/* Don't check parity */
|
||||
}
|
||||
#endif
|
||||
tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
|
||||
/* Set up C-g for both SIGQUIT and SIGINT.
|
||||
We don't know which we will get, but we handle both alike
|
||||
so which one it really gives us does not matter. */
|
||||
tty.main.c_cc[VQUIT] = quit_char;
|
||||
if (tty_out->input == stdin)
|
||||
{
|
||||
tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
|
||||
/* Set up C-g for both SIGQUIT and SIGINT.
|
||||
We don't know which we will get, but we handle both alike
|
||||
so which one it really gives us does not matter. */
|
||||
tty.main.c_cc[VQUIT] = quit_char;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We normally don't get interrupt or quit signals from tty
|
||||
devices other than our controlling terminal; therefore,
|
||||
we must handle C-g as normal input. Unfortunately, this
|
||||
means that the interrupt and quit feature must be
|
||||
disabled on secondary ttys, or we would not even see the
|
||||
keypress.
|
||||
|
||||
Note that even though emacsclient could have special code
|
||||
to pass SIGINT to Emacs, we should _not_ enable
|
||||
interrupt/quit keys for emacsclient frames. This means
|
||||
that we can't break out of loops in C code from a
|
||||
secondary tty frame, but we can always decide what
|
||||
display the C-g came from, which is more important from a
|
||||
usability point of view. (Consider the case when two
|
||||
people work together using the same Emacs instance.) */
|
||||
tty.main.c_cc[VINTR] = CDISABLE;
|
||||
tty.main.c_cc[VQUIT] = CDISABLE;
|
||||
}
|
||||
tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
|
||||
tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
|
||||
#ifdef VSWTCH
|
||||
|
|
|
|||
|
|
@ -176,9 +176,7 @@ extern char *tgetstr ();
|
|||
void
|
||||
ring_bell ()
|
||||
{
|
||||
struct frame *f = (updating_frame
|
||||
? updating_frame
|
||||
: XFRAME (selected_frame));
|
||||
struct frame *f = XFRAME (selected_frame);
|
||||
|
||||
if (!NILP (Vring_bell_function))
|
||||
{
|
||||
|
|
@ -206,10 +204,7 @@ ring_bell ()
|
|||
void
|
||||
tty_ring_bell ()
|
||||
{
|
||||
struct frame *f = (updating_frame
|
||||
? updating_frame
|
||||
: XFRAME (selected_frame));
|
||||
|
||||
struct frame *f = XFRAME (selected_frame);
|
||||
struct tty_display_info *tty = FRAME_TTY (f);
|
||||
|
||||
OUTPUT (tty, (tty->TS_visible_bell && visible_bell
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue