komorebi
Windows 平铺式窗口管理器。
komorebi 是一个平铺式窗口管理器,作为微软 Windows 10 及以上版本的桌面窗口管理器的扩展运行。
komorebi 允许您通过命令行界面控制应用程序窗口、虚拟工作区和显示器,可与第三方软件如 whkd
和 AutoHotKey 配合使用,以设置用户自定义的键盘快捷键。
komorebi 旨在默认情况下对操作系统和桌面环境进行尽可能少的修改。用户可以在自己的 komorebi 配置文件中进行此类修改,但这些修改在可预见的将来仍将保持可选和默认关闭状态。
请参阅文档了解如何安装和配置 komorebi,常见工作流程,完整的配置架构参考以及完整的命令行界面参考。
有一个 Discord 服务器可用于 komorebi 相关的讨论、帮助、故障排除等。如果您有任何具体的功能请求或错误报告,请在此存储库中创建一个问题。
有一个 YouTube 频道,我会在那里发布 komorebi 开发视频。如果您想收到即将发布的视频通知,请订阅并开启通知。
komorebi 是一个免费且开源的项目,如果您发现该软件有用并有经济能力,我们鼓励您进行慈善捐款。
在考虑在 GitHub 上赞助我之前,我鼓励您向巴勒斯坦儿童救济基金会进行慈善捐款。
本项目已启用 GitHub 赞助。不幸的是,除了我的感激之情和在 komorebi 现场开发视频和教程结束时的呼喊外,我没有什么特别的东西可以提供。
如果您想赞助或打赏项目但无法使用 GitHub 赞助,您也可以通过 Ko-fi 进行赞助。
安装
提供了一份详细的安装和快速入门指南,展示了如何使用 scoop
、winget
或从源代码构建来开始使用。
与 Fancy Zones 的比较
社区成员 Olge 创建了一个优秀的视频,比较了 Windows 11 的默认窗口管理功能、Fancy Zones 和 komorebi。
如果您不熟悉平铺式窗口管理器,或者正在查看 komorebi 并想知道"这与 Fancy Zones 有何不同?🤔",这个简短的视频将回答您大部分问题。
演示
@amnweb 展示了在 Windows 11 上运行的 komorebi v0.1.28
,启用了窗口边框、非焦点窗口透明度和动画效果,并使用了通过 komorebi 的窗口管理器事件订阅集成的自定义状态栏。
https://github.com/LGUG2Z/komorebi/assets/13164844/21be8dc4-fa76-4f70-9b37-1d316f4b40c2
@haxibami 展示了在 Windows 11 上运行的 komorebi,包含终端模拟器、网络浏览器和代码编辑器。原始视频可以在这里观看。
@aik2mlj 展示了在 Windows 11 上运行的 komorebi,包含多个工作区、终端模拟器、网络浏览器,以及启用了 komorebi 工作区小部件的 yasb 状态栏。原始视频可以在这里观看。
贡献指南
如果您想为 komorebi
做出贡献,请仔细阅读以下指南。
提交规范
- 展平所有
use
语句 - 运行
cargo +stable clippy
并确保在提交前解决所有警告和建议 - 在提交前运行
cargo +nightly fmt --all
以确保一致的格式 - 使用 Commitizen CLI 的
git cz
来准备提交信息 - 在提交信息正文中至少提供一个简短的句子或段落,描述您对所提交更改的思考过程
PR 应仅包含单个功能或错误修复
审查涉及多个不相关功能和代码库部分的拉取请求非常困难。
请不要提交这样的拉取请求;您将被要求将它们分成更小的 PR,每次只处理一个功能或错误修复。
如果您正在处理多个功能和错误修复,我建议您从 master
分支切出一个名为 local-trunk
的分支并保持更新,然后将您正在处理的各个独立分支变基到该分支上,如果您想一起测试它们或创建一个包含所有集成内容的构建。
对代码库的重构必须事先获得批准
komorebi
是一个成熟的代码库,其内部一致性和结构已经在近半个世纪的时间里有机发展。
有无数小时的实时编码视频展示了这个项目的工作,并向新贡献者展示了如何完成从实现新的 komorebic
命令到通过制造商硬件标识符和显卡端口区分显示器等各种基本任务。
对代码库结构的重构不会轻易进行,需要事先讨论和批准。
在收到明确批准或请求之前,请不要开始重构代码库并期望您的更改被整合。
同样,在实现功能和修复错误时,请尽可能遵循代码库的结构,不要将此视为"顺便进行一些重构"的机会。
如果功能和错误修复的 PR 淹没在对代码库结构的大范围更改中,那么审查这些 PR 是极其困难的。
不接受对面向用户界面的破坏性更改
这包括但不限于:
- 所有
komorebic
命令 komorebi.json
架构komorebi-application-specific-configuration
架构
任何用户在升级到新版本的 komorebi
后都不应发现他们的配置文件停止工作。
通常情况下,有办法将最初看似需要破坏用户界面的更改重新构造为增量更改。
对于一些灵感,请看看这个提交,它增加了用户在 komorebi.json
中以十六进制格式指定颜色的功能,同时保留了 RGB 格式。
还有一个过程用于优雅地、非破坏性地弃用不再需要的配置选项。
许可证
komorebi
使用 PolyForm Strict 1.0.0 许可证。从高层次来看,这意味着您可以自由地对 komorebi
进行任何操作,除了再分发或基于该软件分发新作品(即硬分支)。
任何人都可以自由地创建自己的 komorebi
分支,进行针对个人使用或通过拉取请求集成回上游的更改。
请查看 CONTRIBUTING.md 以获取有关 komorebi
代码贡献许可的更多信息。
开发
如果您使用 IntelliJ,应启用以下设置以确保 IDE 能够识别宏生成的代码,以便完成和导航:
- 在"设置 > 语言和框架 > Rust"下将"展开声明性宏"设置为"使用新引擎"
- 启用以下实验性功能:
org.rust.cargo.evaluate.build.scripts
org.rust.macros.proc
日志和调试
komorebi
的日志将追加到 %LOCALAPPDATA%/komorebi/komorebi.log
;此文件永不轮换或覆盖,因此它会一直增长,直到被用户删除。
每当运行 komorebic stop
命令或直接向 komorebi
发送 Ctrl-C 信号时,komorebi
进程会确保在终止前恢复所有隐藏的窗口。
然而,如果你遇到无法恢复的隐藏窗口,komorebi
已知的窗口句柄列表会被存储并持续更新在 %LOCALAPPDATA%/komorebi//komorebi.hwnd.json
中。
恢复窗口
运行 komorebic restore-windows
将读取窗口句柄列表并强制恢复它们,无论主 komorebi
进程是否正在运行。
崩溃和死锁
如果 komorebi
停止响应,很可能是由于崩溃或死锁。在崩溃的情况下,日志中会报告这一情况。在死锁的情况下,日志中不会有任何错误,但进程和日志会看起来冻结。
如果你认为遇到了死锁,可以使用 --features deadlock_detection
编译 komorebi
,然后尝试再次重现死锁。这将每5秒在后台检查死锁,如果发现死锁,相关信息将出现在日志中,可以在提交问题时分享这些信息。
窗口管理器状态和集成
可以使用 komorebic state
命令查询窗口管理器的当前状态,该命令返回 State
结构体的 JSON 表示。
这也可以被轮询以构建进一步的集成和小部件。
窗口管理器事件订阅
命名管道
可以使用命名管道订阅 komorebi
处理的每个 WindowManagerEvent
和 SocketMessage
的通知。
首先,你的应用程序必须创建一个命名管道。创建命名管道后,运行以下命令:
komorebic.exe subscribe-pipe <你的管道名称>
注意,你不需要包含命名管道的完整路径,只需要名称即可。
如果命名管道存在,komorebi
将开始推送成功处理的事件和消息的 JSON 数据:
[JSON 数据示例略]
然后你可以根据 type
键过滤你感兴趣的事件。有关可能的通知类型的完整列表,请参阅 komorebi
中的 WindowManagerEvent
和 komorebi::core
中的 SocketMessage
的枚举变体。
以下是一个使用 nodejs
通过命名管道订阅和过滤事件的示例。
[JavaScript 代码示例略]
Unix 域套接字
可以使用 Unix 域套接字 订阅 komorebi
处理的每个 WindowManagerEvent
和 SocketMessage
的通知。
UDS 也是 komorebi
和 komorebic
之间唯一的通信模式。
首先,你的应用程序必须在 $ENV:LocalAppData\komorebi
中创建一个套接字。创建套接字后,运行以下命令:
komorebic.exe subscribe-socket <你的套接字名称>
如果套接字存在,komorebi 将开始推送成功处理的事件和消息的 JSON 数据,如上面命名管道部分的示例所示。
Rust 客户端
从 v0.1.22
版本开始,可以使用 komorebi-client
crate 在 Rust 代码库中订阅 komorebi
处理的每个 WindowManagerEvent
和 SocketMessage
的通知。
以下是在基本 Rust 应用程序中使用 komorebi-client
的简单示例。
// komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.28"}
use anyhow::Result;
use komorebi_client::Notification;
use komorebi_client::NotificationEvent;
use komorebi_client::UnixListener;
use komorebi_client::WindowManagerEvent;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;
pub fn main() -> anyhow::Result<()> {
let socket = komorebi_client::subscribe(NAME)?;
for incoming in socket.incoming() {
match incoming {
Ok(data) => {
let reader = BufReader::new(data.try_clone()?);
for line in reader.lines().flatten() {
let notification: Notification = match serde_json::from_str(&line) {
Ok(notification) => notification,
Err(error) => {
log::debug!("丢弃格式错误的 komorebi 通知: {error}");
continue;
}
};
// 匹配并过滤所需的通知
}
}
Err(error) => {
log::debug!("{error}");
}
}
}
}
可以在 komokana 中找到一个真实世界的示例。
订阅事件通知架构
可以使用 komorebic notification-schema
命令生成发送给订阅者的事件通知的 JSON Schema。此命令的输出可以重定向到剪贴板或文件,可以与 Quicktype 等服务一起使用,以生成不同编程语言的类型定义。
通过 TCP 通信
可以使用 --tcp-port=N
标志在您选择的端口上可选地公开 TCP 监听器。如果没有向 komorebi
或 komorebic start
提供此标志,则不会创建 TCP 监听器。
创建后,您的客户端可以以与 komorebic
相同的方式向 komorebi
发送任何 SocketMessage。
如果您想创建自己的 komorebic
替代品,其中包含脚本编写和各种中间件层,可以使用此功能。同样,如果您想将 komorebi
与自定义输入处理程序集成,也可以使用此功能。
如果客户端发送无法识别的消息,它将被断开连接,并必须在尝试再次通信之前重新连接。
Socket 消息架构
可以使用 komorebic socket-schema
命令生成用于向 komorebi
发送指令的 socket 消息的 JSON Schema。此命令的输出可以重定向到剪贴板或文件,可以与 Quicktype 等服务一起使用,以生成不同编程语言的类型定义。
致谢
-
首先,感谢我的妻子,既为这个项目命名,也为她在其永无止境的开发过程中的耐心
-
感谢 @sitiom 成为一位模范的开源社区领袖
-
感谢 nog 的开发者们,他们在我之前的工作教会了我无法回报的知识
-
感谢 GlazeWM 的开发者们与我一起推动 Windows 上平铺窗口管理的边界,并具有出色的协作精神
-
感谢 @Ciantic 帮助我将隐藏的虚拟桌面隐藏功能引入
komorebi