Skip to content

Fix: System UI brightness slider has no effect while KompaktX is running - #4

Open
chadchad4423 wants to merge 2 commits into
ScreenSensitive:mainfrom
chadchad4423:fix/sync-system-brightness-slider
Open

Fix: System UI brightness slider has no effect while KompaktX is running#4
chadchad4423 wants to merge 2 commits into
ScreenSensitive:mainfrom
chadchad4423:fix/sync-system-brightness-slider

Conversation

@chadchad4423

@chadchad4423 chadchad4423 commented Aug 24, 2026

Copy link
Copy Markdown

Fix: Adaptive Brightness has no effect on physical brightness while KompaktX is running

KompaktX drives the physical backlight through a persistent 1x1 overlay window (WindowManager.LayoutParams.screenBrightness), separate from Android's own brightness system. That overlay's brightness value was set once and never released, so even after a user turned Adaptive Brightness back on, the overlay kept pinning the screen to its last static value — physical brightness stopped responding to ambient light entirely, even though the Adaptive Brightness toggle itself correctly showed "on."

A second, related path made this worse: brightnessObserver (the ContentObserver watching Settings.System.SCREEN_BRIGHTNESS) would react to any external brightness write — including the ones Android's own adaptive-brightness algorithm makes continuously — by re-pinning the overlay back to a stale target, fighting the system's live adjustments in real time.

This PR:

  • Adds a ContentObserver on Settings.System.SCREEN_BRIGHTNESS_MODE that releases the overlay/panel/lockscreen brightness overrides the moment Adaptive Brightness is turned on, so the physical backlight goes back to being fully system-controlled.
  • Adds an isAdaptiveBrightnessOn() guard at the top of brightnessObserver's onChange(), so it stops reacting to SCREEN_BRIGHTNESS writes at all while adaptive mode is active — it no longer fights the system's own live adjustments.
  • Changes the passive reapply path (applyBrightness(forceManualMode = false), used by reapplyBrightness() / loadSavedBrightness()) to skip overlay pinning entirely while Adaptive Brightness is already on.

Testing

Built on top of #5 (Fix 2) since this change depends on the forceManualMode parameter it introduces. Verified on a physical Mudita Kompakt (MuditaOS K 1.5), standalone and combined with the other three fixes (Fix 1 + Fix 2 + Fix 3 + Fix 4 together, cherry-picked onto one branch):

  • Full 6-step protocol — panel-open, cross-screen consistency, repeated Settings → Display checks, sleep/wake, KompaktX slider drag, System UI slider sync — 100% pass.
  • Additional stress test using a flashlight to force real ambient-light swings: confirmed brightness tracked it live, not just holding a static value that happened to pass the screen-based checks.

Note: This PR is stacked on PR #5 and includes its forceManualMode change, so it can be merged directly into main either before or after PR #5 is handled. It should also be reviewed alongside PR #4: both modify brightnessObserver. Their combined result has been tested successfully, although the second PR merged may require minor conflict resolution depending on merge strategy.

Chad added 2 commits August 24, 2026 18:57
KompaktX's overlay-based brightness control (OverlayPanelManager) is the
sole path that actually drives the physical backlight, via the
screenBrightness field on a persistent overlay window. A ContentObserver
on Settings.System.SCREEN_BRIGHTNESS was meant to reapply that value if
something cleared it, but it fired on ANY external write to that setting
-- including the one the stock System UI brightness slider makes -- and
immediately stomped it back to KompaktX's last value. That's why the
System UI slider appeared to do nothing while KompaktX was installed.

Since applyBrightness() already sets currentBrightnessTarget before
writing Settings.System.SCREEN_BRIGHTNESS, a self-triggered observer
callback always finds sys == target and is a no-op. A callback where
sys != target is therefore reliably an external change. Flip the
observer to adopt that external value as the new target instead of
reverting it, mirroring applyBrightness()'s side effects (overlay
screenBrightness, lockscreen accessibility overlay, and persistence)
so the change reaches the physical screen, survives a KompaktX process
restart, and applies above the lockscreen too.

No UI/range changes: brightness remains a plain linear 0-255 value in
both directions, matching the existing stock-slider behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant