Releases: ignis-sh/ignis
v0.5.1
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
v0.5
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_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 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.
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.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:
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_workspace.idHyprlandService.kb_layoutis removed, useHyprlandService.main_keyboard.active_keymapinstead.HyprlandService.switch_kb_layout()is removed, useHyprlandService.main_keyboard.switch_layout()instead (to restore the old functionality pass"next"as an argument to it).HyprlandService.workspaceswill not be notified on the active workspace change anymore.
If you want to restore the old functionality, usebind_many():
# Old
hyprland.bind(
"workspaces",
transform=lambda value: [WorkspaceButton(i) for i in value],
)
# New
hyprland.bind_many(
["workspaces", "active_workspace"],
transform=lambda workspaces, *_: [
WorkspaceButton(i) for i in workspaces
],
)Niri Service moved to GObject-based objects
#181 introduces GObject-based objects for Niri Service.
A few notes:
- Since these objects are not dictionaries anymore, you have to get properties like usual class attributes
NiriService.kb_layoutis removed, useNiriService.keyboard_layouts.current_nameinstead.NiriService.active_workspaceshas been dropped, to avoid introducing a separate data structure (list) that needs to be kept up to date. Active workspaces can still be extracted fromNiriService.workspaces(eachNiriWorkspaceobject exposes theis_activeproperty).NiriService.send_commandnow performs json serialization of thecmdargument and adds a trailing newline ("\n") to the resulting string, thus eliminating the need to pre-process any argument passed to this method.
See updated docs for more info.
Other Breaking Changes
- #103:
Binding.target_propertyremoved, useBinding.target_properties(list) instead - #146: logs are stored at
$XDG_STATE_HOME/ignis/ignis.log(~/.local/state/ignis/ignis.log) instead of~/.ignis/ignis.log - The minimal required version of PyGObject is now 3.50.0
- Now
Utils.FileMonitor.flagsusesGio.FileMonitorFlags, notstr - chore!: rename
DBusProxy.proxy->gproxyfor clarity - refactor!: overhaul
DBusProxyinitialization & add support for async initialization (#142) - chore!: remove
Utils.download_image()as unnecessary - feat!: wrap gvc instead of using git submodule (#109)
New Features
- feat!: allow binding multiple properties (IgnisGObject.bind_many()) (#103)
- feat: add Widget.Stack (Widget.StackPage, Widget.StackSwitcher) (#107)
- feat: Support installation using pip (#92)
- feat: allow skipping gvc build using meson options
- feat: allow skipping dependency check using meson options
- feat(
Widget.Window): adddynamic_input_regionproperty - feat: add
Utils.get_monitors() - feat(
IgnisApp): addreload_on_monitors_changeproperty (closes #87) - feat: allow gtk css priority to be overridden (#116)
- feat: support Grass Sass compiler as a fallback (#123)
- feat(
Widget.EventBox): allow custom scroll flags (#129) - feat: allow custom command format for
Application.launch() - feat: add
Application.launch_uwsm()(#134) - feat(
Application): addis_terminalproperty - feat(
Application): allow running terminal applications using a separate format (closes #141) - feat(
DBusProxy): make__get_dbus_propertyand__set_dbus_propertypublic - feat(
DBusProxy): addget_dbus_property_async()&set_dbus_property_async() - feat!: follow XDG base directories (#144)
- feat: add
Utils.snake_to_pascal()&Utils.pascal_to_snake() Wifi: Allow get and change PSK (#131)- feat: log python warnings
- feat!: asyncio integration (#152)
- feat: log exceptions from asynchronous functions
- feat: add
ConnectionManager&DBusConnectionManager(#159) - feat(
Utils): add functions for file operations (#149) - feat(
NiriService): addwindowsproperty (#164) - feat: add
Utils.get_app_icon_name()(#167) - feat(
HyprlandService): addget_workspace_by_id()method - feat: add
DataGObject - feat(
DBusProxy): addcall()&call_async()methods - feat(
DBusProxy): support calling D-Bus methods asynchronously using pythonic way - feat!(
DBusMenu): move to async - feat(
HyprlandService): sync workspace on "renameworkspace" event (#172) - feat(
FetchService): add k10temp cpu temperature support (#187) - feat: add
ignis.is_editable_installvariable - feat(
HyprlandService): addwindowsproperty (#210) - feat(
HyprlandService): addget_windows_on_workspace()method - feat(
OptionsManager): Add support for hot-reloading when the file is modified externally (#198) - feat: store compiled css file in a random temporary directory (#211)
- feat(
OptionsManager): implementTrackedList(#215) - feat: support modifying
options.applications.pinned_apps(#216) - feat(
HyprlandService): addmonitorsproperty (#219)
Fixes
- fix(nix): add
gnome-bluetoothtoGI_TYPELIB_PATH(#97) - fix(
NetworkService): exceptKeyErroron.pop() - fix(
Vpn): notifyactive-vpn-id&is-connectedwhen adding/removing an active connection - fix(
Widget.Box): notify child onappend(),remove(), andprepend() - fix(
Widget.Window): change input region after realize if surface is None - fix(
SystemTrayService): do not add an item if itsbus_nameis already present inself._items(closes #118) - fix(
SystemTrayService): add icon theme of item to search path (#120) - fix: use triple double quotes (
""") in__commit__.py - fix: escape commit message for correct string syntax in
__commit__.py - fix(nix): do not use
substituteInPlacefor/bin/sass(#130) - fix(
Wifi): do not add access points with the same bssid - refactor(
Widget.PopoverMenu): improve menu generation logic (#136) - fix(
SystemTrayService): initialize item proxy asynchronously (closes #140) - fix: use
GLib.Errorinstead ofGLib.GError - fix(
SystemTrayItem): move to asynchronous property synchronization (#147) - Wi-Fi AP Connection Fixes (...
v0.4
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: #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 #43
- fix(nix): add GStreamer & PipeWire to build inputs by @0x006E in #44
- feat: Niri Service by @regenman in #54
- feat: IgnisApp.add_icons() by @linkfrg in #53
- fix: UPower Device State always return false by @newor0599 in #59
- feat: Power Menu in example bar by @regenman in #57
- feat(network): support wireguard vpn connections by @regenman in #63
- fix: use the icon provided by a Spotify installation when it is unavailable in the icon theme by @linkfrg in #67
- feat: Bluetooth Service by @linkfrg in #28
- fix(nix): prefix PATH instead of overwriting it by @campbellcole in #72
- feat: add cpu_temp to fetch service by @trolljoe in #73
- feat: Systemd Service by @regenman in #62
- fix(nix): use librsvg pixbuf module loader cache to allow loading SVG icons by @campbellcole in #78
- feat: Utils.DebounceTask & Utils.debounce by @linkfrg in #76
- Feat(Widget.EventBox): Add support for right & left scroll events by @regenman in #82
- feat(network): refactor signal handling by @linkfrg in #80
- fix(network): use rsn_flags & wpa_flags to check the security protocol of an access point by @linkfrg in #86
- fix(network): WifiConnectDialog: use an unique window name based on the bssid by @linkfrg in #89
New Contributors
- @0x006E made their first contribution in #44
- @regenman made their first contribution in #54
- @newor0599 made their first contribution in #59
- @campbellcole made their first contribution in #72
- @trolljoe made their first contribution in #73
Full Changelog: v0.3...v0.4
v0.3
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 #13
- @gauravsatish made their first contribution in #16
- @ratson made their first contribution in #21
- @tyrypyrking made their first contribution in #29
- @imxnasr made their first contribution in #38
Full Changelog: v0.2...v0.3
v0.2
Breaking Changes
- cli: move to
clickinstead ofargparse:- subcommands instead of arguments (e.g.,
quitinstead of--quit) - to run Ignis, use the
initsubcommand (ignis init)
- subcommands instead of arguments (e.g.,
Utils.Poll: passselfas an argument to the callback- Network Service: add support for controlling multiple devices; more functionality for controlling Ethernet
Utils.Poll: use milliseconds instead of seconds- Use service classes directly:
- remove
ServiceClassandServicefromignis.services - add
.get_default()method to services - add
BaseServiceclass
- remove
- remove the
appvariable fromignis.app; use theIgnisApp.get_default()method instead - feat!(options): add support for option groups
- feat!(options): use the Option class directly
New Features:
- Utils: add
Utils.get_ignis_commit - switch to using exceptions instead of logging
- App: added
remove_window()method - CLI: print "No such window" error
- Examples: add examples/bar
- CLI: add support to execute blocks of code
- Recorder: added
pause_recordingand `continue_recording`` methods - Widgets: add
Widget.ArrowandWidget.ArrowButton - App: add
is_readyproperty - App: add support for multiple style paths (CSS providers)
- Utils: add
Utils.get_current_dir() - Widgets: add
Widget.RevealerWindow
Fixes:
- App: return value immediately in
__RunPython__and__RunFile__ - Audio Service: Stream: rounding volume added
- MPRIS Service: fix issue a player sometimes doesn't close
- Widget.FileChooserButton: do not set icon name if the path doesn't exist
- Hyprland Service: except
json.decoder.JSONDecodeErrorin__listen_socket() - Recorder Service: fix memory leak
- Widget.Box: not all children are removed
- Network Service (Wi-Fi): notify
enabledproperty; return when unavailable inWifiDevice.scan() - Network Service: fix some properties not updating or notifying
- Notifications Service: close the old notification when replacing it with a new one
- Notifications Service: do not sort notifications and popups by ID
__init__.py: removed the extra slash (/) at the end ofCACHE_DIR- MPRIS Service: notify
art_urlonly when necessary - logging: log all unhandled exceptions
- Recorder Service: fix issue where the output file was sometimes corrupted
- mpris: invalid filename when downloading art image from the URL
- add
Variableclass
Other:
- add Ruff and mypy
- remove
post_install.py - move version from the
VERSIONfile to__version__in__init__.py - docs: move to pydata Sphinx theme
- move to
logurufor logging - Recorder Service: move all XDG Desktop Portal stuff to the
SessionManagerclass - Widget.Window: raise
ValueErroron invalidinput_widthandinput_heightvalues - Widget.Window: set default value for
input_widthandinput_heightto 0 - split CLI and
IgnisClient, move all CLI-related code tocli.py - docs: simplify the build process
- docs: add checks for Sphinx build; move options creation and
os.makedirs()to class constructors - docs: add version switcher
- add
py.typedmarker - docs: sort members by source
- Wallpaper Service: use
WallpaperLayerWindowinstead ofWidget.Window - use pygobject-stubs; add stubs for
Gvc,NM,Gtk4LayerShell - docs: use sphinx_design
- docs: use sphinx_copybutton
- split services into separate directories and files
- dbus: use async calls using `result_handler``
- docs: generate widgets and utils API reference files when building documentation (mock imports)
- docs: improve developer docs
- docs: add module names
New Contributors
Full Changelog: v0.1...v0.2