* gamer-mode: 0.7.0 Adds a monitor bar widget that renders live readings the way the shell's own sysmon widgets do, with a flame band beneath them while gamer mode runs. - Readings warm toward the highlight colour over the shell's own activity and critical thresholds, so a monitor sitting beside a sysmon capsule group warms in step with it. - The flame is advected along a wandering wind and sharpened so it reads as tongues rather than a smudge; the flare ignites and decays on an ease-out. - The band's slot is reserved on each side of the readings, so toggling gamer mode never moves a digit and the readings stay centred in the pill. - Panel readings outrank their captions, progress fills warm at the same thresholds, and the mark carries a load-reactive halo with a soft ember under the header while the mode runs. - The mark is redrawn and ships a dark and a light ramp. * gamer-mode: tighten the README prose
501 lines
23 KiB
Markdown
501 lines
23 KiB
Markdown
# Gamer Mode
|
|
|
|
Live CPU, RAM, and GPU readings in the bar, plus a one-click mode that suspends
|
|
background resource hogs and restores what was running before.
|
|
|
|
> Requires Noctalia v5 and plugin API 19. Noctalia v4 uses a different QML
|
|
> plugin format and will not list or load this source.
|
|
|
|
## Plugin
|
|
|
|
| Field | Value |
|
|
| --- | --- |
|
|
| ID | `nomadcxx/gamer-mode` |
|
|
| Entries | Bar widgets: `gamermode`, `monitor`; panel: `main`; service: `service` |
|
|
|
|
## Requirements
|
|
|
|
- `pgrep` and `pkill` from procps probe and signal process targets
|
|
- `systemctl` controls service and timer targets
|
|
- `docker` controls container targets
|
|
- `powerprofilesctl` from power-profiles-daemon switches the power profile
|
|
|
|
Each tool matters only if you target that kind. Without `powerprofilesctl` the
|
|
panel hides its power row and the toggle still works.
|
|
|
|
## Usage
|
|
|
|
| Gesture | Action |
|
|
| --- | --- |
|
|
| Left-click | Opens the panel. Set **Left-click action** to `toggle` to toggle instead. |
|
|
| Right-click | Toggles gamer mode, whatever **Left-click action** says. |
|
|
|
|
The glyph takes the accent colour while gamer mode runs. Its tooltip shows the
|
|
live readings in an aligned table and ends with gamer-mode state.
|
|
|
|
The panel shows a bar per reading, the power profile selector, the suspend
|
|
profile selector, what the plugin has suspended, and the maintenance actions.
|
|
|
|

|
|
|
|
Running under load. CPU and GPU sit past their thresholds, so their bars have
|
|
warmed; RAM and swap have not. The halo rings the mark, the ember sits under the
|
|
header, and the suspend profile shows as a label because the session already
|
|
recorded one.
|
|
|
|
Pick `light` or `heavy` in the panel and press Enable, and that profile applies
|
|
for the session. A plugin reads its own settings and cannot write them, so the
|
|
choice rides along with the enable rather than changing the **Gamer mode
|
|
profile** setting. While gamer mode runs the selector gives way to a label,
|
|
because the session already fixed the profile. To change it, disable first.
|
|
|
|
Drive it from a shell or a keybind:
|
|
|
|
```sh
|
|
noctalia msg plugin nomadcxx/gamer-mode:service all toggle
|
|
noctalia msg plugin nomadcxx/gamer-mode:service all enable
|
|
noctalia msg plugin nomadcxx/gamer-mode:service all disable
|
|
```
|
|
|
|
Toggle the panel:
|
|
|
|
```sh
|
|
noctalia msg panel-toggle nomadcxx/gamer-mode:main
|
|
```
|
|
|
|
## Monitor
|
|
|
|
Add the `monitor` widget when you want the readings on the bar. Keep the
|
|
`gamermode` widget for a compact toggle icon. Both entries use the same click
|
|
actions: left-click follows **Left-click action**, and right-click toggles gamer
|
|
mode.
|
|
|
|
The monitor groups related readings in a fixed order. A metric shown on the bar
|
|
stays out of its tooltip, so hovering adds the disabled readings instead of
|
|
repeating the row. The tooltip always includes gamer-mode state and the number
|
|
of suspended targets. Vertical bars stack each reading and omit the flame.
|
|
|
|

|
|
|
|
Gamer mode off above, running under load below. The flame is lit, and the
|
|
readings past their thresholds have warmed toward the highlight colour.
|
|
|
|
### The pill
|
|
|
|
The monitor draws no background of its own, for the same reason the shell's
|
|
built-in `sysmon` widgets do not: the bar draws it. Turn it on the way you would
|
|
for any widget and the shell frames the readout in the same stadium capsule,
|
|
sized and centred by the bar rather than guessed at by the plugin:
|
|
|
|
```toml
|
|
[widget.gamermonitor]
|
|
type = "nomadcxx/gamer-mode:monitor"
|
|
capsule = true
|
|
```
|
|
|
|
`capsule_fill`, `capsule_padding`, `capsule_radius`, and `capsule_opacity` work
|
|
here as they do elsewhere. The monitor can also join a `capsule_group`, sharing
|
|
one capsule with the `sysmon` widgets beside it.
|
|
|
|
Values hug their text by default, so the readout is exactly as wide as its
|
|
readings and grows as network rates change. **Reserved value width** trades that
|
|
for a steady width: set it to the widest reading you expect and values
|
|
right-align inside the reservation instead of pushing their neighbours. It sets
|
|
a floor rather than a clamp, so nothing gets truncated.
|
|
|
|
### Warning colours
|
|
|
|
Each reading warms towards the theme's error colour as it climbs, holding its
|
|
normal colour below an activity threshold and saturating at a critical one. The
|
|
thresholds are the shell's own defaults for each metric: 50%/90% for CPU,
|
|
60°C/85°C for temperatures, 1/50 MB/s for network. A monitor grouped beside the
|
|
built-in `sysmon` widgets therefore warms in step with them.
|
|
|
|
| Monitor setting | Default | Description |
|
|
| --- | --- | --- |
|
|
| CPU usage | On | Shows processor load. |
|
|
| CPU temperature | On | Shows processor temperature. |
|
|
| RAM used | On | Shows used memory in GiB. |
|
|
| Swap used | Off | Shows swap percentage when swap exists. |
|
|
| GPU usage | On | Shows graphics load when the shell reports a GPU. |
|
|
| GPU temperature | On | Shows graphics temperature when available. |
|
|
| VRAM used | Off | Shows used video memory when available. |
|
|
| Load average | Off | Shows the one-minute load average. |
|
|
| Network rates | On | Shows aggregate download and upload rates. |
|
|
| Icons | On | Places a glyph beside each reading. Turn it off for numbers only. |
|
|
| Reserved value width | `0` | Pixels held for each reading. Zero lets values hug their text. |
|
|
| Highlight while gamer mode is on | On | Adds the flame band under the readings. |
|
|
| Flame height | `5` | How tall the flame band is, in pixels (2-12). See the note below on why the useful range is small. |
|
|
| Flame | `flare` | `off`, a 900 ms `flare`, or `always`. |
|
|
| Flame style | `graph` | One graph node, or 28 sharper `bars`. |
|
|
|
|
The widget holds the band's slot open whether or not it burns, so toggling gamer
|
|
mode never shifts your readings. It reserves an equal gap above them to match the
|
|
band below, which keeps them centred in the pill instead of pinned to its top
|
|
edge.
|
|
|
|
That is why the band stays small. On a 42px bar at the default capsule thickness
|
|
of `0.76`, the pill measures 32px inside and the readings take 22, leaving 10 to
|
|
split between the gap and the band. Ask for more than half and the flame lands
|
|
outside the pill.
|
|
|
|
Raise **capsule thickness** in your bar settings if you want a bigger flame. It
|
|
sets the pill's height, so a taller pill gives you a taller band: at `0.95` the
|
|
pill runs about 40px and fits 9px of flame with the readings still centred.
|
|
|
|
### While gamer mode is on
|
|
|
|
A ring wraps the panel mark and thickens as load climbs, and a soft ember pulses
|
|
under the header. The panel's vsync frame tick drives each of them, and the shell
|
|
stops that tick when you close the panel, so an idle or closed panel costs
|
|
nothing.
|
|
|
|
The mark ships as two files, one dark ramp and one light, and the shell picks
|
|
between them by dark mode. A plugin cannot read palette colours, so those stay a
|
|
fixed pair instead of following your theme.
|
|
|
|
`always` holds the widget at about 30 frames per second while gamer mode runs.
|
|
Noctalia keeps widget timers running when another window covers the bar, so
|
|
this setting consumes CPU during play. `flare` returns to a one-second idle tick
|
|
after 900 ms.
|
|
|
|
### Maintenance
|
|
|
|
Three one-shot cleanups sit at the foot of the panel. None of them is part of
|
|
gamer mode, and turning gamer mode off does not undo any of them.
|
|
|
|
| Action | What it does | Needs a password |
|
|
| --- | --- | --- |
|
|
| Clear shader caches | Deletes the Mesa, NVIDIA `GLCache`, RADV, and Steam shader caches | No |
|
|
| Drop page cache | `sync`, then `vm.drop_caches=3` | Yes |
|
|
| Reclaim swap | `swapoff -a && swapon -a`, pulling swapped pages back into RAM | Yes |
|
|
|
|
Clearing shader caches takes two clicks. The first measures and the button
|
|
reports the size, the second deletes. Games recompile shaders on their next
|
|
launch, so that launch is slower. This is the one to reach for when a driver
|
|
update leaves stale shaders behind.
|
|
|
|
The plugin expands every cache path from a fixed list and drops any that
|
|
resolves outside your home directory, so the `rm` only ever sees the paths
|
|
above, and only those that exist.
|
|
|
|
Dropping the page cache frees the RAM the kernel uses to cache files. The kernel
|
|
refills it, and the pages it discards are ones it would otherwise have reused, so
|
|
this buys less than the number in `free` suggests.
|
|
|
|
Reclaiming swap only runs when what is swapped out fits in free RAM with a tenth
|
|
of total held back. Otherwise it reports that there is no room and does nothing,
|
|
because succeeding into an out-of-memory kill would defeat the point.
|
|
|
|
## Settings
|
|
|
|
| Setting | Default | Description |
|
|
| --- | --- | --- |
|
|
| Bar icon | `device-gamepad-2` | Glyph shown in the bar. Names a glyph from the shell's registry. |
|
|
| Custom icon | Empty | SVG or PNG used instead of the glyph. File changes reload in the bar. |
|
|
| Custom icon, gamer mode on | Empty | Optional active-state image for the toggle. |
|
|
| Left-click action | `open_panel` | Opens the panel or toggles gamer mode. Right-click toggles either way. |
|
|
| Poll interval | `3` | Seconds between metric updates: 2, 3, or 5. |
|
|
| Gamer mode profile | `light` | Selects which target profile a toggle applies. |
|
|
| Auto performance profile | On | Switches to the `performance` power profile while gamer mode runs, then hands back the previous one. |
|
|
| Show temperatures | On | Includes CPU and GPU temperatures in the tooltip and panel. |
|
|
| Suspend targets (JSON) | Empty | Replaces the built-in target list. See below. |
|
|
|
|
The setting names the profile a bar click applies. The panel selector overrides
|
|
it for the enable it is sent with, and the bar's right-click toggle does not see
|
|
that selection, so it uses the setting.
|
|
|
|
Noctalia cannot tint a custom image. Set **Custom icon, gamer mode on** if the
|
|
toggle needs a distinct active state; otherwise it reuses the resting image and
|
|
reports state in the tooltip.
|
|
|
|
## Target list
|
|
|
|
`targets` takes a JSON array. Each entry needs a `match`, a `kind`, and the
|
|
`profiles` it belongs to. `action` is optional.
|
|
|
|
```json
|
|
[
|
|
{"match": "awww-daemon", "kind": "process", "action": "freeze", "profiles": ["light", "heavy"]},
|
|
{"match": "qbittorrent", "kind": "process", "action": "freeze", "profiles": ["light", "heavy"]},
|
|
{"match": "ollama.service", "kind": "system-service", "action": "stop", "profiles": ["light", "heavy"]},
|
|
{"match": "fstrim.timer", "kind": "system-timer", "action": "stop", "profiles": ["light", "heavy"]},
|
|
{"match": "brave", "kind": "process", "action": "freeze", "profiles": ["heavy"]},
|
|
{"match": "jellyfin.service","kind": "system-service", "action": "stop", "profiles": ["heavy"]}
|
|
]
|
|
```
|
|
|
|
An empty setting uses the built-in list: 173 entries, 94 of them in `light`.
|
|
Breadth costs almost nothing, because a target that is not running probes as
|
|
`down`, so the plugin never touches it and never restores it. An entry for
|
|
software you do not have costs one `pgrep`.
|
|
|
|
The plugin falls back to the built-in list when the setting holds invalid JSON or
|
|
when every entry in it fails validation, and logs the reason. It drops single bad
|
|
entries and honours the rest, so one typo costs you one target.
|
|
|
|
`match` compares through `pgrep -x`, so it needs the whole name. Substrings and
|
|
patterns do not match. The plugin quotes every value for the shell and refuses a
|
|
`match` holding a newline, carriage return, or NUL at parse time.
|
|
|
|
### Actions
|
|
|
|
`action` defaults to `stop`.
|
|
|
|
| | `stop` | `freeze` |
|
|
| --- | --- | --- |
|
|
| Mechanism | `pkill` / `systemctl stop` / `docker stop` | `SIGSTOP` / `docker pause` |
|
|
| Probes | read-only, never elevated | read-only, never elevated |
|
|
| Frees RAM | Yes | No, pages stay resident |
|
|
| Frees VRAM | Yes | No |
|
|
| Halts CPU use | Yes | Yes |
|
|
| Halts disk I/O | Yes | Yes |
|
|
| Keeps state | No, the target shuts down | Yes, the target resumes where it stopped |
|
|
| Restarts | Units, timers, and containers | Always |
|
|
|
|
Pick `freeze` for anything you return to: a browser, an editor, a wallpaper
|
|
daemon. Pick `stop` when you need the memory back. A local model runtime such as
|
|
`ollama` holds VRAM until the service stops, and freezing keeps every VRAM page
|
|
allocated, so those targets use `stop`.
|
|
|
|
Network connections drop while a target sits frozen. That suits a torrent client
|
|
and hurts a chat app.
|
|
|
|
### Kinds
|
|
|
|
| `kind` | Probe | `stop` | Start | `freeze` | Thaw |
|
|
| --- | --- | --- | --- | --- | --- |
|
|
| `process` | `pgrep -x` | `pkill -x` | none, see below | `pkill -STOP -x` | `pkill -CONT -x` |
|
|
| `user-service` | `systemctl --user is-active` | `systemctl --user stop` | `systemctl --user start` | `systemctl --user kill --kill-whom=all -s SIGSTOP` | same with `SIGCONT` |
|
|
| `system-service` | `systemctl is-active` | `pkexec systemctl stop` | `pkexec systemctl start` | `pkexec systemctl kill --kill-whom=all -s SIGSTOP` | same with `SIGCONT` |
|
|
| `user-timer` | `systemctl --user is-active` | `systemctl --user stop` | `systemctl --user start` | invalid | invalid |
|
|
| `system-timer` | `systemctl is-active` | `pkexec systemctl stop` | `pkexec systemctl start` | invalid | invalid |
|
|
| `container` | `docker inspect -f '{{.State.Running}}'` | `docker stop` | `docker start` | `docker pause` | `docker unpause` |
|
|
|
|
### Timers
|
|
|
|
Stopping `foo.service` leaves `foo.timer` free to fire it again five minutes into
|
|
your session, so scheduled work needs its own target. A stock Arch install
|
|
enables `fstrim.timer`, `smartd.timer`, `paccache.timer`, and the package-cache
|
|
timers, and each one stalls disk I/O mid-game.
|
|
|
|
The timer kinds require the `.timer` suffix on `match`. `systemctl is-active
|
|
fstrim` resolves to `fstrim.service`, so the plugin rejects a timer entry without
|
|
the suffix at parse time.
|
|
|
|
### Processes do not restart
|
|
|
|
`kind: "process"` has no start command. A bare process name carries no argv, no
|
|
environment, and no working directory, so the plugin cannot relaunch one. That
|
|
makes `process` with `action: "stop"` a one-way trip. The plugin allows it and
|
|
logs a warning, and every built-in process entry uses `freeze`. To get something
|
|
back, target the unit or container that supervises it.
|
|
|
|
### Protected targets
|
|
|
|
The plugin refuses some targets whatever the setting says, because stopping them
|
|
ends your session, kills your audio or network, or kills the game gamer mode
|
|
serves. It drops such an entry at parse time with a logged reason, and every
|
|
command builder refuses it again at action time, so a session file written by an
|
|
older version cannot act on one either.
|
|
|
|
```
|
|
session/display niri hyprland sway river wayfire labwc gnome-shell kwin_wayland
|
|
plasmashell Xorg Xwayland greetd sddm gdm
|
|
the shell noctalia quickshell
|
|
audio pipewire pipewire-pulse wireplumber pulseaudio
|
|
core IPC systemd systemd-logind dbus-broker dbus-daemon elogind
|
|
network NetworkManager wpa_supplicant iwd systemd-networkd
|
|
game stack steam steamwebhelper gamescope wine wineserver proton lutris
|
|
heroic bottles gamemoded
|
|
```
|
|
|
|
Matching ignores case and any `.service`, `.timer`, or `.socket` suffix, so
|
|
`Steam`, `steam`, and `steam.service` all fail. The list takes no override. A
|
|
wrong entry here costs you a dead session or a killed game, and an override field
|
|
is the one people copy from a forum post without reading. To act on one of these,
|
|
use Feral GameMode's `start=` and `end=` script hooks in `gamemode.ini`.
|
|
|
|
### System units ask for a password once
|
|
|
|
Stopping or starting a system unit needs authorisation. The plugin runs all the
|
|
units of one operation through a single `pkexec /usr/bin/systemctl` call, which
|
|
asks once and then does the whole batch as root.
|
|
|
|
Two simpler approaches were measured first and each cost a password prompt per
|
|
unit, seven units meaning seven dialogs:
|
|
|
|
- One `systemctl` per unit. polkit's `auth_admin_keep` retains an authorisation
|
|
against the subject that gave it, and the subject systemd reports is the
|
|
calling process, so seven processes are seven subjects with nothing to reuse.
|
|
- One `systemctl` naming all seven units. systemctl issues its `StopUnit` calls
|
|
in parallel, so every polkit check is outstanding before any of them has an
|
|
answer, and again nothing can reuse an authorisation that does not exist yet.
|
|
|
|
`org.freedesktop.policykit.exec` is `auth_admin` with no retention, so each
|
|
`pkexec` prompts. The built-in targets only ever stop system units and never
|
|
freeze them, so an enable costs one prompt and a disable costs one. A custom
|
|
target list that mixes stops and freezes pays one prompt per operation.
|
|
|
|
Without `pkexec` the plugin falls back to calling `systemctl` directly, which
|
|
still works through systemd's own polkit check at the cost of the prompt-per-unit
|
|
behaviour. It logs the downgrade at startup.
|
|
|
|
You need an authentication agent running for any prompt to appear. Most desktops
|
|
start one; standalone compositors often do not. Check with:
|
|
|
|
```sh
|
|
pgrep -af 'polkit.*agent'
|
|
```
|
|
|
|
If nothing is listed, install one such as `mate-polkit`, `polkit-gnome` or
|
|
`hyprpolkitagent` and start it with your session. Without an agent the calls fail
|
|
and each one is logged.
|
|
|
|
To skip the prompt entirely, grant the units you target. Scope the rule to those
|
|
units: a blanket rule lets anything running as you stop or start any system unit.
|
|
In `/etc/polkit-1/rules.d/49-gamermode.rules`:
|
|
|
|
```javascript
|
|
polkit.addRule(function (action, subject) {
|
|
var units = ["sonarr.service", "radarr.service", "fstrim.timer"];
|
|
if (action.id == "org.freedesktop.systemd1.manage-units"
|
|
&& subject.isInGroup("wheel")
|
|
&& units.indexOf(action.lookup("unit")) >= 0) {
|
|
return polkit.Result.YES;
|
|
}
|
|
});
|
|
```
|
|
|
|
## Targets left out of the built-in list
|
|
|
|
Each of these suits someone and makes a poor default. Paste what you want into
|
|
`targets`.
|
|
|
|
**Voice chat.** Freezing these cuts voice during the activity the plugin serves.
|
|
|
|
```json
|
|
{"match": "discord", "kind": "process", "action": "freeze", "profiles": ["heavy"]},
|
|
{"match": "vesktop", "kind": "process", "action": "freeze", "profiles": ["heavy"]},
|
|
{"match": "slack", "kind": "process", "action": "freeze", "profiles": ["heavy"]},
|
|
{"match": "element-desktop", "kind": "process", "action": "freeze", "profiles": ["heavy"]}
|
|
```
|
|
|
|
**Music.** Plenty of people game with music playing.
|
|
|
|
```json
|
|
{"match": "spotify", "kind": "process", "action": "freeze", "profiles": ["heavy"]},
|
|
{"match": "spotifyd.service", "kind": "user-service", "action": "stop", "profiles": ["heavy"]},
|
|
{"match": "mpd.service", "kind": "user-service", "action": "stop", "profiles": ["heavy"]}
|
|
```
|
|
|
|
**Recording and streaming.** Plenty of people stream the game they play.
|
|
|
|
```json
|
|
{"match": "obs", "kind": "process", "action": "freeze", "profiles": ["heavy"]},
|
|
{"match": "gpu-screen-recorder", "kind": "process", "action": "freeze", "profiles": ["heavy"]}
|
|
```
|
|
|
|
**Language runtimes.** `java`, `dotnet`, and `node` burn CPU, and they run games
|
|
too. Minecraft and every PrismLauncher or MultiMC instance runs as `java`. Unity
|
|
and .NET titles run as `dotnet`. Freezing those freezes the game. Add them only
|
|
if nothing you play uses them.
|
|
|
|
**Container and VM daemons.** Stopping `docker.service` takes down every
|
|
container, and starting it again leaves their previous states behind. Stopping
|
|
`libvirtd` kills running guests. Target single containers with
|
|
`kind: "container"`, which pauses and unpauses through the cgroup freezer.
|
|
|
|
**Shared databases.** Other services tend to depend on `postgresql`, `mysqld`,
|
|
and `redis`. The built-in `heavy` profile does cover `elasticsearch` and
|
|
`opensearch`, whose JVM heaps often top the RAM table on a development box.
|
|
|
|
**VRAM without stopping the daemon.** `ollama` unloads models while staying up.
|
|
No target kind covers this, so use a Feral GameMode hook:
|
|
|
|
```ini
|
|
[custom]
|
|
start=/usr/bin/ollama stop --all
|
|
```
|
|
|
|
## Restore semantics
|
|
|
|
Enabling writes a session snapshot to the plugin data directory
|
|
(`session.json`). For every target in the active profile it records whether the
|
|
target was `running` or `active` or already down, which `action` applied, the
|
|
power profile in effect, and the kernel boot ID.
|
|
|
|
The snapshot lands on disk before anything is suspended. It is the only record
|
|
of what was running beforehand, so a target suspended without one is
|
|
unrecoverable: disable would read the session, find none, and return. If the
|
|
write fails, enabling stops there with the machine untouched and tells you why.
|
|
|
|
Disable runs two passes, because the two actions need different logic.
|
|
|
|
The plugin probes each **`stop` target** again and starts it back when it is
|
|
still down. So it leaves alone anything you stopped before enabling gamer mode,
|
|
and anything you restarted by hand while gamer mode ran. It logs and skips a
|
|
missing unit or container, and never fails hard partway.
|
|
|
|
The plugin thaws every **`freeze` target** without probing. A frozen process
|
|
still appears in `pgrep`, so no probe distinguishes "still frozen" from
|
|
"running", and `SIGCONT` to a process that is not stopped exits 0 and changes
|
|
nothing. Thawing blind beats probing here: it cannot misread a state, cannot
|
|
stomp a manual restart, and cannot leave something frozen after a probe fails to
|
|
run.
|
|
|
|
The snapshot sits on disk, so gamer mode survives a shell restart. Reload
|
|
Quickshell mid-session and the panel still reports it as on with the same suspend
|
|
list, and disable still restores.
|
|
|
|
Enabling twice does nothing. A second enable would re-probe and record the
|
|
targets it had suspended as "was down", losing what it needs to restore them.
|
|
|
|
### After a reboot
|
|
|
|
A session file outlives a reboot, so the plugin compares the boot ID at startup.
|
|
A different ID means the session went stale: nothing that was frozen still
|
|
exists, and units that were stopped may have come back on their own.
|
|
|
|
A stale session gets a full restore pass before the plugin clears it. A stopped
|
|
unit that is not `enabled` is still down after a reboot, and putting it
|
|
back is what you were told would happen. Frozen targets died with the reboot, so
|
|
their thaw does nothing. This can fire a few `systemctl start` calls
|
|
soon after login, and the plugin logs each one.
|
|
|
|
Within the same boot the plugin always keeps the session, even when everything
|
|
looks like it is running, because that is the case where something may still sit
|
|
frozen and need thawing. A session written before version 0.2.0 carries no boot
|
|
ID, and the plugin treats it as current so it does not abandon targets that may
|
|
still be suspended.
|
|
|
|
## Notes
|
|
|
|
- The plugin stores its session snapshot in Noctalia's plugin data directory. It
|
|
makes no network requests.
|
|
- `renice` is absent by design. It looks like the safe middle ground and is not.
|
|
With `RLIMIT_NICE=0`, the default, an unprivileged process lowers priority and
|
|
never raises it back, so a renice would degrade every process it touched for
|
|
the life of that process. `freeze` gives you the reversible option instead.
|
|
Feral GameMode needs membership in a `gamemode` group to renice at all for the
|
|
same reason.
|
|
- No I/O weighting for user units. cgroup v2 delegates `cpu`, `memory`, and
|
|
`pids` to the user manager, and not `io`.
|
|
- The toggle widget carries the readings in its tooltip. The monitor shows your
|
|
selected readings in the bar and puts the rest in its tooltip.
|
|
- The panel shows no per-core CPU breakdown and no top-process list.
|
|
- Nothing places the widget on your bar for you. The manifest has no field for a
|
|
default bar section, and a plugin can read its settings but not write them, so
|
|
bar layout stays yours. Add it under **Settings → Bar**.
|
|
- VRAM appears where the shell reports it, which means NVML on NVIDIA.
|
|
- The plugin toggles no compositor effects. Animations, blur, and shadows belong
|
|
to your compositor's own config.
|
|
- Feral GameMode exposes a `ClientCount` property that emits changes and a
|
|
`GameRegistered` signal on `com.feralinteractive.GameMode`, and `org.scx.Loader`
|
|
switches sched_ext schedulers. Arming gamer mode from either one would work and
|
|
is not built.
|
|
|
|
## License
|
|
|
|
MIT
|