项目正在用 Rust 重写(见 rust-rewrite 分支),API 仍可能变动;不支持 GNOME Wayland 和 X11,需在支持 Layer Shell 的 Wayland 合成器上运行;README 未提供安装步骤,需自行查阅官方文档。
ignis
ignis-shLGPL-2.1活跃维护用 Python 编写和配置的桌面 Shell 组件框架,基于 GTK4 和 Wayland,让 Linux 用户像搭积木一样自定义桌面小部件与状态栏。
A widget framework for building desktop shells, written and configurable in Python
README 未给出安装命令,仅指向文档:https://ignis-sh.github.io/ignisREADME 未说明硬件要求;仅支持实现 Layer Shell 协议的 Wayland 合成器(如 Sway、Hyprland、COSMIC、KDE Plasma on Wayland),不支持 GNOME Wayland 与 X11。
用 Python 写和配置的 GTK4 桌面外壳控件框架,帮你快速搭出状态栏等桌面组件
用 Python 编写和配置的桌面 Shell 组件框架,基于 GTK4 和 Wayland,让 Linux 用户像搭积木一样自定义桌面小部件与状态栏。
核心能力
- 基于 GTK4 构建桌面外壳控件
- 用 Python 编写并配置界面
- 内置大量开箱即用的 Services 与 Utilities
- 灵活组合与操作控件
- 支持 Layer Shell 协议的 Wayland 合成器
容易踩的坑
- 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
- fix(HyprlandService): parse event data correctly with multiple ">>" by @ratson in https://github.com/ignis-sh/ignis/pull/222
- fix!(
HyprlandService): rename method to match return type by @ratson in https://github.com/ignis-sh/ignis/pull/223 - fix(
SystemTrayService): do not init item if another task with the same bus name is already running by @linkfrg in https://github.com/ignis-sh/ignis/pull/224 - feat!: store options in
XDG_DATA_HOMEby @linkfrg in https://github.com/ignis-sh/ignis/pull/225 - fix(
HyprlandService): do not add object if its data is empty by @linkfrg in https://github.com/ignis-sh/ignis/pull/229 - refactor: unify
Gio.Menugeneration viaIgnisMenuModelby @linkfrg in https://github.com/ignis-sh/ignis/pull/236 - fix(
IgnisApp): inherit parameters passed toapply_css()inreload_css()by @linkfrg in https://github.com/ignis-sh/ignis/pull/245 - fix!(
ListBox): do not activate row onselect_row()by @linkfrg in https://github.com/ignis-sh/ignis/pull/248 - fix(
ListBox): updaterowsproperty when child list is modified via methods by @linkfrg in https://github.com/ignis-sh/ignis/pull/246 - feat(cli): support relative file paths by @linkfrg in https://github.com/ignis-sh/ignis/pull/247
- fix(
IgnisMenuModel): correctly release items and actions of the old menu model by @linkfrg in https://github.com/ignis-sh/ignis/pull/238 - refactor: move to using linkfrg/gi-stubs-extra by @linkfrg in https://github.com/ignis-sh/ignis/pull/252
- nix: General improvements to the package by @MOIS3Y in https://github.com/ignis-sh/ignis/pull/239
- fix(nix): directly use the Ignis executable on reload by @linkfrg in https://github.com/ignis-sh/ignis/pull/268
- feat(
HyprlandService): supportmoveworkspaceevent by @linkfrg in https://github.com/ignis-sh/ignis/pull/272 - fix(
Window): improve handling of size changes fordynamic_input_regionby @linkfrg in https://github.com/ignis-sh/ignis/pull/274 - feat!(cli): move to
typerby @linkfrg in https://github.com/ignis-sh/ignis/pull/277 - feat!: use
richexception tracebacks by @linkfrg in https://github.com/ignis-sh/ignis/pull/279 - fix(
HyprlandService): usemoveworkspacev2instead ofmoveworkspaceby @linkfrg in https://github.com/ignis-sh/ignis/pull/281 - feat: add support for
end_charinUtils.send_socket()by @linkfrg in https://github.com/ignis-sh/ignis/pull/282 - fix(
NiriService): use end character insend_command()by @linkfrg in https://github.com/ignis-sh/ignis/pull/283 - docs: add
Void Linuxinstallation section by @linkfrg in https://github.com/ignis-sh/ignis/pull/286 - feat(
NiriService): addoverview_openedproperty by @Rikiub in https://github.com/ignis-sh/ignis/pull/289 - fix(NiriService): adapt event stream initialization to new IPC event by @regenman in https://github.com/ignis-sh/ignis/pull/291
- fix(
utils/file): raiseTypeErrorexceptions by @emmanuel-ferdman in https://github.com/ignis-sh/ignis/pull/292 - Revert "feat!(cli): move to
typer(#277)" by @linkfrg in https://github.com/ignis-sh/ignis/pull/301 - feat!(cli): small improvements to CLI messages & command names by @linkfrg in https://github.com/ignis-sh/ignis/pull/302
- docs: use
sphinx-clickto autogenerate cli documentation by @linkfrg in https://github.com/ignis-sh/ignis/pull/303 - github(workflows): cache
libcairo2-devinstatic.yamlby @linkfrg in https://github.com/ignis-sh/ignis/pull/304 - feat!: export widgets by @linkfrg in https://github.com/ignis-sh/ignis/pull/299
- feat!: export utils by @linkfrg in https://github.com/ignis-sh/ignis/pull/300
- fix(options): remove
is_sphinx_buildcheck where unnecessary by @linkfrg in https://github.com/ignis-sh/ignis/pull/308 - github(workflows): cache pip dependencie
- 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_charinUtils.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) SyncHyprlandMonitoractive 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 toapply_css()inreload_css()(#245) - (
ListBox) Updaterowsproperty when child list is modified via methods (#246) - (
OptionsGroup) Maketo_dict()return all options instead of only modified ones - Mark
bin/ignisas executable - Rename
ignis.logging->ignis.log_utilsto avoid naming collision - (
WifiAccessPoint) Sync connections in_setup() - (
Window) Improve handling of size changes fordynamic_input_region(#274) - (
NiriService) Use end character insend_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
- Add support for
- 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&OptionsAPI 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_countare removed, use corresponding options inignis.options.Options. E.g., replacenotifications.dndwithoptions.notifications.dnd - Recorder Service:
bitrate,default_file_location,default_filenameproperties are removed. All the same like with Notification Service. - Applications Service: public API hasn't changed
- Wallpaper Service:
wallpaperproperty is removed. Useoptions.wallpaper.wallpaper_path.
If you use Options Service to define your custom options, move to the new
OptionsManagerAPI.More info is available in the documentation.
Asyncio
asynciointegration! Some functions are asynchronous now. Useawaitorasyncio.create_task()to call them.DBusProxynew_async()get_dbus_property_async()set_dbus_property_async()
BluetoothDeviceconnect_to()disconnect_from()
WifiAccessPointcommit_changes_async()connect_to()connect_to_graphical()disconnect_from()forget()
EthernetDeviceconnect_to()disconnect_from()
VpnConnectionconnect_to()disconnect_from()
WifiDevicescan()
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:
-
MprisPlayernext()previous()pause()play()play_pause()stop()seek()
-
SystemTrayItemactivate()secondary_activate()context_menu()scroll()
-
SystemdUnitstart()stop()restart()
This also affects some property setters:
BacklightDevice.brightnesssetter is now synchronous, you can use its asynchronous version which is available as usual method:set_brightness_async(). Same forBacklightService.brightnessandMprisPlayer.position.Explicit GObject Property type
#157 replaces
GObject.Propertywith the newIgnisPropertyclass. The main difference withIgnisPropertyis that it can determine the property type automatically based on the return type of thegetter. 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
Noneas a value for a property which type isbool/int/str/floator GObject/GType. If you use.bind(), you have to add an additional check if the new value isNone.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
IgnisGObjectfor Hyprland Service, replacing usual python dictionaries. This approach allows to bind properties and other GObject features.New classes:
HyprlandWorkspaceHyprlandWindowHyprlandKeyboard
Migration Guide:
- 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 - Notification Service:
- 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_availableproperty 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
**kwargstoUtils.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
- feat(nix): remove submodules for nix build by @ratson in https://github.com/linkfrg/ignis/pull/43
- fix(nix): add GStreamer & PipeWire to build inputs by @0x006E in https://github.com/linkfrg/ignis/pull/44
- feat: Niri Service by @regenman in https://github.com/linkfrg/ignis/pull/54
- feat: IgnisApp.add_icons() by @linkfrg in https://github.com/linkfrg/ignis/pull/53
- fix: UPower Device State always return false by @newor0599 in https://github.com/linkfrg/ignis/pull/59
- feat: Power Menu in example bar by @regenman in https://github.com/linkfrg/ignis/pull/57
- feat(network): support wireguard vpn connections by @regenman in https://github.com/linkfrg/ignis/pull/63
- fix: use the icon provided by a Spotify installation when it is unavailable in the icon theme by @linkfrg in https://github.com/linkfrg/ignis/pull/67
- feat: Bluetooth Service by @linkfrg in https://github.com/linkfrg/ignis/pull/28
- fix(nix): prefix PATH instead of overwriting it by @campbellcole in https://github.com/linkfrg/ignis/pull/72
- feat: add cpu_temp to fetch service by @trolljoe in https://github.com/linkfrg/ignis/pull/73
- feat: Systemd Service by @rege
- HyprlandIPCNotFoundError doesn't raise during Hyprland Service initialization, use the new
- 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
selfas 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
systeminfosubcommand - 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_hintevent 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
- @somokill made their first contribution in https://github.com/linkfrg/ignis/pull/13
- @gauravsatish made their first contribution in https://github.com/linkfrg/ignis/pull/16
- @ratson made their first contribution in https://github.com/linkfrg/ignis/pull/21
- @tyrypyrking made their first contribution in https://github.com/linkfrg/ignis/pull/29
- @imxnasr made their first contribution in https://github.com/linkfrg/ignis/pull/38
Full Changelog: https://github.com/linkfrg/ignis/compare/v0.2...v0.3
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Ignis
[!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
-
A simple bar, see examples

Contributing
Check out the Developer Guide
Licensing
Ignis is licensed under the LGPL-2.1-or-later.
Special Thanks
AGS - for inspiration
