42

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?

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

6 Answers 6

44

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)

2
  • 4
    Cmd-R is the magic sequence for me
    – bruceg
    Commented Jan 16, 2017 at 23:55
  • So helpful, thanks. This took me a long time to find so SEO this Google: mac iterm iterm2 display clipboard contents vim ex buffer focus
    – bsb
    Commented Nov 22, 2019 at 9:00
20

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.

1
  • 1
    I'm running Manjaro linux, Gnome, terminator and oh-my-zsh. This problem was happening to me and this answer helped a lot. Commented May 29, 2019 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.

2
  • 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
    Commented Jun 24, 2015 at 16:52
  • So ... could anyone tell how exactly "telling Vim to ignore \e[O and \e[I"?
    – Libin Wen
    Commented Sep 14, 2019 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.

1
  • 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
    Commented Jun 24, 2015 at 16:59
0

Specifically for iTerm, the simplest way to get rid of this issue is to open Preferences -> Advanced, scroll down to Terminal, and set "Apps may turn on Focus Reporting" to "No".

-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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .