Skip to content
equisdotsPublic

About

Nyx — self-contained Quickshell mascot island + control-center notch module

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

27 Commits

Folders and files

Repository files navigation

   ╲   ╱╲   ╱    ─────────────
    ╲ ╱  ╲ ╱     N Y X
     ✕    ✕      ─────
    ╱ ╲  ╱ ╲     mascot island + notch
   ╱   ╲╱   ╲    ╲_____╱

Nyx — the self-contained Quickshell mascot island and control-center notch.

Never imports the shell core: the palette, the settings path and the live data are injected, and the only runtime requirements are Quickshell (Wayland), Hyprland (hyprctl cursorpos, socket2) and a Nerd Font.

nyx/
  nyx.json             registry: name, path and author of every component
  plugin.json          equisdots plugin manifest (Plugins registry; toggle)
  host/                the host adapter the shell mounts (ui/PluginHosts.qml)
  catalog/             species/cards discovery (MascotsCatalog + qmldir + scan)
  settings/            its own settings page (Plugins → Nyx in the shell)
  notch/               the shipped notch cards (defaults.json)
  front/               the "chrome" — island/notch window + control center
    MascotsOverlay.qml  per-screen island/notch window (positions, cursor +
                        event polling, moods, dock host, per-mascot popovers)
    MascotDock.qml      control center: search, hero, quick actions, grid, tabs
  mascots/             species, one folder each + the shared host/base
    Mascot.qml          host: loads the species QML (entry), bob / blink / moods
    InfoMascot.qml      base for the "info" species (glyph + value)
    MascotFaceEyes.qml  shared face eyes/brows (flame / cat / dog)
    MascotMetrics.js    vendored scale helpers (no shell imports)
    flame/manifest.json + FlameMascot.qml
    cat|dog|eyes|dots|watcher/
    battery|cpu|memory|wifi|volume|temperature/   (InfoMascot-based)
    github/manifest.json + GithubMascot.qml + GithubPopover.qml + github_fetch.sh

A species folder holds its manifest.json and its files (entry, optional popover, scripts, assets); entry/popover resolve relative to the folder.

Plugin integration (equisdots)

Nyx ships as a plugin (standard: equisdots/plugins → docs/plugins.md). Its manifest declares:

"host": "host/Mascots.qml",
"provides": { "mascots": { "species": "mascots", "cards": "notch" } }
  • host — the shell mounts the adapter generically (ui/PluginHosts.qml); it runs inside the shell tree, imports the core kit, renders the island and publishes frameObstacle (per-screen rects) so the screen frame hugs it.
  • provides.mascots.species / .cards — this plugin's own extension rule: any installed plugin may declare the same keys to extend the island; the user dirs (~/.config/hypr/mascots/...) still win on id.
  • settings.page — the settings page above appears as Plugins → Nyx.

See docs/shell-integration.md for the full shell-side contract (discovery, cards, editor).

Settings (when settingsPath is set)

The plugin's own configuration UI is settings/NyxPage.qml (deployed to the shell's ui/plugins/nyx/ and listed as Plugins → Nyx), which edits:

Key Values Default Meaning
mascots.enabled bool false master switch
mascots.species id or [id, …] flame look: one id for every mascot (or mixed), or an array = one mascot per id (the lineup). ids come from the discovered catalog
mascots.count 1..8 3 mascots in the island (string mode only; array mode uses the lineup length)
mascots.size 0.6..1.6 1.0 mascot scale
mascots.position top-left … bottom-right top-center island position; the dock unfolds toward the screen centre (up when the island is at the bottom)
mascots.appearance island notch island notch snaps to the top edge with a macOS-style silhouette (no coloured border); dock still floats
mascots.notchWidth px (design units) 260 notch width; clamped to fit the mascots and to half the screen
mascots.notchHeight px (design units) 0 notch height; 0 = automatic (mascot height + padding)
mascots.notchOffset px (design units) 0 vertical offset; negative tucks the notch up into the screen edge
mascots.notchReserve bool true in notch mode, reserve the top strip so maximized windows clear it (exclusive zone)
mascots.dock.size compact medium large wide large control-center panel width preset
mascots.dock.width px (design units) 0 explicit panel width (0 = use the preset)
mascots.dock.style floating joined floating joined welds the panel under the notch (notch widens + squares off)
mascots.dock.columns / rows 3..7 / 1..3 5 / 2 widget grid shape (page size = columns × rows)
mascots.dock.hero / quick / search bool true show the clock + now-playing hero, quick actions and search
mascots.dock.favorites array of widget ids [] tiles pinned to the dock's Favorites tab
mascots.watcher.format 24 12 24 Watcher clock format
mascots.watcher.seconds bool true show the seconds field
mascots.watcher.speed number 1.0 typewriter speed multiplier
mascots.watcher.moods bool true mood-driven effects (angry red, sleepy dim, happy bounce)
mascots.watcher.eye bool false little tracking eye next to the clock
mascots.profiles object {} named presets of the whole mascots block (saved in the editor)
uiScale number 1.0 extra user scale
bar.position / bar.thickness string / px top / 48 island margin below the bar band

Extending: species & notch cards

Both are discovered from a shipped (repo) dir and a user dir; a user file whose id matches a shipped one overrides it. Drop a file and restart the shell (or call MascotsCatalog.refresh() in the equisdots shell) to pick it up.

Species — ~/.config/hypr/mascots/species/*.json (shipped: mascots/species.json):

{ "id": "moon", "label": "Moon", "icon": "󰽦", "entry": "Moon.qml", "order": 100 }

entry is a QML file next to the manifest; omit it to use a built-in kind (flame cat dog eyes dots watcher). The QML root may declare any of mood, lookX, lookY, tint, crust, text, red, blinking, clock, palette, options — the host binds them. Enable species in Settings → Plugins → Nyx; each enabled species adds one mascot and the island width follows the count.

customizable lists the option names a species accepts (["color","size"]); the host passes them through options from settings → mascots.options.<id> (color = a palette role or #hex, size = a 0.6..1.8 content scale). A controls array is the richer form: [{"type":"color"},{"type":"size"}, {"type":"text","key":"user","label":"User","placeholder":"…","default":"…"}] — a text control stores a string under options.<key>. The shipped info species (battery, cpu, memory, wifi, volume, temperature) declare customizable and are built on InfoMascot, which applies colour and size.

popover (optional) is a QML file next to the manifest. A species that declares one becomes clickable: clicking its mascot opens that popover in a panel under/over the island (clicking the island again collapses it). The popover root's contract is options, palette, scaleUnit, accent. The shipped github species uses this: the octocat opens the contribution heatmap for options.user (see mascots/github/); the fetch is cached per user (~/.cache/nyx/github/<user>.json, GITHUB_CACHE_TTL seconds, default 1800).

Notch cards — ~/.config/hypr/mascots/notch/*.json (shipped: the shell's notch/defaults.json):

{ "id": "weather", "label": "Weather", "icon": "󰖐", "exec": "…" }

exec runs a shell command when the card is picked; without it the card opens the shell panel with that id. Add "enabled": false to hide a shipped card and "thumb" for a preview image.

Public API (per screen)

MascotsOverlay exposes enabled, species (string or array), mascotCatalog, count, size, uiScale, position, barPosition, barThickness, appearance, notchWidth, notchHeight, notchOffset, notchReserve, dockSize, dockWidth, dockStyle, dockColumns, dockRows, dockShowHero, dockShowQuick, dockShowSearch, quickActions, quickHandler, stats, favorites, watcherFormat, watcherSeconds, watcherSpeed, watcherMoods, watcherEye, palette, settingsPath, widgetStatePath, dockWidgetName, widgetRectProvider, widgetList and widgetLauncher. The palette object needs base, surface1, text, crust, red, yellow, green, blue, mauve (colors) and glassOn (bool); a Catppuccin-Mocha fallback is built in. widgetRectProvider(name, sw, sh, uiScale) returns { x, y, w, h } in screen coordinates for widgets that should hide the island when they overlap it; dockWidgetName hides the island entirely for that widget (e.g. a dock). widgetList is an array of { id, label, icon } cards shown in the click dock; an entry may also carry an optional thumb (path or URL), shown instead of the icon once it loads (e.g. a live wallpaper preview). widgetLauncher(id) is called when one is picked.

Integration example

Item {
    Colors { id: themeColors }              // your palette source

    MascotsOverlay {
        palette: themeColors
        settingsPath: "~/.config/hypr/settings.json"
        widgetStatePath: "/run/user/1000/quickshell/current_widget"
        dockWidgetName: "applauncher"
        widgetRectProvider: (name, sw, sh, scale) => computeRect(name)
    }
}

The overlay is a click-through layer surface (qs-mascots, mask 0x0), one per screen, and it never captures input.

About

Nyx — self-contained Quickshell mascot island + control-center notch module

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages