Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
dc21f3c
fix(turbo): a falcond that crashed here does not turn Turbo off from …
ruscher Oct 10, 2026
c3a2148
fix(ui): centre the welcome grid with a clamp
ruscher Oct 10, 2026
3c00bef
fix(logs): lines other components print at every start are debug
ruscher Oct 10, 2026
de92922
docs: fold the issue #4 and CI audit reports into permanent pages
ruscher Oct 10, 2026
27f7bde
build: one main menu category, and ignore two more leftovers
ruscher Oct 10, 2026
30bc3f8
fix(about): the developer line names the developer
ruscher Oct 10, 2026
7a9c25c
build: declare Rust 1.88, the oldest that builds the workspace
ruscher Oct 10, 2026
41901ee
refactor: drop lint allows that suppress nothing, and comments that r…
ruscher Oct 10, 2026
b8d00a6
i18n(ui): "label: value" and counts as each language writes them
ruscher Oct 10, 2026
1c311d8
docs: remove screenshots nothing shows
ruscher Oct 10, 2026
f4a622a
fix(booster): read the governor and EPP on every CPU
ruscher Oct 10, 2026
090c1c9
fix(fg): record lsfg-vk entries before writing lsfg-vk's file
ruscher Oct 10, 2026
75fa4a8
fix(turbo): bring Steam and Heroic along a preset change once they close
ruscher Oct 10, 2026
9784488
fix(turbo): take away a preset whose record cannot be read
ruscher Oct 10, 2026
cf26eb3
fix(turbo): remove the preset's vkBasalt file when the preset goes
ruscher Oct 10, 2026
eaba2b5
fix(config): write video.toml and environment.d in one rename
ruscher Oct 10, 2026
a643d71
fix(config): one session bus connection for reading the environment
ruscher Oct 10, 2026
8e313ce
fix(graphics): one change to a game's files at a time
ruscher Oct 10, 2026
3df7863
fix(graphics): a file behind a linked folder stays recorded
ruscher Oct 10, 2026
96e355d
fix(ai-graphics): the buttons go grey in the click that starts a change
ruscher Oct 10, 2026
1c3cdf7
fix(graphics): the Profiles menu's Restore is the page's Restore
ruscher Oct 10, 2026
7b420ba
fix(i18n): AI Graphics lays labels and placeholders out as translated
ruscher Oct 10, 2026
8e1b7bd
refactor: drop two copies of shared helpers
ruscher Oct 10, 2026
cceaeb1
refactor(ui): AI Graphics uses the shared i18n::labelled
ruscher Oct 10, 2026
3cbf778
build(unit): cap the helper's memory and tasks
ruscher Oct 10, 2026
891c52c
build(unit): make /run read-only for the helper
ruscher Oct 10, 2026
6de71d8
build(unit): keep the machine-wide sysfs trees read-only
ruscher Oct 10, 2026
65d7f22
fix(helper): leave falcond alone when it is already as asked
ruscher Oct 10, 2026
5c3517f
fix(helper): refuse profiles named after system processes
ruscher Oct 10, 2026
b404d9c
fix(helper): let Polkit prompt only a caller that asked for it
ruscher Oct 10, 2026
e78d4b8
test(helper): run the authorization test on the shipped bus policy
ruscher Oct 10, 2026
8b5117f
i18n(polkit): translate the policy through gettext
ruscher Oct 10, 2026
9534755
docs(security): the helper's new limits
ruscher Oct 10, 2026
cfc172f
fix(steam): an account in both Steam installs is two configurations
ruscher Oct 10, 2026
9038745
fix(steam): LaunchOptions goes inside an empty app block
ruscher Oct 10, 2026
7c5abe7
fix(steam): replace launcher files durably, one edit at a time
ruscher Oct 10, 2026
f44bcc4
fix(mangohud): keep any file the user has before a style replaces it
ruscher Oct 10, 2026
a48dca7
fix(mangohud): record the Steam word per account, and write all or none
ruscher Oct 10, 2026
f9b68af
fix(steam): Gamescope's variables record only what went in, by account
ruscher Oct 10, 2026
768163a
fix(mangohud): Lutris Off puts back the line the game had
ruscher Oct 10, 2026
37d898c
fix(profiles): deleting a profile takes its launch settings out of th…
ruscher Oct 10, 2026
8d1e53b
fix(profiles): a deleted profile says what its launchers kept
ruscher Oct 10, 2026
dcf0ef3
docs(game-settings): steam_env is what was asked; the record is per a…
ruscher Oct 10, 2026
ec5f479
fix(running): Chromium helpers and pre-launch programs are not the game
ruscher Oct 10, 2026
f910737
perf(running): keep what was learned of the running game
ruscher Oct 10, 2026
0061f32
perf(systemd): read a unit's properties without zbus's cache
ruscher Oct 10, 2026
b3d920e
refactor: remove dead detection helpers and stale lint allows
ruscher Oct 10, 2026
a2c5244
perf(watch): wake for the status file only, not its neighbours
ruscher Oct 10, 2026
297e8fe
perf(ui): look for the running game less often while one is known
ruscher Oct 10, 2026
b6cb74c
perf(ui): one reading of falcond's unit for the tray and Home
ruscher Oct 10, 2026
0ea275b
perf(ui): Home's readings and Logs' follow sleep while hidden
ruscher Oct 10, 2026
3317253
docs(games): no public doc link to a private constant
ruscher Oct 10, 2026
1cf08de
docs: the 2.3.2 release notes, in the README and AppStream
ruscher Oct 10, 2026
61fac4f
i18n: 2.3.2's texts in every catalogue
ruscher Oct 10, 2026
4caefb7
release: 2.3.2
ruscher Oct 10, 2026
c81c5c2
fix(turbo): a mode the login set does not fail every preset change
ruscher Oct 10, 2026
ad8ab66
docs: the About screenshot of 2.3.2
ruscher Oct 10, 2026
10c6406
build(pkgbuild): the libraries bigame-ui links, and GTK 4.14 as its f…
ruscher Oct 10, 2026
695d44c
refactor(graphics): fixed-size records through as_chunks (Clippy 1.99)
ruscher Oct 10, 2026
7bd501a
test(helper): Peer through Ping, which needs no machine-id
ruscher Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .github/scripts/check-package-contents.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
# Check what the built bigame-mode package installs: every file Big Game Mode
# needs at runtime, with sane modes and owners, and the references between
# them (desktop entry -> binary and icon, D-Bus activation -> systemd unit ->
# binary, bus policy -> bus name, AppStream -> desktop entry).
# binary, bus policy -> bus name, AppStream -> desktop entry, Polkit policy ->
# its source with the translations merged in).
#
# .github/scripts/check-package-contents.sh <package.pkg.tar.zst> <new-directory>
#
Expand Down Expand Up @@ -163,6 +164,29 @@ if [[ -f "$bus_policy" ]]; then
fi
fi

polkit_policy="$root/usr/share/polkit-1/actions/${app_id}.policy"
if [[ -f "$polkit_policy" ]]; then
# The installed policy is the source with the catalogues merged in: the
# same actions, each with its English description and message as written.
source_policy="$repo/data/${app_id}.policy"
if [[ "$(grep -o '<action id="[^"]*"' "$polkit_policy")" == "$(grep -o '<action id="[^"]*"' "$source_policy")" ]]; then
ok "Polkit policy has the actions of data/${app_id}.policy"
else
fail "Polkit policy's actions differ from data/${app_id}.policy"
fi
if [[ "$(grep -E '<(description|message)>' "$polkit_policy")" == "$(grep -E '<(description|message)>' "$source_policy")" ]]; then
ok "Polkit policy keeps every English description and message"
else
fail "Polkit policy's English descriptions or messages differ from the source"
fi
# polkit matches pt_BR, never msgfmt's pt-BR.
if grep -qE 'xml:lang="[a-z]{2,3}-[A-Z]{2}"' "$polkit_policy"; then
fail "Polkit policy has a translation tagged ll-CC, which polkit never serves"
else
ok "Polkit policy's translations are tagged as polkit looks them up"
fi
fi

if [[ -f "$metainfo" ]]; then
launchable="$(sed -n 's:.*<launchable type="desktop-id">\(.*\)</launchable>.*:\1:p' "$metainfo")"
want_same "AppStream launchable" "$launchable" "${app_id}.desktop"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: Backend tests
#
# Not run on its own for pushes or pull requests: build-package.yml calls it
# beside the package, so each push or pull request is one run with both
# jobs (see docs/ci-workflows-audit.md). A manual run checks any branch.
# jobs (see docs/CI.md). A manual run checks any branch.

on:
workflow_call:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ name: Build Package
# stable-*, and manual runs of such a branch. A failed run is not built, and
# a branch with '/' breaks their recipe, so pull requests are checked by
# package-check.yml, which calls this workflow under another name.
# See docs/ci-workflows-audit.md.
# See docs/CI.md.

on:
push:
Expand Down Expand Up @@ -245,7 +245,7 @@ jobs:
echo "errors=$errors" >> "$GITHUB_OUTPUT"
echo "warnings=$warnings" >> "$GITHUB_OUTPUT"
# Errors fail the build. Warnings are reviewed in
# docs/ci-workflows-audit.md and shown in the run summary: the
# docs/CI.md and shown in the run summary: the
# owned empty directories, libraries GTK already pulls in, and
# programs or services the package runs rather than links.
if (( errors )); then
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/package-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: Package check
# and the package), for pull requests and manual runs of any branch, as one
# run. Under this name a successful run is not handed to the BigLinux package
# builders, which act on "Build Package" runs only (see build-package.yml).
# See docs/ci-workflows-audit.md.
# See docs/CI.md.

on:
pull_request:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ target/
.serena/
.claude/
.DS_Store
Thumbs.db
*.save
__pycache__/
.pytest_cache/
.mypy_cache/
Expand Down
79 changes: 51 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ One switch for per-game performance, presets for what games should favour,
AI Graphics with full backup and undo, and a page that shows — with evidence —
what is really in effect.

[![Version](https://img.shields.io/badge/version-2.3.1-6c5ce7?style=for-the-badge)](https://github.com/biglinux/bigamemode/releases)
[![Version](https://img.shields.io/badge/version-2.3.2-6c5ce7?style=for-the-badge)](https://github.com/biglinux/bigamemode/releases)
[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-2ea44f?style=for-the-badge)](LICENSE)
[![Rust](https://img.shields.io/badge/Rust-1.85%2B-dea584?style=for-the-badge&logo=rust&logoColor=white)](https://www.rust-lang.org/)
[![Rust](https://img.shields.io/badge/Rust-1.88%2B-dea584?style=for-the-badge&logo=rust&logoColor=white)](https://www.rust-lang.org/)
[![GTK4](https://img.shields.io/badge/GTK4-libadwaita-4a86cf?style=for-the-badge&logo=gnome&logoColor=white)](https://gnome.pages.gitlab.gnome.org/libadwaita/)
[![Languages](https://img.shields.io/badge/languages-29-f39c12?style=for-the-badge)](#languages)

Expand Down Expand Up @@ -47,26 +47,48 @@ a way back.
> One rule runs through the project: **nothing is offered that the machine
> cannot do, and nothing is called an improvement without a measurement.**

## What's new in 2.3.1

- **Processors without AVX2/BMI2** (Sandy Bridge, Ivy Bridge and older):
falcond 2.0.14 built for x86-64-v3 dies there with an illegal instruction
([#4](https://github.com/biglinux/bigamemode/issues/4)). Big Game Mode now
names that failure (Home, Details, the tray and the support report) instead
of suggesting a restart, and **Turbo still comes on** with the general
settings, as on a system without falcond. That falcond build is not started
again until the package changes; a falcond built for the x86-64 baseline is
used as soon as it is installed. See
[docs/issue-4-falcond-sigill.md](docs/issue-4-falcond-sigill.md).
- **A falcond that crashes at start** no longer stays enabled to crash again
at every boot, and Turbo can be turned off after it.
- **Game detection:** the Steam runtime's library cache tool (`ldconfig`) is
no longer taken for the running game.
- **Details:** fix commands with `&&` no longer log a markup error.
- **Packaging:** the BigLinux package builders receive only the branches they
can build (`main`, `testing-*`, `stable-*`); pull requests are checked by a
separate workflow. See
[docs/ci-workflows-audit.md](docs/ci-workflows-audit.md).
## What's new in 2.3.2

A stability release, from a full review of the code, the helper and the
package.

- **Turbo on processors falcond cannot run on** (Sandy Bridge, Ivy Bridge and
older with a falcond built for x86-64-v3) no longer switches itself off a
few seconds after it starts, while the power profile stayed at performance.
See [CPU compatibility](docs/CPU-COMPATIBILITY.md).
- **Nothing left behind:** turning Turbo off or changing the preset reaches
Steam and Heroic once they are closed, and deleting a profile takes its
launch options out of Steam, Heroic and Lutris. Profiles says which launcher
to close when one was open.
- **Your settings stay yours:** only what Big Game Mode added is removed,
account by account (a native and a Flatpak Steam are two installs); your
own launch options, Lutris' MangoHud line, and MangoHud and vkBasalt files
(also ones that are not UTF-8, and dotfile-manager symlinks) are kept.
- **AI Graphics** makes one change at a time to a game, so a double click can
no longer mix two installs' backups; Restore from Profiles works as on the
AI Graphics page.
- **Idle cost:** one systemd reading for the tray and Home, no property cache
traffic, slower polling while a game runs, and nothing woken while the
window is hidden.
- **Game detection:** Electron/Chromium helpers, the Steam runtime's locale
tools, Windows installers (`msiexec`, .NET) and crash reporters are not
taken for the game.
- **A stricter helper:** `/run` and the machine-wide `/sys` trees read-only,
memory and task limits, no systemd reload when nothing changes, profiles
named after system processes refused. Its Polkit messages are now
translated with the rest of the application.
- **Quality:** Rust 1.88 declared (the real minimum), French, Chinese and
other languages get their own "label: value" punctuation, and the About
dialog names the developer.

### 2.3.1

- Processors without AVX2/BMI2: a falcond built for x86-64-v3 is named as
the cause instead of a retry being suggested, and Turbo comes on with the
general settings
([#4](https://github.com/biglinux/bigamemode/issues/4)).
- A falcond that crashes at start no longer stays enabled; the Steam
runtime's `ldconfig` is not taken for the game.

### 2.3.0

Expand Down Expand Up @@ -311,7 +333,7 @@ terminal without opening a window (`--network` adds the DNS measurements).
| A frame generation option is disabled | lsfg-vk is not installed or your `Lossless.dll` is not usable by it; the row says which |
| AI Graphics left a game broken | Profiles → the game's menu → **Restore the game's graphics**, or AI Graphics → **Repair** |
| No tray icon on GNOME | Install and enable an AppIndicator extension |
| "falcond is not compatible with this processor" | The installed falcond was built for a newer x86-64 level than this processor's (falcond 2.0.14 built for x86-64-v3 stops with SIGILL without AVX2/BMI2). Turning Turbo off and on again does not help: update falcond once a build for the x86-64 baseline is available. [CPU compatibility](docs/CPU-COMPATIBILITY.md) |
| "falcond is not compatible with this processor" | The installed falcond was built for a newer x86-64 level than this processor's (falcond 2.0.14 built for x86-64-v3 stops with SIGILL without AVX2/BMI2). Turbo still comes on with the general settings; per-game profiles need a falcond built for the x86-64 baseline. Turning Turbo off and on again does not help. [CPU compatibility](docs/CPU-COMPATIBILITY.md) |
| Something else | Details → **Support report**, or `bigame-ui --diagnostics`, and the **Logs** page |

## How it works
Expand Down Expand Up @@ -350,8 +372,9 @@ More in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
```

- **The interface never runs as root.** Only a small helper on the system bus
is privileged, confined by systemd (`ProtectSystem=strict`, `/sys` read-only
except `/sys/devices`, one capability).
is privileged, confined by systemd (`ProtectSystem=strict`, `/run` and `/sys`
read-only except the CPU frequency and device attributes it sets, one
capability, memory and task limits).
- **Every privileged method is authorised by Polkit first** (without Polkit,
access is denied) and every argument is validated on the root side.
- **Narrow, atomic writes** to one known place each, never through a path the
Expand Down Expand Up @@ -402,7 +425,7 @@ languages are welcome.

## Development

Requires Rust 1.85 or newer, GTK 4.14+, libadwaita 1.7+,
Requires Rust 1.88 or newer, GTK 4.14+, libadwaita 1.7+,
`glib-compile-resources` (glib2) and, for the catalogues, gettext and Python 3.

```bash
Expand Down Expand Up @@ -471,7 +494,7 @@ template, compiles the catalogues and runs `cargo test --release --frozen
--workspace` in `check()`.

One run checks every pull request and every push (details in
[`docs/ci-workflows-audit.md`](docs/ci-workflows-audit.md)), with two jobs in
[`docs/CI.md`](docs/CI.md)), with two jobs in
parallel:

- the code (`.github/workflows/backend-tests.yml`): formatting, Clippy with
Expand All @@ -489,7 +512,7 @@ as *Package check*, which is not handed to them.

## Author

**Rafael Ruscher** · <rruscher@gmail.com>
**Rafael Ruscher**, author and lead developer · <rruscher@gmail.com>

I have always loved games, and I am a firm believer in gaming on Linux. In
recent years, with Valve's constant work, compatibility has become almost
Expand Down
6 changes: 3 additions & 3 deletions bigame-engine/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions bigame-engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ resolver = "2"
members = ["bigame-core", "bigame-daemon", "bigame-ui"]

[workspace.package]
version = "2.3.1"
version = "2.3.2"
authors = ["Rafael Ruscher <rruscher@gmail.com>"]
edition = "2024"
license = "GPL-3.0-or-later"
rust-version = "1.85"
rust-version = "1.88"

[workspace.lints.clippy]
pedantic = { level = "warn", priority = -1 }
Expand Down
9 changes: 5 additions & 4 deletions bigame-engine/bigame-core/examples/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ fn main() {
" outputs={:?} hwmon={:?}",
g.connected_outputs, g.hwmon
);
let sample = bigame_core::gpu_telemetry::sample(g);
println!(
" dpm={:?} busy={:?} temp={:?} power_uw={:?}",
" dpm={:?} busy={:?} temp_c={:?} power_w={:?}",
g.dpm_level(),
g.busy_percent(),
g.hwmon_u64("temp1_input"),
g.hwmon_u64("power1_average")
sample.busy_pct,
sample.temp_c,
sample.power_w
);
}
println!("render {:?}", hw.render_gpu().map(|g| &g.card));
Expand Down
11 changes: 5 additions & 6 deletions bigame-engine/bigame-core/examples/falcond_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
fn main() -> anyhow::Result<()> {
use bigame_core::turbo;
let what = std::env::args().nth(1).unwrap_or_else(|| "status".into());
if what != "status" {
if let Some(secs) = std::env::var("BIGAME_WAIT")
if what != "status"
&& let Some(secs) = std::env::var("BIGAME_WAIT")
.ok()
.and_then(|s| s.parse().ok())
{
println!("pid {}", std::process::id());
std::thread::sleep(std::time::Duration::from_secs(secs));
}
{
println!("pid {}", std::process::id());
std::thread::sleep(std::time::Duration::from_secs(secs));
}
match what.as_str() {
"release" => {
Expand Down
1 change: 0 additions & 1 deletion bigame-engine/bigame-core/src/benchmark/lab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ impl Session {

/// The report a person reads.
#[must_use]
#[allow(clippy::too_many_lines)]
pub fn to_markdown(&self, comparisons: &[Comparison]) -> String {
let mut out = String::new();
let _ = writeln!(out, "# {} — {}\n", self.workload, self.date);
Expand Down
10 changes: 5 additions & 5 deletions bigame-engine/bigame-core/src/benchmark/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ pub fn parse_mangohud_csv(content: &str) -> Result<Capture> {
push_col(&mut capture.cpu_temp, &cols, index("cpu_temp"));
push_col(&mut capture.gpu_power, &cols, index("gpu_power"));

if let Some(i) = i_elapsed {
if let Some(v) = cols.get(i).and_then(|c| c.parse::<f64>().ok()) {
first_elapsed.get_or_insert(v);
last_elapsed = Some(v);
}
if let Some(i) = i_elapsed
&& let Some(v) = cols.get(i).and_then(|c| c.parse::<f64>().ok())
{
first_elapsed.get_or_insert(v);
last_elapsed = Some(v);
}
}

Expand Down
2 changes: 1 addition & 1 deletion bigame-engine/bigame-core/src/benchmark/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl ArmSummary {

let mut sorted = runs.clone();
sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let median = if n % 2 == 0 {
let median = if n.is_multiple_of(2) {
f64::midpoint(sorted[n / 2 - 1], sorted[n / 2])
} else {
sorted[n / 2]
Expand Down
Loading