holo-layer: 一种全新的Emacs增强图层插件

加了, popweb应该也好了。

发现 macos 可以在全屏下使用了,是因为昨天的修改吗?不过还是不够自动化,需要全屏后重启一下 holo-layer

我也试了一下,真的是这次改动导致的,万万没想到,本来是为了隐藏icon的,没想到还有意外收获 :joy:

1 个赞

幸好你发现了这个特性,我感觉macos下的全屏问题可以解决了

  1. 使用 LSBackgroundOnly 或者 LSUIElement 可以实现全屏时使用 holo_layer
  2. 在全屏和窗口模式切换时,使用makeKeyAndOrderFront_ 方法,就可以实现将 holo_layer 一起移动过去。目前简单试了一下,可以

但是目前有一个问题是全屏和窗口模式切换之后,位置会发生偏移,我周末试着解决一下这些问题。

这里顺便说一下,我怎么发现的,发现的过程也挺好玩:

  1. LSBackgroundOnly 这次改动让我意识到,oc 能做的 pyobjc 基本能做到(可惜我 oc 也不会用,但能到处搜一搜)
  2. 我尝试找了一些子进程和父进程怎么用同一个 space,但是没有什么收获
  3. 突然想到截图工具不就是这样实现的么,截图工具可以截取全屏应用的内容,它可以在全屏应用所在的 space 中让你选择截取的区域,这部分也是它的图形界面,我就想看看截图工具怎么做到的。但比较可惜的是,我找到的大部分截图工具都是闭源的,或者是开源但效果不符合要求,所以没有开源代码可供参考
  4. 最后找到一个开源截图工具,正准备尝试效果,突然想到了我用了很久的剪切板工具 clipy,它有能力在全屏应用中展示一个小菜单,用于选择剪切板历史内容,完全符合要求
  5. 它是 swift 写的,可惜我也不懂,翻了很久源码不知道它怎么实现的。最后突然看 LSBackgroundOnly 这个名字,想起来它是 Info.plist 中的,打开 clipyInfo.plist 一看,果然,有 LSUIElement,因为之前我就是通过命令设置 python 的 LSUIElement,实现隐藏 icon,所以我知道他俩应该有点相似,但这个命令每次麻烦,我后面就没有用了。并且我将 clipy 的修改为false之后,clipy也不能全屏使用,进一步说明了这个问题。
    <key>LSUIElement</key>
    <string>1</string>
  1. 到这里只是说明了 LSBackgroundOnly 确实有效果,但是还没解决怎么让它一直显示在前面。不过我在捣鼓 clipy 的时候,发现它的设置窗口,在我切换 space 的时候,居然可以一直保持在前面,剩下的就是找它怎么实现的
  2. 最终在里面找到一个 makeKeyAndOrderFront_ 方法,在 holo_layerupdate_window_info 方法(这个方法在全屏和窗口切换时会调用)中添加了试试,发现果然可以。不过可惜光标位置还有问题,还得再解决之后才能这个生效的快乐了
2 个赞

光标位置的问题应该是emacs的bug,我之前提过,你更新emacs到30的最新版应该就修复了。

如果是在全屏重启一下 holo-layer ,光标是正确的,但如果切换过全屏或窗口后,位置就不正确了

另外,我看到你的帖子了,我很好奇 EmacsMacPluginModule 和 eaf 是怎么设置的,可以在 emacs 全屏时正常运行的。我记得之前 eaf 在全屏的情况下不能正常使用来着

你的emacs版本是最新的30的分支的吗,如果是的话那应该就是其他的问题,我那边修复的是每次在focus emacs的时候会fix emacs 返回的光标位置,使其是对的。然后我获取坐标的方式如下,你可以试下通过这种方式看看获取的坐标是不是正确的:

(defun macos--emacs-point-x ()
  "Return the x coordinate at point, adjusted for visual modes like Olivetti."
  (let ((pos (window-absolute-pixel-position)))
    (car pos)))

(defun macos--emacs-point-y ()
  "Return the y coordinate at point, adjusted for visual modes like Olivetti."
  (let ((pos (window-absolute-pixel-position)))
    (cdr pos)))

嗯嗯,我周末看一下。光标位置我觉得是准确的,应该是holo-layer里面没有更新,从窗口切到全屏之后,光标是不正确的,再切个buffer就好了

另外想请教一下这个原因

大佬有黑客精神, 手动点赞👍

在 macos 中,怎么才能感知到 emacs 全屏和退出全屏呢

光标位置不准确的原因是:全屏的时候不会触发 window-size-change-functions 以及 window-configuration-change-hook,但我也不知道还有什么方法

我这边的做法是增加了post-command-hook,也就是每次触发命令的时候就将位置信息传递给插件进行更新,不知道切换全屏的情况下会不会触发这个hook,目前从效果看应该是触发的。

之前eaf全屏运行位置不对是window-absolute-pixel-position返回了错误的位置信息,然后我提交了bug给emacs的维护者,他们增加了fix位置信息的代码,就是在切换全屏和重新选中emacs的时候重新计算了这个值,所以就好了。

这个我问了下ChatGPT,回答如下,感觉可以试一下:

在 macOS 下,Emacs 进入和退出全屏时,可以通过 window-state-change-functions 钩子来触发回调。这个钩子会在窗口状态发生变化时调用,你可以通过它来检测是否进入或退出全屏模式。

以下是一个简单的示例,用于检测进入和退出全屏状态:

(defun my/fullscreen-change-callback (frame)
  "Callback function to handle fullscreen changes."
  (when (eq (frame-parameter frame 'fullscreen) 'fullboth)
    (message "Entered fullscreen"))
  (when (not (eq (frame-parameter frame 'fullscreen) 'fullboth))
    (message "Exited fullscreen")))

(add-hook 'window-state-change-functions 'my/fullscreen-change-callback)

在这个示例中,my/fullscreen-change-callback 函数会在全屏状态变化时被调用。当 frame-parameter 中的 'fullscreen 参数为 fullboth 时,表示已经进入全屏,否则表示退出了全屏。

你可以根据自己的需求在回调函数中添加更多的处理逻辑。

感谢回答,不过我想问的不是全屏时候光标是否正常的问题,而是整个图层是否会展示在全屏的 space 中。holo-layer 在做 LSBackgroundOnly 改动之前 emacs 全屏时都没有展示,但是 eaf 没有 LSBackgroundOnly 这样的配置,依然可以在全屏时候展示,我是比较好奇怎么做到


感谢,window-state-change-functions 看起来是可以的

我自己的EmacsMacPluginModule是基于原生的main window的content view添加的,也就是选中的那个窗口,所以没问题。

eaf的话是 manateelazycat 大佬写的,具体实现就不太了解了。

1 个赞

更新后会报这个错 Process holo-layer<1> trace/BPT trap: 5 看了一下应该就是调用这个方法 makeKeyAndOrderFront_ 的时候出错的。是因为什么包没有装吗?

什么情况下会出现这个错误呢?有没有更详细一些的错误信息看一下?

pyobjc就可以了,不用安装其他包,这个应该已经安装了

就是安装后直接启动 holo-layer 就会报错,我试了一下把你最新加的逻辑移动到

update 里面就好了,可能是因为 PostGui 这个装饰器吧。我测试用就把那个系统判断暂时先去掉了

这是我的配置

(use-package! holo-layer
  :init
  (setq holo-layer-python-command "~/.venv/venv/bin/python")
  :custom
  (holo-layer-enable-cursor-animation t)
  ;;(holo-layer-enable-place-info t)
  (holo-layer-enable-indent-rainbow t)
  (holo-layer-enable-window-border t)
  (holo-layer-enable-type-animation t)
  (holo-layer-type-animation-style "flame")
  :config
  (holo-layer-enable)
  )

Mac下面 commit 6706cdf 可用,之后的都不可用

6706cdf 之后的没有任何效果。

holo-layer 日志相比较6706cdf 多了一行:

Process holo-layer trace/BPT trap: 5

而且,该buffer里依然有: This process is not trusted! Input event monitoring will not be possible until it is added to accessibility clients.

Emacs版本是 emacs git仓库下载,在brew环境自行编译。

我测试把 holo_layer.py 中 98 行开始的 if 语句块移动到 update 之后的逻辑中就可以了。