Framework Laptop Tools
Experimental native desktop/tray controls for Framework Laptop 13 Pro
(Intel Core Ultra Series 3). Other Framework models are not yet validated.
Install framework-laptop-tools, then open Framework Laptop Tools from the
application menu or Fedora Tools settings. Installation changes no hardware
settings. Hardware changes require administrator authorisation.
The window has Monitor, Lighting, Cooling, Battery, CPU, Tray icon and Preferences tabs. Bounded hardware settings use sliders with numeric fields for precise entry. All settings tabs share a Save and Apply / Undo changes bar. Editing stages changes without writing hardware, tray settings, sampling intervals or autostart. The bar stays visible across tabs. Save applies all pending settings with one administrator authorisation for hardware changes; Undo discards all unsaved edits. Successful saves become the new Undo baseline. If a hardware operation fails, earlier operations may already have applied; remaining edits stay pending. CPU slider bounds are read from Linux's hardware-frequency limits.
The Monitor page has CPU/GPU frequency, fan RPM, temperature and battery graphs. The battery heading shows full capacity, health and cycle count when available. Capacity calculated from charge capacity and nominal voltage is approximate. Temperature labels distinguish CPU-area/board sensors from die readings; raw sysfs paths remain available in tooltips. CPU frequency is Linux's reported average across CPU policies, not an instantaneous measurement of every core. GPU GT domains are shown separately rather than assuming they are identical. Click a coloured legend to toggle its series. Hidden series remain in the legend, greyed out and crossed out. Main temperature sensors are shown first; additional sensors are in a collapsed section that remembers their selections, not its open state. NVMe composite is the drive's overall reported temperature; numbered NVMe sensors are device-specific. Memory (SPD) measures the memory module, while EC area sensors are separate from processor/module readings. Each graph starts with blue. Further colours maximise their minimum OKLab distance from enabled colours within a readable candidate palette. Enabling a line assigns its colour; existing enabled lines keep theirs. Disabled colours are released.
Axes use round ticks and relative ages, with units below the vertical axes. Hover draws a guide at the same timestamp on every graph, even when their time spans differ. The popup describes only the graph under the pointer, stays visible while hovering and follows new samples without needing mouse movement. Hover for timestamps and the nearest available readings; no readings are invented across gaps or sleep. Battery charge uses the left percentage axis and rate the right watts axis (positive charging, negative discharging). Blue-grey bands mark logind-observed sleep; faint red bands mark observed charger connection. Plug changes during sleep are unknown, so AC bands are not extended through sleep. There is no history from before app startup. The Monitor history slider spans 5 minutes to 24 hours on a logarithmic scale. Stretch available data fits shorter recordings to the graph width until the selected span has been collected. These viewing controls take effect immediately and are remembered; the default is 24 hours with stretching enabled. All detected sensors retain 24 hours of readings in memory, even when hidden, plus one boundary sample for clipping. Quitting the app clears this history. Changing the sampling interval preserves older lines and hover readings at their original cadence; missing readings and sleep remain gaps. Monitor and tray graphs fill each pixel column from its time-weighted average to its maximum when readings are compressed. With sparse readings, columns follow straight lines between samples. Bands have a minimum vertical height of two logical pixels, padded equally above and below; they never widen sideways. Monitor columns align to physical pixels and the vertical minimum follows display scaling. Plasma scales the tray's 64-pixel icon image to its chosen display size. Missing data and sleep remain gaps. Hover readings report the original samples.
Power usage shows the detected RAPL domains (CPU package, cores, uncore and memory) and hwmon power readings. Unvalidated platform power and ACPI fan power-table entries are excluded; fan speed and duty cycle remain available separately. These domains overlap and must not be added together. Uncore coverage depends on the hardware; it is not labelled GPU power. RAPL watts are energy-counter differences divided by elapsed monotonic time. Wraparound is handled; missing reads, long gaps, detected resets and sleep restart the baseline instead of producing a spike. MSR/MMIO duplicates are not plotted twice. The counters must be readable; this app does not change their permissions. Power readings are also available as tray metrics, using the same history.
Sampling choices are 0.5/1/2/4 seconds for frequencies, power, fan and temperatures, and 15/30/60/120 seconds for the battery graph. Tray autostart is optional. Closing the window leaves monitoring in the tray; Quit exits the application. The Tray icon tab supports one to ten independently configured icons, each showing an application icon, a history graph, or a number. Settings cards wrap to fit the window. New icons default to the application icon; your existing configuration becomes Icon 1. Reducing the count keeps hidden drafts until Save and Apply; saving retains only visible icons. The Move icon arrows swap all settings with the adjacent icon while keeping the position numbers fixed. Undo restores the saved set. All icons share sensor sampling and history, and each has its own appearance and hover choices. Sources include CPU usage, CPU/GPU frequency, temperatures, charge level and battery rate. Sensor graphs share Monitor's history, including gaps, regardless of which sensor is selected for the tray. CPU usage also retains 24 hours. Switching readings or resuming from sleep does not clear history. Frequency numbers use GHz. The tray has optional borders, a background colour with adjustable opacity, line and fill colours, and optional area fill (including adjustable opacity). Frequency ceilings and temperature ranges are saved per sensor; battery rate also has adjustable bounds (initially −75–75 W), while percentages use 0–100. Tray graphs show 10, 15, 20 or 30 seconds, or 1, 2 or 5 minutes, ending at now. The default is one minute. History length is staged with the other tray settings. Older readings are clipped, and unavailable history stays blank. Outside readings can follow the inner edge, optionally in a different colour, or be hidden. The line remains inside the border when a border is enabled. Colour buttons show the opaque RGB swatch and label opacity separately, so a translucent fill is not mistaken for a darker RGB colour. Background opacity can be zero for full transparency; the former Transparent background checkbox migrates to zero opacity without changing the RGB colour. History and out-of-range controls are nested under the History graph display choice. Hover information is configured separately: CPU usage; battery level and remaining/full energy in mWh, followed by signed power and time to the charge target; fan RPM and duty percentage; and the main CPU, memory, NVMe, battery and board temperatures. Multiple temperatures have a heading and indented lines. Missing sensors are unavailable in the settings page. Batteries reporting only charge are converted to mWh using nominal voltage. Choose zero to three top CPU applications, displayed below CPU usage in descending order. Process sampling stops when no icon requests it; the previous checkbox migrates to zero or one. Readable CPU counters are sampled while enabled. Processes are grouped by application where identifiable, otherwise by executable. KDE's catalogue supplies friendly names; ambiguous matches use executable names. Percentages use total CPU capacity, matching the CPU line, rather than one core. Short-lived processes between samples cannot be counted. No process history is written to disk. Charging estimates to a reduced limit use the current charging rate and are marked approximate. Hover choices use the shared Save and Apply / Undo controls. Plasma applies its own hover highlight to tray icons; the app does not patch the system tray to suppress that effect.
Controls and limits
- Keyboard brightness: 0–100%. Use Fn+Space to leave or enter Auto mode. The inspected 13 Pro firmware does not expose a host command to change that mode; its ambient-light logic overrides manual percentage changes in Auto.
- Power-button brightness: 1–100%, or firmware Auto. This is the illuminated power button surrounding the fingerprint reader, not its authentication. The Automatic brightness checkbox disables the slider; both mode and brightness are staged until Save and Apply. Unchecking it allows a fixed brightness to be selected.
- Fan: firmware Auto, manual duty, or a four-point curve. Manual values
range from 0–100%, including fan off. Manual speeds below 30% show a warning.
Saving manual or curve speeds below 30% also requires explicit confirmation.
Four editable temperatures must increase between 20 and 85 °C, reaching 100%
duty at the final point. Speeds between points are interpolated. The hottest EC sensor
drives the curve. Speed increases immediately and decreases gradually.
The privileged worker returns to Auto on suspend, reboot, a sensor fault,
high temperatures, watchdog timeout or service exit. It does not change
thermal warning/shutdown thresholds. Overrides remain active with the GUI closed.
Saving an override writes
/etc/framework-laptop-tools/fan.jsonand enables the worker at boot and after sleep. Sleep still stops the worker and restores Auto first. Failure restores Auto without a restart loop; saved settings are retried at the next boot/resume or explicit Save and Apply. Legacy temporary overrides are still recognised until stopped, but newly saved overrides always persist; installation itself does not enable them. Selecting firmware Auto removes saved settings and disables automatic startup. Do not combine with another fan controller. - Battery charge limit: 50–100%, stored by the firmware. Charge-power settings convert watts to a current limit using present battery voltage; actual watts vary with voltage and system/charger limits. Zero restores firmware defaults. This is battery charging power, not wall power or total laptop power. Charge current has no read-back command in the interface used here. The C-rate used by some other utilities expresses current relative to battery capacity: 1 C means 4.64 A for a 4.64 Ah battery, not a fixed number of watts.
- CPU: minimum/maximum frequency, governor and energy preference, with optional
separate battery/AC profiles. Frequency bounds are clamped per policy: a
requested 4.5 GHz maximum does not restrict a P-core to a slower core's
3.3 GHz ceiling. These are bounds, not guaranteed clock speeds.
On Intel hybrid systems, kernel
cpu_core/cpu_atomPMU membership identifies P-core and E-core policy groups, each with independent overrides. E-core limits clamp to each E-core's own ceiling, including lower-power E-cores. If the kernel cannot identify the groups unambiguously, a single shared range is offered.
Lighting and battery readings refresh on entry and every two seconds while their tab is visible. Unsaved edits are protected. Undo restores the unedited snapshot; normal live refresh then resumes. Charge-current limits cannot be read back, so their initial draft is firmware default, not a claim about current hardware state. Graph legend toggles remain immediate viewing controls, separate from staged settings tabs.
Battery time remaining/full uses UPower when available. Time to a custom charge limit is approximate, based on present current; charging taper makes it less accurate near full. No estimate is displayed when the needed readings are absent.
Saved CPU profiles
CPU editing is staged. Splitting copies the shared values into both columns; battery is on the left and AC on the right. Joining uses the battery column. The hidden AC draft remains recoverable by splitting again until Save and apply commits the joined profile. Shared configurations store only one copy. Undo changes restores the last saved configuration. Background firmware refreshes do not overwrite a dirty CPU draft.
Frequency bounds, governor and energy preference are independent. Frequency overriding is unchecked by default, and both dropdowns default to auto. Auto means this tool never writes that attribute; it is not a preset or reset. Saving all-Auto profiles with frequency overriding off stops/disables the CPU service. Existing CPU limits are left unchanged, including when giving up a previous override, switching to an Auto power-source profile, or uninstalling. There is no TuneD reload or blanket restoration that could disturb another controller. Avoid assigning the same setting to multiple controllers.
The top of the CPU page always shows live Linux values, independently of the draft below. The frequency sliders are disabled when their override is unchecked; governor and EPP remain independently selectable. Tooltip explanations replace the longer instructions formerly at the bottom of the page.
Explicit overrides apply at boot, resume, power-source changes and successful
TuneD profile changes after two seconds for the transition to settle. No TuneD
dependency is required. The service works with the GUI closed; configuration is
root-owned at /etc/framework-laptop-tools/cpu.json. Earlier all-or-nothing configurations
are converted to independent overrides while preserving whether they were enabled.
With active Intel HWP, the Performance governor forces performance EPP and rejects other EPP values. For an explicitly selected Performance governor, this tool uses Powersave when the selected EPP (or the live EPP when Auto) is incompatible. The dropdown retains the user's choice and displays a warning. With EPP on Auto, the service observes EPP changes and reevaluates that explicit governor choice.
If governor is Auto and the live Performance governor blocks an explicitly chosen non-performance EPP, applying fails with a clear message: choose Powersave or leave EPP on Auto. It does not silently take over the Auto governor. Explicit governor changes can themselves affect EPP inside the kernel; Auto does not undo those kernel side effects. Linux does not provide independent control of every combination.
Thermal, power and boost limits still apply. Powersave on active Intel HWP allows dynamic clocks and boost; it does not mean locking the CPU at minimum frequency.
Interfaces
No firmware patch, raw port I/O, downloaded executable, or third-party service
is used. Monitoring reads Linux sysfs and UPower. A restricted KAuth helper
uses sysfs and /dev/cros_ec for documented EC commands. Model checks are
repeated in the privileged helper, not just in the GUI.
References:
- Framework's hardware library and CLI
- 13 Pro keyboard firmware
- Framework LED commands
- Linux EC hardware monitor
- Linux CPU frequency controls
- Intel governor and EPP behaviour
- TuneD profile documentation
- Linux battery units
- Framework Control and framework-tool-tui provide useful interface references; their code is not bundled here.