【问题标题】:Change Emacs window appearance when it loses focus失去焦点时更改 Emacs 窗口的外观
【发布时间】:2011-09-01 13:50:53
【问题描述】:

当我编程时,我在两个屏幕上都使用 Emacs,两个缓冲区在每个窗口中拆分,任何时候屏幕上总共有 4 个开源文件。

我用C-x b 在缓冲区之间切换,用Alt-TAB 在Windows 之间切换。我通过为mode-linemode-line-inactive 定义不同的面来在它们之间切换时更改缓冲区的外观。但是,当我通过Alt-TAB 从 Emacs 窗口完全切换到另一个 Emacs 窗口时,如何停用缓冲区?

我在带有 Gnome 2.32.1 的 Ubuntu 11.04 上使用 Emacs 23.2.1 可能也相关。

PS:问题How to automatically save files on lose focus in Emacs 是在追求不同的目标,但具有相同的“窗口失去焦点”的原始事件。

【问题讨论】:

  • 首先直截了当地说:一个缓冲区包含一个文件,一个窗口显示一个缓冲区,一个窗口由一个框架显示。使用 Alt-Tab 可以切换帧。也就是说:据我所知,您无法取消选择一个窗口来免费获取您的行为。
  • 感谢您的澄清。我有点滥用术语。我想我用“窗口”来表示窗口或框架。

标签: linux emacs lisp elisp dot-emacs


【解决方案1】:

这可能取决于您的窗口管理器以及它如何管理多个窗口或框架,用 emacs 的说法。下面的代码在 fvwm 中像冠军一样工作,但在 gnome 中并不总是如此。

我映射了一个按键 C-o 以在帧之间移动,当您想要转到另一个帧时,这会有所帮助,但 alt-tab 会在途中带您浏览许多多余的应用程序。

如果您正在运行具有两个框架的单个 emacs 实例,您可以使用如下内容:

(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
  )

您也可以尝试添加一些建议,以提高框架和降低框架没有尝试过,但值得一试。

【讨论】:

  • 此外,FrameMove (emacswiki.org/emacs/FrameMove) 与 WindMove(内置)相结合,在 Emacs 中创建了一种非常直观的在窗口/框架之间导航的方式。
【解决方案2】:

我真的很喜欢 @logoscia 的回答,这让我可以做这个更通用的版本。它在没有焦点时使用mode-line-inactive 面。

(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)))

【讨论】:

    【解决方案3】:

    在 Emacs 24.4 及更高版本中,您可以使用 focus-in-hookfocus-out-hook。这段代码似乎可以工作,使得非活动框架的活动窗口与非活动窗口具有相同的颜色:

    (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)
    

    【讨论】:

      【解决方案4】:

      我不知道它是否只能用 Emacs 来完成,但一个可能的替代方法是在 shell 脚本中运行 wmctrl,它会定期检查哪个窗口具有焦点,如果有变化,那么它会让 Emacs 通过emacsclient 可以将 lisp 代码发送到正在运行的 Emacs 进行评估:

      -e'--eval' 告诉 Emacs 评估一些 Emacs Lisp 代码,而不是访问 一些文件。当给出这个选项时,参数 `emacsclient' 被解释为表达式列表 评估,作为要访问的文件列表。

      【讨论】:

      • 有趣的解决方案,但我希望焦点事件立即更新窗口外观,这需要wmctrl 以极高的速度检查哪些窗口具有焦点。我想知道我是否可以捕捉“焦点变化”事件。
      • shell 脚本只是一个简单的例子。可能有一种方法可以在 X 中订阅窗口更改事件,因此您可以编写一个单独的小程序来订阅这些事件并在 X 回调时通知 emacs。
      猜你喜欢
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多