22

I’m using iTerm2 2.1.1 on Yosemite. No tmux.

When iTerm loses focus (when switched to another application by Cmd-Tab or clicking another window), a ^[[I and ^[[O seems to be sent to the terminal. This causes a ^[[I^[[O to appear, or more frustrating, in Vim, this combination opens another small buffer.

Sample: Pressing Cmd-Tab several times after starting cat

% cat
^[[I^[[O^[[I^[[O^[[I^[[O^[[I^[[O^[[I^[[O^[[I^[[O^[[I^[[O^[[I^[[O^[[I

This only happens on iTerm and not on Terminal.app. Also, it reproduces on bash or sh, so it doesn't seem to be a zsh issue. Some Googling suggested that this is a “focus” issue, but what is “focus” in the meanings of a terminal, and is there any way to disable or avoid this?

  • This seems to reproduce when I'm writing Japanese (in Vim), but I'm still not sure what action is the cause... – osyoyu Jun 25 '15 at 0:46
22

According to this:

Add support for reporting focus lost/gained. esc[?1004h turns it on; then the terminal sends esc[I when focusing, esc[O when de-focusing. Send esc[?1004l to disable.

Cmd-R to reset will turn off focus reporting (Thanks to this)

  • 1
    Cmd-R is the magic sequence for me – bruceg Jan 16 '17 at 23:55
11

I don't have a Mac handy to test this answer, but I encounter this problem in XTerm under Linux very occasionally and (assuming iTerm2 respects the same control codes) you might find the fix below helpful.

Run the following shell command inside the terminal where you're seeing the problem:

printf "\e[?1004l"

(Note that the last character there is a lower-case 'ell'.)

This ANSI control sequence is like the one listed in Thomas Dickey's answer, but it turns the feature off (rather than on). It should solve your problem in all applications, not just Vim, by stopping the characters from occurring at all.


On Linux I can demonstrate this control sequence working with the following steps:

  • Run xterm and enable the feature by running printf "\e[?1004h" in it.
  • Run xeyes or some other GUI application from that same XTerm. (For some reason, this effect does not happen for me until the XTerm in question launches an application. Anybody know why?)
  • Repeatedly switch focus into and out of the original XTerm (e.g. by clicking on windows) and see ^[[O and ^[[I being "typed" into the original XTerm.
  • Now close Xeyes, return to the original XTerm, and run printf "\e[?1004l" (to disable the feature, as described in the fix above).
  • Repeat the "run xeyes, switch focus" steps above, but this time see no characters being entered in the terminal.

I personally only see this problem if I've inadvertently dumped binary output to the terminal, but if you're encountering it more regularly you might want to add that printf to your shell's interactive startup script (e.g. ~/.bashrc). There doesn't appear to be any harm (under XTerm at least) to sending the control code if the feature is already disabled, so it should be safe even if you only see this problem sometimes.

If you're concerned about your shell always generating that output, perhaps because you sometimes use it in places that don't handle those control codes well, or if the problem is sometimes triggered after the shell starts up, then you might prefer to set up an alias (e.g. with alias focusfix='printf "\e[?1004l"') to make it more convenient to run manually.

  • I'm running Manjaro linux, Gnome, terminator and oh-my-zsh. This problem was happening to me and this answer helped a lot. – Fabio Montefuscolo May 29 at 15:02
2

The term "focus" refers to which terminal (or window) is currently accepting keyboard and mouse input events. Only one can have focus; there are protocols for establishing how to gain and lose focus in a graphical environment which it would not be helpful to explore.

From the description (see also Tmux current pane indicator when focus regained), it appears that iTerm2 implements this xterm feature:

FocusIn/FocusOut

FocusIn/FocusOut can be combined with any of the mouse events since it uses a different protocol. When set, it causes xterm to send CSI I when the terminal gains focus, and CSI O when it loses focus.

It is enabled by private mode 1004 (added to xterm in 2007, patch #224):

CSI ? Pm h
      DEC Private Mode Set (DECSET).
           Ps = 1 0 0 4  -> Send FocusIn/FocusOut events. 

and may be related to this patch: Vim - Add support for focus reporting mode (DECSET/DECRST 1004) works on xterm compatible terminals, which equates all behavior of "xterm" mouse features in one setting:

/* focus reporting is supported by xterm compatible terminals and tmux. */

So... you could disable that by telling vim that your terminal does not use the xterm mouse protocol. The cited patch tells vim to turn on the FocusIn/FocusOut feature (which should normally be off), and if there is some flaw in its logic, may leave the feature enabled after exiting vim.

While vim is the most likely cause of the mode being enabled, it is possible that some other program (or script) turns it on. As suggested in another answer, you could narrow that down by collecting the output to your terminal using the script program (producing a typescript file). Analyzing that can be time-consuming (and since this site does not appear to support attachments, it does not seem suitable to soliciting detailed discussion). I generally use unmap to transform typescript files into readable form for this purpose.

  • Thanks for your detailed answer. Telling Vim to ignore \e\[O and \e\[I solves this issue in Vim, but not in other applications like cat or in rails server (maybe programs using readline?). – osyoyu Jun 24 '15 at 16:52
  • So ... could anyone tell how exactly "telling Vim to ignore \e[O and \e[I"? – Libin Wen Sep 14 at 13:49
0

To solve this problem, you have to know what program enables focus reporting mode. You should take a log recorded by script(1) command.

  • Is Focus Reporting a feature that is off by default, and turned on by an escape sequence? Actually, I noticed that this issue doesn't happen on a new terminal window, but reproduces after doing something, so I'll try to identify it. – osyoyu Jun 24 '15 at 16:59
-2

I found this question by trying to solve my terminal displaying "^@" when focus was lost.

Reading through the answers, I tried going to iTerm2 preferences -> Profiles -> "Default" -> Session and unchecking: "When idle, send ASCII code 0 every 60 seconds"

Problem solved, hope it helps someone

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.