从spacemacs迁移到DOOM;company-childframe by @tumashu

我刚刚调试了一下, 直接用 make-frame 创建 frame 就会导致 Mac 顶部有很多全屏工作区被创建. 闪白色的是背景色没有填充.

基于我现在的调试现象, 我大胆猜测是, emacs 默认是全屏的, 然后调用 make-frame 也会创建一个全屏的 frame, 加上背景色没有填充, 就出现了第一次调用, 先白色, 然后叠加Mac 全屏切屏的动画效果.

Mac 下的Emacs最大化右边和下边都有空隙,顶部还有标题栏, 看着不爽.

frame-resize-pixelwise t
default-frame-alist 
'((right-divider-width . 1)
 (bottom-divider-width . 1)
 (background-color . "#181E24")
 (ns-appearance . dark)
 (ns-transparent-titlebar . t)
 (vertical-scroll-bars)
 (left-fringe . 4)
 (right-fringe . 4))

ns-use-native-fullscreen nil
ns-use-fullscreen-animation nil

Preference - general

Preference - dock

隐藏之后就没有缝隙了

1 个赞

@fuxialexander @tumashu 刚刚研究了一下, 给两位提供一下线索 make-frame 在 emacs 全屏的状态就会导致闪烁, 背景颜色闪烁还好修, 主要是 emacs 全屏的时候, make-frame 也会创建一个 全屏的frame, 这样Mac 就会自动把新建的 全屏frame 弄到另外一个 space 中去, 就是这个问题才是大范围闪烁的根本现象.

有三条路可以尝试一下:

  1. make-frame 的时候指定窗口状态, 不要让 frame 进入 fullscreen 状态
  2. make-frame 第一次创建的 frame 直接杀掉, 第二次就好了, 但是这个方法比较脏
  3. 看看底层有没有改进的方法

我觉得你要么用了假的 Emacs,要么用了假的 mac


我用了 Mituharu 的 patch,沒有发現全屏有什麼问題。

1 个赞

我上个星期编译的 emacs git, 上个星期才买的 MacBook Pro.

怎么会是假的呢? :smiley:

以前都全屏用 Emacs , 没有注意到 frame-resize-pixelwise 这个变量, 好东西, 用了果然就没有缝隙了.

为了能够在 Mac 上用 posframe.el , 我重新写了个补丁, Mac 默认最大化, 其他平台默认全屏 Start max status in Mac, then i can use posframe.el with flycheck and… · manateelazycat/lazycat-emacs@430e522 · GitHub

这样我的 flycheck 和 sdcv 的提示都可以用 posframe 了.

在 emacs 社区混了这么长时间, 就 posframe 是我自己的想法,并付诸了实现,我维护的大多数包都是继承了别人的工作。。。。

这个会不会是继承了当前窗口的什么属性导致的?

在创建 frame 的时候我强制设置: fullscreen 为 nil, 看能不能解决你的问题。

或者 make-frame 之前有一些 hook, 你可以尝试在那些 hook 里面做一些手脚, 只要在 frame 显示之前, 通过 set-frame-parameter 函数来调整新建 frame 的参数, 应该可行.

make-frame 应该是集成了当前 frame 的 frame 属性才会导致新建的 frame 也是全屏的.

你弄完了,可以发给git 版, 我帮你测试一下.

修复bug全靠猜。。。。

好了,我刚刚下载了上一个版本, 真的好了, 果然是 fullscreen 取消就好了

我给你点一个赞, 我 Mac Emacs又可以全屏显示了.

你看,这些都不用上游修复了, 我们讨论讨论你自己就修复了, 哈哈哈

我也是看到上面你们的分析,才这么试一试。。。。 都是大家努力的结果

等等, 剧情有反转

@tumashu @fuxialexander 我终于搞定 Mac 下全屏窗口和 make-frame 和平共处的问题了, 见一下代码注释:

;; 在Mac平台, Emacs不能进入Mac原生的全屏模式,否则会导致 `make-frame' 创建时也集成原生全屏属性后造成白屏和左右滑动现象.
;; 所以先设置 `ns-use-native-fullscreen' 和 `ns-use-fullscreen-animation' 禁止Emacs使用Mac原生的全屏模式.
;; 而是采用传统的全屏模式, 传统的全屏模式, 只会在当前工作区全屏,而不是切换到Mac那种单独的全屏工作区,
;; 这样执行 `make-frame' 先关代码或插件时,就不会因为Mac单独工作区左右滑动产生的bug.
;;
;; Mac平台下,不能直接使用 `set-frame-parameter' 和 `fullboth' 来设置全屏,
;; 那样也会导致Mac窗口管理器直接把Emacs窗口扔到单独的工作区, 从而对 `make-frame' 产生同样的Bug.
;; 所以, 启动的时候通过 `set-frame-parameter' 和 `maximized' 先设置Emacs为最大化窗口状态, 启动5秒以后再设置成全屏状态,
;; Mac就不会移动Emacs窗口到单独的工作区, 最终解决Mac平台下原生全屏窗口导致 `make-frame' 左右滑动闪烁的问题.
(setq ns-use-native-fullscreen nil)
(setq ns-use-fullscreen-animation nil)
(set-frame-parameter (selected-frame) 'fullscreen 'maximized)
(run-at-time "5sec" nil (lambda () (set-frame-parameter (selected-frame) 'fullscreen 'fullboth)))

@tumashu 你的旧版和新版都不行, 之所以刚才可以, 是因为刚好和我本地调试的代码重叠了导致的错觉, 你不用更新版本了, 就按照我上面的代码就可以搞定问题.

Mac 的全屏状态的切换一定是有一个周期的, 必须等 Mac 窗口管理器认为一个窗口的状态都初始化好了以后, 才能使用 (set-frame-parameter (selected-frame) 'fullscreen 'fullboth) 让Emacs再进入全屏状态, 否则 Mac 会非常聪明的把你的Emacs窗口移动到单独的工作区.

以上代码完全靠多重交叉测试摸索出来的 workaround, 因为不知道 Mac 窗口管理器的实现原理和源代码, 所以没法从根本上修正问题.