Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@
## [Unreleased]

### Добавлено
- **Лимит яркости экрана** (Настройки → Экран) — два независимых лимита, для сети и для батареи:
яркость выше лимита плавно (за ~10 с, без скачка) сводится обратно. Бережёт OLED-панель от
выгорания. Заблокировать сам ползунок Windows невозможно — только вернуть после факта, о чём
честно написано в настройке. Вместо ультиматума — вежливый торг: раз в минуту разрыв сокращается
вдвое, а если пользователь после нашего шага снова поднял яркость — приложение уступает и не
трогает её 2 часа (пауза сбрасывается блокировкой, сном, сменой питания и перезапуском).
Понижение ниже лимита не трогается вовсе — приложение никогда не поднимает яркость. При
включённой адаптивной яркости Windows фича не работает и объясняет причину прямо в настройках.
Опция «Запоминать яркость» при этом хранит намерение пользователя: превышение лимита не
запоминается вообще (а не обрезается), восстановление клампится к текущему лимиту. Тайминги
правятся в config.json (`BrightnessRampMs`, `BrightnessConvergeMs`, `BrightnessBackoffMin` и др.)
(XIC-29).

### Изменено
- **Вкладка «Экран» видна всегда** — на ней поселилась яркость (лимиты + переехавший из «Общих»
тумблер «Запоминать яркость экрана»), поэтому фича «Управление частотой» теперь скрывает только
раздел частоты внутри вкладки, а не вкладку целиком (XIC-29).
- **Сведения о железе на вкладке «О программе»** — рядом с моделью появились версия BIOS с датой
выпуска и серийный номер. Модель теперь показывается вместе с кодом платы («Xiaomi Book Pro 14
(TM2424)») — в отчётах о совместимости важен именно код. **Серийный номер закрыт по умолчанию**,
Expand Down
36 changes: 35 additions & 1 deletion src/Config/AppConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,45 @@ public sealed class AppConfig
public PerfMode? BatteryPerfMode { get; set; }

/// <summary>Запоминать и восстанавливать яркость экрана отдельно для сети и батареи.
/// Самостоятельная опция (в «Общих»): работает и без «Профилей питания» — держит её
/// Самостоятельная опция (вкладка «Экран»): работает и без «Профилей питания» — держит её
/// PowerProfileGuard независимо. По умолчанию выкл: утилита перебивает яркость Windows
/// только по явному выбору пользователя.</summary>
public bool RememberBrightness { get; set; } = false;

/// <summary>
/// Ограничивать яркость экрана (XIC-29, бережёт OLED от выгорания): выше лимита яркость
/// плавно сводится обратно. Заблокировать сам ползунок Windows невозможно — только вернуть
/// после факта, о чём честно сказано в описании настройки. Держит BrightnessCapGuard.
/// </summary>
public bool BrightnessCapEnabled { get; set; } = false;

/// <summary>Лимит яркости (%) при питании от сети.</summary>
public int BrightnessCapAc { get; set; } = 80;

/// <summary>Лимит яркости (%) при питании от батареи.</summary>
public int BrightnessCapBattery { get; set; } = 60;

// Тайминги лимита яркости — только правкой config.json (в UI не выносим, дефолты согласованы
// в XIC-29). Кривые значения клэмпит BrightnessCapGuard при чтении.

/// <summary>Длительность плавного хода яркости на весь путь, мс: интервал шага = длительность /
/// дельта, поэтому спуск 100→70 и 75→70 занимает одинаковое время. Дефолт 10 с.</summary>
public int BrightnessRampMs { get; set; } = 10_000;

/// <summary>Интервал между шагами схождения к лимиту. Дефолт 1 мин.</summary>
public int BrightnessConvergeMs { get; set; } = 60_000;

/// <summary>Пауза после повторного подъёма яркости пользователем («мне правда нужно ярче»), минут.
/// Сбрасывается блокировкой, сном, сменой питания и перезапуском. Дефолт 2 часа.</summary>
public int BrightnessBackoffMin { get; set; } = 120;

/// <summary>Делитель разрыва при схождении: за шаг сокращаем (яркость − лимит) во столько раз.</summary>
public int BrightnessGapDivisor { get; set; } = 2;

/// <summary>Порог схождения, %: если до лимита осталось не больше — доводим сразу
/// (иначе гонялись бы за половинками бесконечно).</summary>
public int BrightnessSnapPercent { get; set; } = 2;

/// <summary>Запомненная яркость экрана (0–100) от сети; null — ещё не запомнена.</summary>
public int? AcBrightness { get; set; }

Expand Down
13 changes: 11 additions & 2 deletions src/Localization/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,16 @@
"settings.battery.capacity": "Capacity",
"settings.battery.capacity.desc": "Current maximum and design capacity.",
"settings.battery.capacity.val": "{0:0.0} / {1:0.0} Wh",
"settings.display.sub": "Refresh rate depending on the power source.",
"settings.display.sub": "Screen brightness and refresh rate.",
"settings.bright.group": "Brightness",
"settings.bright.cap": "Limit brightness",
"settings.bright.cap.desc": "Protects an OLED panel from burn-in: brightness above the limit smoothly slides back to it. Windows offers no way to lock the slider itself — it can only be brought back after the fact. Raise it again and the app yields, leaving brightness alone for 2 hours.",
"settings.bright.cap.ac": "Limit on AC",
"settings.bright.cap.ac.desc": "Maximum brightness while plugged in.",
"settings.bright.cap.battery": "Limit on battery",
"settings.bright.cap.battery.desc": "Maximum brightness on battery power.",
"settings.bright.adaptive": "The limit is inactive right now: adaptive brightness is enabled in the power plan, so Windows itself adjusts brightness from the light sensor — the two would fight each other. Turn it off in Settings → System → Display → \"Change brightness automatically when lighting changes\".",
"settings.hz.group": "Refresh rate",
"settings.hz.auto": "Auto refresh rate by power",
"settings.hz.auto.desc": "Higher on AC, lower on battery — saves power.",
"settings.hz.hold": "Keep refresh rate",
Expand Down Expand Up @@ -138,7 +147,7 @@
"settings.touchscreen.feature": "Touchscreen control",
"settings.touchscreen.feature.desc": "Panel cell and key action. A disabled touchscreen always re-enables itself after a reboot.",
"settings.refresh.feature": "Refresh rate control",
"settings.refresh.feature.desc": "Menu item, panel cell and the Display tab. Turn off if you don't need auto Hz switching.",
"settings.refresh.feature.desc": "Menu item, panel cell and the refresh-rate section of the Display tab. Turn off if you don't need auto Hz switching.",
"settings.touchpad.sub": "How the touchpad behaves.",
"settings.touchpad.deadzone": "Bottom dead zone",
"settings.touchpad.deadzone.desc": "Don't start a touch in the bottom strip — protection from a resting palm.",
Expand Down
13 changes: 11 additions & 2 deletions src/Localization/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,16 @@
"settings.battery.capacity": "Ёмкость",
"settings.battery.capacity.desc": "Текущая максимальная и проектная ёмкость.",
"settings.battery.capacity.val": "{0:0.0} / {1:0.0} Вт·ч",
"settings.display.sub": "Частота обновления в зависимости от питания.",
"settings.display.sub": "Яркость и частота обновления экрана.",
"settings.bright.group": "Яркость",
"settings.bright.cap": "Ограничивать яркость",
"settings.bright.cap.desc": "Бережёт OLED-панель от выгорания: яркость выше лимита плавно возвращается к нему. Заблокировать сам ползунок Windows нельзя — только вернуть после факта. Поднимете снова — приложение уступит и не будет трогать яркость 2 часа.",
"settings.bright.cap.ac": "Лимит от сети",
"settings.bright.cap.ac.desc": "Максимальная яркость при питании от сети.",
"settings.bright.cap.battery": "Лимит от батареи",
"settings.bright.cap.battery.desc": "Максимальная яркость при питании от батареи.",
"settings.bright.adaptive": "Сейчас лимит не работает: в схеме электропитания включена адаптивная яркость, и Windows сама меняла бы яркость по датчику освещённости — две системы мешали бы друг другу. Отключить её можно в Параметры → Система → Дисплей → «Автоматически менять яркость при изменении освещения».",
"settings.hz.group": "Частота обновления",
"settings.hz.auto": "Авто-частота по питанию",
"settings.hz.auto.desc": "Повышенная от сети, пониженная от батареи — экономит заряд.",
"settings.hz.hold": "Удерживать частоту",
Expand Down Expand Up @@ -138,7 +147,7 @@
"settings.touchscreen.feature": "Управление сенсорным экраном",
"settings.touchscreen.feature.desc": "Ячейка в панели и действие для клавиш. Отключённый сенсорный экран всегда включается сам после перезагрузки.",
"settings.refresh.feature": "Управление частотой экрана",
"settings.refresh.feature.desc": "Пункт меню, ячейка панели и вкладка «Экран». Выключите, если авто-герцовка вам не нужна.",
"settings.refresh.feature.desc": "Пункт меню, ячейка панели и раздел частоты во вкладке «Экран». Выключите, если авто-герцовка вам не нужна.",
"settings.touchpad.sub": "Поведение сенсорной панели.",
"settings.touchpad.deadzone": "Мёртвая зона снизу",
"settings.touchpad.deadzone.desc": "Не начинать касание в нижней полосе — защита от лежащей ладони.",
Expand Down
13 changes: 11 additions & 2 deletions src/Localization/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,16 @@
"settings.battery.capacity": "容量",
"settings.battery.capacity.desc": "当前最大容量与设计容量。",
"settings.battery.capacity.val": "{0:0.0} / {1:0.0} 瓦时",
"settings.display.sub": "根据电源自动切换刷新率。",
"settings.display.sub": "屏幕亮度与刷新率。",
"settings.bright.group": "亮度",
"settings.bright.cap": "限制亮度",
"settings.bright.cap.desc": "保护 OLED 屏幕免于烧屏:亮度超过上限时会平滑地降回上限。Windows 不允许锁定亮度滑块本身,只能事后调回。若您再次调高,应用会让步,2 小时内不再干预亮度。",
"settings.bright.cap.ac": "接通电源时的上限",
"settings.bright.cap.ac.desc": "接通电源时的最大亮度。",
"settings.bright.cap.battery": "使用电池时的上限",
"settings.bright.cap.battery.desc": "使用电池时的最大亮度。",
"settings.bright.adaptive": "上限当前不生效:电源计划中已启用自适应亮度,Windows 会根据光线传感器自动调节亮度,两者会互相干扰。可在 设置 → 系统 → 屏幕 → “光线变化时自动更改亮度” 中关闭。",
"settings.hz.group": "刷新率",
"settings.hz.auto": "按电源自动刷新率",
"settings.hz.auto.desc": "接通电源时更高,使用电池时更低,省电。",
"settings.hz.hold": "保持刷新率",
Expand Down Expand Up @@ -138,7 +147,7 @@
"settings.touchscreen.feature": "触摸屏控制",
"settings.touchscreen.feature.desc": "面板单元格与按键动作。禁用的触摸屏重启后总会自动恢复。",
"settings.refresh.feature": "屏幕刷新率控制",
"settings.refresh.feature.desc": "菜单项、面板单元格和“屏幕”选项卡。若不需要自动切换刷新率,可关闭。",
"settings.refresh.feature.desc": "菜单项、面板单元格和“屏幕”选项卡中的刷新率部分。若不需要自动切换刷新率,可关闭。",
"settings.touchpad.sub": "触摸板的行为。",
"settings.touchpad.deadzone": "底部死区",
"settings.touchpad.deadzone.desc": "不在底部区域开始触摸——防止手掌误触。",
Expand Down
1 change: 1 addition & 0 deletions src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ private static void Main()
() => c.ChargeCare && !c.TravelMode ? c.CarePercent() : 100);
});
services.AddSingleton<RefreshRateGuard>();
services.AddSingleton<BrightnessCapGuard>(); // лимит яркости (XIC-29); события ему раздаёт PowerProfileGuard
services.AddSingleton<PowerProfileGuard>();
services.AddSingleton<TravelChargeMonitor>();
services.AddSingleton<TrayIconController>();
Expand Down
Loading
Loading