Power Profiles
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-14
|
||||
@@ -0,0 +1,48 @@
|
||||
## Context
|
||||
|
||||
Currently, the system uses a default power management configuration. There is no easy way for the user to switch between different power-saving modes for different use cases, such as presenting, running a headless server, or normal desktop usage.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Implement a script to control power management settings.
|
||||
- Define three distinct power profiles: `caffeinated`, `headless`, and `normal`.
|
||||
- Integrate the script with Hyprland for key-based switching.
|
||||
- Provide visual feedback of the current profile in the Waybar status bar.
|
||||
- Manage the entire configuration using Nix and Home Manager.
|
||||
|
||||
**Non-Goals:**
|
||||
- Creating a graphical user interface for configuration.
|
||||
- Supporting operating systems other than NixOS.
|
||||
- Supporting display managers other than Wayland/Hyprland.
|
||||
|
||||
## Decisions
|
||||
|
||||
1. **State Management**: A state file at `~/.local/state/power-profile` will store the name of the currently active profile (e.g., `caffeinated`). This simple approach allows the control script and Waybar module to easily share the current state.
|
||||
|
||||
2. **Control Script**: A `bash` script will be the core of this feature. It will accept arguments like `next`, `prev`, or a specific profile name (`caffeinated`, `headless`, `normal`). When called, it will:
|
||||
a. Update the state file.
|
||||
b. Kill any existing `hypridle` process.
|
||||
c. Start a new `hypridle` process with the configuration corresponding to the selected profile.
|
||||
d. Send a signal to Waybar to refresh the module (`pkill -RTMIN+8 waybar`).
|
||||
|
||||
3. **Power Management Daemon**: `hypridle` will be used to manage idle events. We will define three separate service configurations for it, one for each profile, with different timeouts for screen blanking (`hyprlock`), and system suspension.
|
||||
- **Caffeinated**: No timeouts. `hypridle` will run with no events configured.
|
||||
- **Headless**: Timeout for screen blanking and locking, but no suspend action.
|
||||
- **Normal**: Default timeouts for screen blanking, locking, and suspension.
|
||||
|
||||
4. **Waybar Module**: A `custom/power-profile` module in Waybar will be used.
|
||||
- It will use Waybar's `on-click` functionality to call the control script to cycle profiles.
|
||||
- It will execute a small script (`exec`) that reads the state file and outputs JSON with an icon representing the current state (e.g., `{"text": "", "tooltip": "Profile: Caffeinated"}`).
|
||||
- The module will update automatically when it receives a real-time signal, which the control script will send.
|
||||
|
||||
5. **Hyprland Keybinding**: A `bind` entry in `hyprland.conf` will be added to call the control script to cycle through the profiles, e.g., `bind = $mainMod, BRACKETRIGHT, exec, ~/dotfiles/scripts/power-profile.sh next`.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **[Risk]** The `pkill hypridle` command could potentially interfere with other user-started `hypridle` instances if they exist.
|
||||
- **Mitigation**: This is unlikely in a typical user session. The script will be part of a managed dotfiles configuration where only one instance is expected.
|
||||
- **Mitigation**: `systemctl --user restart hypridle.service` should restart hypridle with new configuration
|
||||
|
||||
- **[Trade-off]** Using a state file on disk introduces a small amount of I/O and a potential point of failure if file permissions are incorrect.
|
||||
- **Rationale**: This is a simple and reliable IPC mechanism for this use case, preferable to more complex solutions. The file will be managed by Home Manager, ensuring correct permissions.
|
||||
@@ -0,0 +1,23 @@
|
||||
## Why
|
||||
|
||||
Users need a quick way to switch between different power management configurations on their system depending on the task at hand. For example, a "caffeinated" mode is needed to prevent the system from sleeping during presentations or long-running tasks, while a "headless" mode is useful for running the machine as a server, and a "normal" mode for everyday desktop use.
|
||||
|
||||
## What Changes
|
||||
|
||||
- A script will be created to manage three power management profiles: `caffeinated`, `headless`, and `normal`.
|
||||
- A Waybar module will be added to display the current power profile.
|
||||
- A Hyprland keybinding will be configured to cycle through the power profiles.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `power-profile-management`: Manages power-saving settings for different operational modes, including screen blanking, locking, and system suspension. It also provides a visual indicator for the current mode in the Waybar status bar.
|
||||
|
||||
### Modified Capabilities
|
||||
- None
|
||||
|
||||
## Impact
|
||||
|
||||
- **Code:** New Nix code for the power management script and Waybar/Hyprland configuration.
|
||||
- **System:** Affects system-wide power settings managed by `swayidle` or a similar service.
|
||||
- **User Interface:** A new module will appear in the Waybar status bar.
|
||||
@@ -0,0 +1,48 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Manage Power Profiles
|
||||
The system SHALL provide three distinct power management profiles: `caffeinated`, `headless`, and `normal`.
|
||||
|
||||
#### Scenario: Caffeinated Profile
|
||||
- **WHEN** the `caffeinated` profile is active
|
||||
- **THEN** the system SHALL NOT blank the screen.
|
||||
- **AND** the system SHALL NOT lock the screen.
|
||||
- **AND** the system SHALL NOT suspend.
|
||||
|
||||
#### Scenario: Headless Profile
|
||||
- **WHEN** the `headless` profile is active
|
||||
- **THEN** the system SHALL blank the screen after a timeout.
|
||||
- **AND** the system SHALL lock the screen when it blanks.
|
||||
- **AND** the system SHALL NOT suspend.
|
||||
|
||||
#### Scenario: Normal Profile
|
||||
- **WHEN** the `normal` profile is active
|
||||
- **THEN** the system SHALL blank the screen after a default timeout.
|
||||
- **AND** the system SHALL lock the screen when it blanks.
|
||||
- **AND** the system SHALL suspend after a longer default timeout.
|
||||
|
||||
### Requirement: Cycle Through Power Profiles
|
||||
The system SHALL allow the user to cycle through the power profiles using a keybinding.
|
||||
|
||||
#### Scenario: Cycle Forward
|
||||
- **WHEN** the user presses the "next profile" keybinding
|
||||
- **THEN** the active power profile SHALL change from `normal` to `caffeinated`, `caffeinated` to `headless`, and `headless` to `normal`.
|
||||
|
||||
#### Scenario: Cycle Backward
|
||||
- **WHEN** the user presses the "previous profile" keybinding
|
||||
- **THEN** the active power profile SHALL change from `normal` to `headless`, `headless` to `caffeinated`, and `caffeinated` to `normal`.
|
||||
|
||||
### Requirement: Visual Indicator for Current Profile
|
||||
The system SHALL display the current power profile mode in the Waybar status bar.
|
||||
|
||||
#### Scenario: Display Caffeinated Icon
|
||||
- **WHEN** the `caffeinated` profile is active
|
||||
- **THEN** a "caffeinated" icon SHALL be visible in the Waybar status bar.
|
||||
|
||||
#### Scenario: Display Headless Icon
|
||||
- **WHEN** the `headless` profile is active
|
||||
- **THEN** a "headless" icon SHALL be visible in the Waybar status bar.
|
||||
|
||||
#### Scenario: Display Normal Icon
|
||||
- **WHEN** the `normal` profile is active
|
||||
- **THEN** a "normal" icon SHALL be visible in the Waybar status bar.
|
||||
@@ -0,0 +1,39 @@
|
||||
## 1. State Management and Control Script
|
||||
|
||||
- [x] 1.1 Create the state directory `~/.local/state` if it doesn't exist.
|
||||
- [x] 1.2 Create the control script `scripts/power-profile.sh`.
|
||||
- [x] 1.3 Implement logic in the script to read and write the current profile to `~/.local/state/power-profile`.
|
||||
- [x] 1.4 Implement `next` and `prev` logic to cycle through `normal`, `caffeinated`, and `headless`.
|
||||
- [x] 1.5 Add logic to kill existing `swayidle` processes.
|
||||
- [x] 1.6 Add logic to start `swayidle` with profile-specific arguments.
|
||||
- [x] 1.7 Add logic to send a signal to Waybar to refresh the module (`pkill -RTMIN+8 waybar`).
|
||||
|
||||
## 2. NixOS and Home Manager Configuration
|
||||
|
||||
- [x] 2.1 Create a new Nix module `modules/power-profiles.nix` for the feature.
|
||||
- [x] 2.2 In the module, define the three `swayidle` service configurations.
|
||||
- [x] 2.3 Package the `power-profile.sh` script using `pkgs.writeShellScriptBin`.
|
||||
- [x] 2.4 Add the script package to `home.packages`.
|
||||
- [x] 2.5 Ensure the state directory is created using `home.file`.
|
||||
|
||||
## 3. Waybar Integration
|
||||
|
||||
- [x] 3.1 Add a `custom/power-profile` module to the Waybar configuration in `config/waybar/config`.
|
||||
- [x] 3.2 Configure the module's `exec` to a script that reads the state file and outputs JSON with the correct icon and tooltip.
|
||||
- [x] 3.3 Configure `on-click` to call `power-profile.sh next`.
|
||||
- [x] 3.4 Configure `on-click-right` to call `power-profile.sh prev`.
|
||||
- [x] 3.5 Add styles for the module in `config/waybar/style.css`.
|
||||
- [x] 3.6 Define the real-time signal number for updates (e.g., `signal: 8`).
|
||||
|
||||
## 4. Hyprland Integration
|
||||
|
||||
- [x] 4.1 Add a keybinding to `config/hypr/hyprland.conf` to call `power-profile.sh next`.
|
||||
- [x] 4.2 Add a keybinding to call `power-profile.sh prev`.
|
||||
|
||||
## 5. Verification
|
||||
|
||||
- [ ] 5.1 Rebuild the system with `home-manager switch`.
|
||||
- [ ] 5.2 Verify that the Waybar module appears and shows the default `normal` state.
|
||||
- [ ] 5.3 Test the keybindings to cycle through the profiles and observe the icon change.
|
||||
- [ ] 5.4 Check that `swayidle` processes are restarted correctly with each profile change.
|
||||
- [ ] 5.5 Verify the behavior of each profile (e.g., no suspension in `caffeinated` mode).
|
||||
@@ -1,4 +1,3 @@
|
||||
schema: spec-driven
|
||||
|
||||
context: |
|
||||
Tech stack: Unix System, NixOS, Flakes, Home-manager
|
||||
context: |
|
||||
Tech stack: Unix System, NixOS, Flakes, Home-manager
|
||||
|
||||
Reference in New Issue
Block a user