more oled features and system freeze fixes

This commit is contained in:
2026-08-06 19:58:50 +02:00
parent 40af1dad26
commit faa3a7257f
9 changed files with 382 additions and 58 deletions
+31
View File
@@ -1,6 +1,7 @@
import GLib from 'gi://GLib';
import Meta from 'gi://Meta';
import Clutter from 'gi://Clutter';
import Graphene from 'gi://Graphene';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import {SettingsKey} from './settingsKeys.js';
@@ -13,6 +14,11 @@ const SHIFT_PATTERN = [
const FORCE_ROTATION_CHECK_SECONDS = 60;
// Extra margin, in pixels, added on top of the configured shift amount when
// overscanning background actors — rounding/timing slack so a step never
// exposes a sliver of empty stage at the trailing edge.
const OVERSCAN_SAFETY_PX = 2;
/**
* Reduces OLED burn-in risk through three independent techniques:
* - pixel shifting: nudges the background actors a few px on a slow cycle
@@ -105,6 +111,7 @@ export class OledProtectionManager {
const [dx, dy] = SHIFT_PATTERN[this._shiftStep];
for (const actor of this._backgroundActors()) {
this._ensureOverscan(actor, amount);
actor.ease({
translation_x: dx * amount,
translation_y: dy * amount,
@@ -114,12 +121,36 @@ export class OledProtectionManager {
}
}
/**
* Background actors (the real desktop background, and our own live
* wallpaper actor in most display modes) are sized to exactly cover
* the stage with no slack, so nudging one by a few pixels for burn-in
* protection would drag its edge inward and expose bare stage on the
* side it moved away from. Scaling the actor up slightly around its
* center — by just enough margin to cover the configured shift amount
* — keeps every edge overscanned past the stage bounds no matter which
* step of the shift pattern is active.
*/
_ensureOverscan(actor, amount) {
const width = actor.width;
const height = actor.height;
if (width <= 0 || height <= 0)
return;
const margin = amount + OVERSCAN_SAFETY_PX;
actor.pivot_point = new Graphene.Point({x: 0.5, y: 0.5});
actor.scale_x = 1 + (2 * margin) / width;
actor.scale_y = 1 + (2 * margin) / height;
}
_resetShift() {
this._shiftStep = 0;
for (const actor of this._backgroundActors()) {
actor.ease({
translation_x: 0,
translation_y: 0,
scale_x: 1,
scale_y: 1,
duration: 500,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});