开发者

Change Emacs window appearance when it loses focus

When I program I use two screens with Emacs on both with two buffers split in each window totaling 4 open source files on screen at any one time.

I switch between buffers with C-x b and between Windows with Alt-TAB. I change the appearance of buffers when I switch between them by defining different faces for mode-line and mode-line-inactive. But how do I inactivate a buffer when I switch from the Emacs window completely to another Emacs window via Alt-TAB?

It's probably also relevant that I'm using Emacs 23.2.1 on Ubuntu 1开发者_运维问答1.04 with Gnome 2.32.1.

PS: The question How to automatically save files on lose focus in Emacs is after a different goal but with the same original event of "window losing focus".


It may depend on your window manager and how it manages multiple windows, or frames, in emacs parlance. The code below works like a champ in fvwm but not always in gnome.

I map a keystroke, C-o, to go between frames, this helps when you want to go to the other frame but an alt-tab would take you through a number of superfluous apps on the way.

If you're running a single instance of emacs with two frames you could use something like the following:

(defun pgr-previous-frame ()
  "go to the previous frame"
  (interactive)
  (pgr-switch-frame (previous-frame)))

(defun pgr-next-frame ()
  "go to the next frame"
  (interactive)
  (pgr-switch-frame (next-frame)))

(defun pgr-switch-frame (frame)
  "go to the specified frame and raise it"
  ;; reset the frame properties here
  (select-frame frame)     
  (raise-frame frame)
  ;;change the display in some manner here
  )

You could also try adding some advice to raise-frame and lower-frame haven't tried it but it's worth a try.


I really liked @logoscia answer, which allowed me to do this more generic version. It uses the mode-line-inactive face when no focus.

(add-hook 'focus-out-hook
      (lambda ()
        (copy-face 'mode-line '--mode-line-backup)
        (copy-face 'mode-line-inactive 'mode-line)))
(add-hook 'focus-in-hook
      (lambda ()
        (copy-face '--mode-line-backup 'mode-line)))


In Emacs 24.4 and later, you can use focus-in-hook and focus-out-hook. This piece of code seems to work, such that the active window of an inactive frame has the same colour as an inactive window:

(defvar my-mode-line-active-background "gray75")
(defvar my-mode-line-inactive-background "gray40")

(defun my-unhighlight-mode-line ()
  (set-face-attribute 'mode-line nil
                      :background my-mode-line-inactive-background))

(add-hook 'focus-out-hook 'my-unhighlight-mode-line)

(defun my-highlight-mode-line ()
  (set-face-attribute 'mode-line nil
                      :background my-mode-line-active-background))

(add-hook 'focus-in-hook 'my-highlight-mode-line)


I don't know if it can be done only with Emacs, but a possible alternative is running wmctrl in a shell script which perodically checks which window has the focus and if there is a change then it lets Emacs know via emacsclient which can send lisp code to a running Emacs for evaluation:

-e'--eval' Tell Emacs to evaluate some Emacs Lisp code, instead of visiting some files. When this option is given, the arguments to `emacsclient' are interpreted as a list of expressions to evaluate, not as a list of files to visit.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜