Wired Notification Daemon

repository·master·Indexed 18 days ago

https://github.com/toqozz/wired-notify

A lightweight, highly customizable notification daemon featuring extensible layouts and programmable elements. It includes a CLI for managing notifications, DND mode, and action execution via a Unix socket. Wired supports configuration via Rusty Object Notation (.ron) and provides integration for Arch Linux (AUR), NixOS, NetBSD, and Fedora/CentOS/RHEL.

Tokens
7.6K
Snippets
27
Records
39
Agent score
71%

What's inside Wired

  1. Run Wired as a service or autostart

    master

    You can start Wired by adding it to your desktop environment's autostart script, or by using systemd as a user service. To use systemd, copy the wired.service file from the repository root to /usr/local/lib/systemd/user/wired.service (or your distro's equivalent).

    # Autostart method
    /path/to/wired &
    
    # systemd method
    $ systemctl enable --now --user wired.service
  2. Install Wired via Nix (Flakes)

    master

    Wired supports Nix Flakes. You can run it directly, install it to your user profile, or integrate it into your own Flake or NixOS configuration.

    # Run directly from the repository
    nix run 'github:Toqozz/wired-notify'
    
    # Install to user profile (systemd service will not be available)
    nix profile install 'github:Toqozz/wired-notify'
  3. Install Wired via AUR

    master

    On Arch Linux, you can install Wired using an AUR helper like yay. You can choose between the stable version or the -git version which tracks the master branch.

    # Install stable version
    $ yay -S wired
    
    # Install master branch version
    $ yay -S wired-git
  4. Configure Wired with Home-Manager (Standalone)

    master

    If using standalone Home-Manager, you can use the provided Wired overlay and module to enable the service and provide a configuration file (e.g., wired.ron).

    {
      # ...
      outputs = { self, nixpkgs, home-manager, wired, ... }: {
        homeConfigurations.alice = let
          system = "x86_64-linux";
        in home-manager.lib.homeManagerConfiguration {
          pkgs = import nixpkgs {
            inherit system;
            overlays = [ wired.overlays.default ];
          };
    
          modules = [
            wired.homeManagerModules.default
            ({ ... }: {
              services.wired = {
                enable = true;
                config = ./wired.ron;
              };
            })
          ];
        };
      };
    }
  5. Build Wired from source

    master

    To build Wired manually, ensure you have the following dependencies installed: rust, dbus, cairo, pango, glib2, x11, xss. Then use cargo build --release.

    $ git clone https://github.com/Toqozz/wired-notify.git
    $ cd wired-notify
    $ cargo build --release
    $ ./target/release/wired
  6. Install Wired via NixOS (All Users)

    master

    To install Wired for all users in a NixOS configuration, add the Wired input and include its package in your environment.systemPackages.

    {
      inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
        wired.url = "github:Toqozz/wired-notify";
      };
      outputs = { self, nixpkgs, wired }: let
        std = nixpkgs.lib;
        system = "x86_64-linux";
      in {
        nixosConfigurations.alice = std.nixosSystem {
          inherit system;
          modules = [
            ./configuration.nix
            {
              environment.systemPackages = [ wired.packages.${system}.wired ];
            }
          ];
        };
      };
    }
  7. Install Wired on NetBSD

    master

    Wired is available in official NetBSD repositories via pkgin, or can be built from source using make.

    # Using pkgin
    $ pkgin install wired-notify
    
    # Building from source
    $ cd /usr/pkgsrc/x11/wired-notify
    $ make install
  8. Use Hook to position elements

    master

    The Hook struct determines how a LayoutBlock is positioned relative to its parent and itself using AnchorPosition.

    • parent_anchor: The point on the parent's rectangle used for alignment.
    • self_anchor: The point on the block's own rectangle used for alignment.

    Positioning is calculated by finding the difference between the parent anchor and the self anchor, then applying the block's offset.

  9. Define a LayoutBlock for UI elements

    master

    A LayoutBlock is the fundamental unit of the UI tree. It combines a Hook (for positioning), an offset, and a LayoutElement (the actual drawable content). Blocks can have children, forming a tree structure.

    Key fields for configuration:

    • name: Identifier for the block.
    • parent: The name of the parent block.
    • hook: Defines how this block anchors itself relative to its parent.
    • offset: A Vec2 applied on top of the anchor position.
    • params: A LayoutElement defining what this block draws.
    • render_criteria: A list of RenderCriteria that must be met for the block to be drawn. If empty, it always draws.
    • render_anti_criteria: A list of RenderCriteria that, if met, prevent the block from being drawn. This takes priority over render_criteria.
    // Example conceptual structure of a LayoutBlock
    LayoutBlock {
        name: "my_block".to_string(),
        parent: "root".to_string(),
        hook: Hook { ... },
        offset: Vec2 { x: 10.0, y: 10.0 },
        params: LayoutElement::TextBlock(params), 
        render_criteria: vec![RenderCriteria::Summary],
        render_anti_criteria: vec![],
        // ...
    }
  10. Understand the Message enum

    master

    The Message enum represents the two types of events received from the DBus notification interface:

    • Notify(Notification): A new notification has been sent.
    • Close(u32): A notification with the specified ID should be closed.
    // Example of handling messages
    while let Ok(msg) = receiver.recv() {
        match msg {
            Message::Notify(notification) => {
                println!("New notification: {}", notification.summary);
            }
            Message::Close(id) => {
                println!("Closing notification: {}", id);
            }
        }
    }
  11. Initialize the DBus notification thread

    master

    To start receiving notifications via the DBus session bus, call init_dbus_thread(). This function registers the org.freedesktop.Notifications name on the session bus and spawns a background thread to process incoming DBus messages. It returns a JoinHandle for the background thread and a Receiver<Message> which you can use to consume incoming notification events.

    let (handle, receiver) = init_dbus_thread();
    // Use receiver to listen for Message variants (Notify or Close)