ignis

ignis-shLGPL-2.1活跃维护

用 Python 编写和配置的桌面 Shell 组件框架,基于 GTK4 和 Wayland,让 Linux 用户像搭积木一样自定义桌面小部件与状态栏。

A widget framework for building desktop shells, written and configurable in Python

v0.6.0发布于 2026-08-01 13:57 UTC696star +1 / 7 天46fork同步于 2026-11-10 17:56 UTC

怎么上手

由 README 提炼,执行前请确认
README 未给出安装命令,仅指向文档:https://ignis-sh.github.io/ignis
硬件要求按 README 说明

README 未说明硬件要求;仅支持实现 Layer Shell 协议的 Wayland 合成器(如 Sway、Hyprland、COSMIC、KDE Plasma on Wayland),不支持 GNOME Wayland 与 X11。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

用 Python 写和配置的 GTK4 桌面外壳控件框架,帮你快速搭出状态栏等桌面组件

用 Python 编写和配置的桌面 Shell 组件框架,基于 GTK4 和 Wayland,让 Linux 用户像搭积木一样自定义桌面小部件与状态栏。

核心能力

  • 基于 GTK4 构建桌面外壳控件
  • 用 Python 编写并配置界面
  • 内置大量开箱即用的 Services 与 Utilities
  • 灵活组合与操作控件
  • 支持 Layer Shell 协议的 Wayland 合成器

容易踩的坑

项目正在用 Rust 重写(见 rust-rewrite 分支),API 仍可能变动;不支持 GNOME Wayland 和 X11,需在支持 Layer Shell 的 Wayland 合成器上运行;README 未提供安装步骤,需自行查阅官方文档。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.6.0
  1. v0.6.0最新正式版2026-08-01 · 2026-08-01 13:57 UTC

    This is the final release of Ignis implemented in Python before the Rust rewrite.

    If you are on v0.5.1, it is recommended to stick with it and move once the rewrite is complete.

    What's Changed

  2. v0.5.12025-05-28 · 2025-05-28 13:40 UTC
    查看更新说明

    This is primarily a bug-fix release built on top of v0.5, with commits cherry-picked from main.

    New Features

    • Add support for end_char in Utils.send_socket() (#282)

    Fixes

    • (HyprlandService) Rename method to match return type (#223)
    • (TrackedList) Set attribute instead of emitting signals when notifying changes
    • (HyprlandService) Parse event data correctly with multiple ">>" (#222)
    • (HyprlandService) Do not convert workspace id to int if it's empty on "activespecialv2"
    • (SystemTrayService) Do not init item if another task with the same bus name is already running (#224)
    • (NotificationsService) Use correct key when "icon_data" in hints
    • (HyprlandService) Sync HyprlandMonitor active workspace data on workspace change (closes: #231)
    • (HyprlandService) Do not add object if its data is empty (#229)
    • (ListBox) Correct typing for rows property: ListBoxRow -> Gtk.Widget
    • (IgnisApp) Inherit parameters passed to apply_css() in reload_css() (#245)
    • (ListBox) Update rows property when child list is modified via methods (#246)
    • (OptionsGroup) Make to_dict() return all options instead of only modified ones
    • Mark bin/ignis as executable
    • Rename ignis.logging -> ignis.log_utils to avoid naming collision
    • (WifiAccessPoint) Sync connections in _setup()
    • (Window) Improve handling of size changes for dynamic_input_region (#274)
    • (NiriService) Use end character in send_command() (#283)
    • (meson) Correct the project license (closes: #265)

    Other

    • (workflows) Use correct name of the documentation artifact based on doc tag
    • (workflows) Add release.yaml
    • Specify license as text in pyproject.toml
    • Bump to 0.5.1

    Documentation

    • Sync

    Miscellaneous

    • Change project license to LGPL-2.1
  3. v0.52025-03-25 · 2025-03-25 19:48 UTC
    查看更新说明

    It took 3 months to prepare this release and here we go! This update mainly focuses on rethinking and refactoring some parts of Ignis, but it include many new features & fixes too!

    Breaking Changes

    Options

    Options Service is removed, introducing the new OptionManager & Options API instead!

    Now all options for all services of Ignis will be in one place, and one class to manage them all.

    Migration guide:

    • Notification Service: dnd, popup_timeout, max_popups_count are removed, use corresponding options in ignis.options.Options. E.g., replace notifications.dnd with options.notifications.dnd
    • Recorder Service: bitrate, default_file_location, default_filename properties are removed. All the same like with Notification Service.
    • Applications Service: public API hasn't changed
    • Wallpaper Service: wallpaper property is removed. Use options.wallpaper.wallpaper_path.

    If you use Options Service to define your custom options, move to the new OptionsManager API.

    More info is available in the documentation.

    Asyncio

    asyncio integration! Some functions are asynchronous now. Use await or asyncio.create_task() to call them.

    • DBusProxy
      • new_async()
      • get_dbus_property_async()
      • set_dbus_property_async()
    • BluetoothDevice
      • connect_to()
      • disconnect_from()
    • WifiAccessPoint
      • commit_changes_async()
      • connect_to()
      • connect_to_graphical()
      • disconnect_from()
      • forget()
    • EthernetDevice
      • connect_to()
      • disconnect_from()
    • VpnConnection
      • connect_to()
      • disconnect_from()
    • WifiDevice
      • scan()
    • Utils.exec_sh_async()
    • Utils.read_file_async()
    • Utils.write_file_async()
    • Widget.FileDialog.open_dialog()

    Plus, methods of some services are synchronous and have their explicit async versions now.

    Affected methods:

    • MprisPlayer

      • next()
      • previous()
      • pause()
      • play()
      • play_pause()
      • stop()
      • seek()
    • SystemTrayItem

      • activate()
      • secondary_activate()
      • context_menu()
      • scroll()
    • SystemdUnit

      • start()
      • stop()
      • restart()

    This also affects some property setters:

    BacklightDevice.brightness setter is now synchronous, you can use its asynchronous version which is available as usual method: set_brightness_async(). Same for BacklightService.brightness and MprisPlayer.position.

    Explicit GObject Property type

    #157 replaces GObject.Property with the new IgnisProperty class. The main difference with IgnisProperty is that it can determine the property type automatically based on the return type of the getter. This greatly reduces code repetition, as it is sufficient to specify only the return type for the getter function.

    Since properties have explicit types, their value can only be of the that defined type because it is now controlled on the GObject/C side, which doesn't support dynamic types.

    It means you can't set None as a value for a property which type is bool/int/str/float or GObject/GType. If you use .bind(), you have to add an additional check if the new value is None.

    Otherwise, an exception like this will be raised: TypeError: could not convert None to type 'gdouble' when setting property 'IgnisScale.value'

    Hyprland Service moved to GObject-based objects

    #171 brings objects inherited from IgnisGObject for Hyprland Service, replacing usual python dictionaries. This approach allows to bind properties and other GObject features.

    New classes:

    • HyprlandWorkspace
    • HyprlandWindow
    • HyprlandKeyboard

    Migration Guide:

    1. Since these objects are not dictionaries anymore, you have to get properties like usual class attributes:
    # Old
    hyprland.active_workspace["id"]
    # New
    hyprland.active_wor
    
  4. v0.42024-12-30 · 2024-12-30 18:48 UTC
    查看更新说明

    Happy New Year everyone! Bringing you a new update with many new features and fixes...

    Breaking Changes

    • HyprlandIPCNotFoundError doesn't raise during Hyprland Service initialization, use the new HyprlandService.is_available property instead

    New Features

    • feat(nix): remove submodules for nix build (#43)
    • feat: add HyprlandService.is_available property
    • feat: Niri Service (#54)
    • feat: Hyprland keyboard layout widget in example bar (also #54)
    • feat: allow passing **kwargs to Utils.exec_sh()
    • feat: IgnisApp.add_icons() (#53)
    • feat: Power Menu in example bar (#57)
    • feat(network): support wireguard vpn connections (#63)
    • feat: Bluetooth Service (#28)
    • feat(fetch): add cpu_temp property (#73)
    • feat: Systemd Service (#62)
    • feat: Utils.DebounceTask & Utils.debounce (#76)
    • feat(Widget.EventBox): add support for on scroll [right, left] events (#82)
    • feat(network): refactor signal handling (#80)
    • feat: Utils.listen_socket() & Utils.send_socket(): add 'errors' argument
    • feat(logging): log 'Happy New Year!'

    Fixes

    • fix(nix): add gstreamer, gst-plugins, pipewire to buildInputs (#44)
    • fix: UPower Device State always return false (#59)
    • fix: display the latest notification in example bar
    • fix: use the icon provided by a Spotify installation when it is unavailable in the icon theme (#67)
    • fix(nix): prefix PATH instead of overwriting it (#72)
    • fix: Widget.Grid: prevent from calling __apply() two times during init
    • fix(nix): use librsvg pixbuf module loader cache to allow loading SVG icons (#78)
    • fix(notifications): dismiss the oldest popup in the list (0), not the newest (-1)
    • fix(docs): Widget.Window.monitor: move the docstring from the setter to the GObject.Property itself
    • fix(network): use rsn_flags & wpa_flags to check the security protocol of an access point (#86)
    • fix: remove windows gracefully by overriding destroy() and unreliaze() methods
    • fix(network): WifiConnectDialog: use an unique window name based on the bssid (#89)
    • fix(hyprland): use 'errors=ignore' when decoding the response from the socket (closes: https://github.com/linkfrg/ignis/issues/91)
    • fix(niri): use 'errors=ignore' when decoding the response from the socket
    • fix(network): Ethernet: watch for available device connections
    • fix: do not remove window on close request when hide_on_close is True
    • other minor typing and typos fixes

    Misc

    • docs: update user/installation.rst
    • add ruff to dev.txt
    • stubs: remove UPowerGlib.pyi (not required)
    • github(workflows): run ruff & mypy on examples
    • move ruff config to pyproject.toml
    • specify default selection for ruff
    • docs: add a note about symbolic icons in IgnisApp.add_icons()
    • README.md: add note about #60
    • fix(stubs/NM.pyi): typing issue with enum with zero members

    PRs

  5. v0.32024-11-15 · 2024-11-15 23:24 UTC
    查看更新说明

    Breaking Changes

    • fix!(gobject): IgnisGObject.set_property: do not return when a value is None
    • feat!(Utils.ThreadTask): use explicit run()
    • feat!(Utils.FileMonitor): pass self as the first argument to a callback
    • feat!(applications): rename search() -> search_apps(); add support for searching in a custom list of applications (new required argument)

    New Features

    • feat: add Utils.get_ignis_branch() and Utils.get_ignis_commit_msg()
    • feat(cli): print the git branch and the git commit message in --version
    • feat(cli): add systeminfo subcommand
    • feat: add support for custom paths and xml in Utils.load_interface_xml()
    • feat: DBusProxy: add support for system bus
    • feat: DBusProxy: add support for setting dbus properties
    • feat: Backlight Service (#16)
    • feat: add UPower Service (#10, #26)
    • feat(logging): log GTK errors
    • feat: add Utils.send_socket() & Utils.listen_socket()
    • feat(network): add VPN functionality (#29)
    • feat: Widget.Window: add margin properties
    • feat(system tray): SystemTrayItem: add activate(), secondary_activate(), context_menu() and scroll() functions (closes #36)
    • feat(Utils.FileMonitor): add the prevent_gc property

    Fixes

    • fix(Widget.Window): wrong type hint for anchor property;
    • fix(Widget.Window): unset all anchors if the anchor property is set to None
    • fix(hyprland): messages from sockets is limited by the buffer size (1024/4096 bytes)
    • fix(app): reload CSS only on the changes_done_hint event type (closes #18)
    • fix(applications): disable python virtual env for subprocess & set cwd to home dir
    • fix(cli): set prog_name explicitly
    • fix(dbus menu): call AboutToShow on popup (closes #33)
    • fix(notifications): popup_timeout setter function is not working (#38)
    • fix(Utils.FileMonitor): "changed" signal is called only if a callback is present
    • fix: use TypeAlias annotation for classes in Utils

    Other

    • github: add issue forms
    • github(workflows): build documentation on pull requests
    • Package for NixOS (and some fixes for it) (#13, #14, #21, #25)
    • docs: fix incorrect import of services in examples (closes #20)
    • docs: General improvements to the API Reference (#35)
    • docs: refactor versioning stuff

    New Contributors

    Full Changelog: https://github.com/linkfrg/ignis/compare/v0.2...v0.3

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Ignis

    docs Checked with mypy Code style: black Linting: Ruff

    [!WARNING] Ignis is currently being rewritten in Rust. See the rust-rewrite branch.

    A widget framework for building desktop shells, written and configurable in Python.

    • Easy to use
    • GTK4-based
    • Batteries Included (a lot of built-in Services and Utilities!)
    • Flexible work with widgets

    [!NOTE] Ignis is mostly stable, but still a work in progress. The API is a subject to change.

    The breaking changes tracker is available in #60

    Getting started

    See the Documentation

    Supported Desktops

    • wlroots-based Wayland compositors (e.g., Sway)
    • Hyprland
    • Smithay based compositors (e.g., COSMIC)
    • KDE Plasma on wayland

    ...and all other compositors that implement the Layer Shell protocol.

    Ignis is not supported on:

    • GNOME Wayland
    • X11

    ...because they don't support the Layer Shell protocol.

    Examples

    Contributing

    Check out the Developer Guide

    Licensing

    Ignis is licensed under the LGPL-2.1-or-later.

    Special Thanks

    AGS - for inspiration