#插件 #启动器 #桌面 #前端 #弹出式启动器 #进程间通信 #JSON

onagre-launcher

用于编写 pop-launcher 插件和前端库

2 个稳定版本

1.2.4 2024年2月14日
1.2.3 2024年1月22日

#11 in #前端

Download history 23/week @ 2024-04-08 51/week @ 2024-04-15 24/week @ 2024-04-22 31/week @ 2024-04-29 13/week @ 2024-05-06 45/week @ 2024-05-13 61/week @ 2024-05-20 38/week @ 2024-05-27 41/week @ 2024-06-03 30/week @ 2024-06-10 24/week @ 2024-06-17 43/week @ 2024-06-24 46/week @ 2024-07-01 16/week @ 2024-07-08 32/week @ 2024-07-15 26/week @ 2024-07-22

124 每月下载量
3 crates 中使用

MPL-2.0 许可证

21KB
218

Onagre 启动器

此仓库是 pop-launcher 的分支,移除了所有 PopOs 特定和依赖项。

基于模块化和 IPC 的桌面启动器服务,使用 Rust 编写。桌面启动器可以通过启动 pop-launcher 进程并通过 stdin 和 stdout 管道进行 JSON IPC 通信与该服务接口。根据服务收到的查询,启动器服务还会根据需要启动插件目录中找到的插件。

使用 IPC 可以使每个插件将它们的数据与其他插件进程和前端隔离,这些前端正在与它们交互。如果插件崩溃,启动器将继续正常运行,并优雅地清理崩溃进程。前端和插件也可以用任何语言编写。pop-launcher 将负责在需要时并行调度这些插件的执行。

安装

需要以下依赖项

然后必须与兼容的 pop-launcher 前端一起使用

just build-release # Build
just install # Install locally

如果您正在打包,请在构建 chroot 外运行 just vendor,然后在构建 chroot 内使用 just build-vendored。然后您可以指定自定义根目录和前缀。

# Outside build chroot
just vendor

# Inside build chroot
just build-vendored
sudo just rootdir=debian/tmp prefix=/usr install

想要安装特定插件?移除不需要的插件

just plugins="calc desktop_entries files find pop_shell pulse recent scripts terminal web" install

插件目录

  • 用户本地插件: ~/.local/share/pop-launcher/plugins/{plugin}/
  • 系统管理员的全局安装: /etc/pop-launcher/plugins/{plugin}/
  • 发行版打包: /usr/lib/pop-launcher/plugins/{plugin}/

插件配置

插件元数据定义在 pop-launcher/plugins/{plugin}/plugin.ron

(
    name: "PluginName",
    description: "Plugin Description: Example",
    bin: (
        path: "name-of-executable-in-plugin-folder",
    ),
    icon: Name("icon-name-or-path"),
    // Optional
    query: (
        // Optional -- if we should isolate this plugin when the regex matches
        isolate: true,
        // Optional -- Plugin which searches on empty queries
        persistent: true,
        // Optional -- avoid sorting results from this plugin
        no_sort: true,
        // Optional -- pattern that a query must have to be sent to plugin
        regex: "pattern",
        // Optional -- the launcher should keep a history for this plugin
        history: true,
    )
)

脚本目录

  • 用户本地脚本: ~/.local/share/pop-launcher/scripts
  • 系统管理员的全局安装: /etc/pop-launcher/scripts
  • 分发打包: /usr/lib/pop-launcher/scripts

示例脚本

#!/bin/sh
#
# name: Connect to VPN
# icon: network-vpn
# description: Start VPN
# keywords: vpn start connect

nmcli connection up "vpn-name"

JSON IPC

无论实现前端还是插件,pop-launcher使用的JSON编解码器是基于行的。每一行将包含一个JSON消息,该消息将被序列化为RequestPluginResponseResponse。这些类型可以在docs.rs中参考。IPC基于标准输入/输出流,因此请注意不要将日志写入stdout。

前端JSON IPC

前端将通过stdin管道将Request发送到pop-launcher服务。stdout管道将以Response进行响应。设计前端以异步接受响应是理想的。如果插件支持取消,发送InterruptSearch将取消任何正在进行的搜索。

插件JSON IPC

插件将通过它们的stdin管道从pop-launcher接收Request。它们应该以PluginResponse消息进行响应。

请求

如果您正在编写前端,您将这些事件发送到pop-launcher的stdin管道。如果您正在编写插件,则插件将从其stdin接收这些事件。

pub enum Request {
    /// Activate on the selected item
    Activate(Indice),
    /// Activate a context item on an item.
    ActivateContext { id: Indice, context: Indice },
    /// Perform a tab completion from the selected item
    Complete(Indice),
    /// Request for any context options this result may have.
    Context(Indice),
    /// Request to end the service
    Exit,
    /// Requests to cancel any active searches
    Interrupt,
    /// Request to close the selected item
    Quit(Indice),
    /// Perform a search in our database
    Search(String),
}

JSON等效

  • { "激活":数字}
  • { "激活上下文": { "id":数字, "上下文":id}}
  • { "完成":数字}
  • { "上下文":数字}
  • "退出"
  • "中断"
  • { "退出":数字}
  • { "搜索":字符串}

插件响应

如果您正在编写插件,您应该将这些事件发送到您的stdout。

pub enum PluginResponse {
    /// Append a new search item to the launcher
    Append(PluginSearchResult),
    /// Clear all results in the launcher list
    Clear,
    /// Close the launcher
    Close,
    // Additional options for launching a certain item
    Context {
        id: Indice,
        options: Vec<ContextOption>,
    },
    // Notifies that a .desktop entry should be launched by the frontend.
    DesktopEntry {
        path: PathBuf,
        gpu_preference: GpuPreference,
    },
    /// Update the text in the launcher
    Fill(String),
    /// Indicates that a plugin is finished with its queries
    Finished,
}

JSON等效

  • { "追加":插件搜索结果},
  • "清除",
  • "关闭",
  • { "上下文": { "id":数字, "选项": 数组<上下文选项> }}
  • { "桌面入口": { "路径":字符串, "gpu偏好":Gpu偏好}}
  • { "填充":字符串}
  • "完成"

其中PluginSearchResult

{
    id: number,
    name: string,
    description: string,
    keywords?: Array<string>,
    icon?: IconSource,
    exec?: string,
    window?: [number, number],
}

ContextOption

{
    id: number,
    name: string
}

GpuPreference

"Default" | "NonDefault"

并且IconSource是以下两种之一

  • { "Name": string },其中名称是系统图标,或通过路径引用的图标
  • { "Mime": string },其中mime是mime essence字符串,用于显示基于文件的图标

响应

实现前端的人应监听这些事件

pub enum Response {
    // An operation was performed and the frontend may choose to exit its process.
    Close,
    // Additional options for launching a certain item
    Context {
        id: Indice,
        options: Vec<ContextOption>,
    },
    // Notifies that a .desktop entry should be launched by the frontend.
    DesktopEntry {
        path: PathBuf,
        gpu_preference: GpuPreference,
    },
    // The frontend should clear its search results and display a new list
    Update(Vec<SearchResult>),
    // An item was selected that resulted in a need to autofill the launcher
    Fill(String),
}

JSON等效

  • "关闭"
  • { "桌面入口":字符串}
  • { "更新": 数组<搜索结果>}
  • { "填充":字符串}

其中SearchResult

{
    id: number,
    name: string,
    description: string,
    icon?: IconSource,
    category_icon?: IconSource,
    window?: [number, number]
}

依赖项

~4.5–7MB
~124K SLoC