refactor(input): compile the disabled diagnostics and screenshot-blur subsystems out of normal builds

TextInputDiagnostics.enabled and kBlurArtwork were mutable/const-false flags nothing ever set, yet the diagnostics side eagerly built log strings on the gamepad and key-simulator hot paths on every event. Both flags are now const bool.fromEnvironment (PLEZY_TEXT_INPUT_DIAGNOSTICS / PLEZY_BLUR_ARTWORK) so the branches const-fold away, every eager interpolation sits behind a guard, and screenshot blurring stays one dart-define away. The vowel-rotation title obfuscation had no consumer need beyond artwork blur and is gone.
This commit is contained in:
edde746
2026-08-17 19:02:22 +02:00
parent 0e1af9faaf
commit 78fa2c29e3
4 changed files with 115 additions and 61 deletions
+85 -37
View File
@@ -329,15 +329,19 @@ class GamepadService with WindowListener {
}
Future<void> _setNativeTextInputFocused(bool focused) async {
_logGamepadDiag('setNativeTextInputFocused requested focused=$focused current=$_nativeTextInputFocused');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('setNativeTextInputFocused requested focused=$focused current=$_nativeTextInputFocused');
}
if (_nativeTextInputFocused == focused) {
_logGamepadDiag('setNativeTextInputFocused no-op focused=$focused');
if (TextInputDiagnostics.enabled) _logGamepadDiag('setNativeTextInputFocused no-op focused=$focused');
return;
}
_nativeTextInputFocused = focused;
if (focused) {
_logGamepadDiag('native text input focused; clearing repeat/buttons/duplicate guard before pause');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('native text input focused; clearing repeat/buttons/duplicate guard before pause');
}
_stopDirectionRepeat();
_pressedButtons.clear();
_suppressedButtons.clear();
@@ -347,20 +351,22 @@ class GamepadService with WindowListener {
final debugHandler = debugNativeTextInputFocusHandler;
if (debugHandler != null) {
_logGamepadDiag('setNativeTextInputFocused using debug handler focused=$focused');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('setNativeTextInputFocused using debug handler focused=$focused');
}
await debugHandler(focused);
return;
}
try {
if (focused) {
_logGamepadDiag('calling Gamepad.pause for native text input');
if (TextInputDiagnostics.enabled) _logGamepadDiag('calling Gamepad.pause for native text input');
await Gamepad.instance.pause();
_logGamepadDiag('Gamepad.pause completed for native text input');
if (TextInputDiagnostics.enabled) _logGamepadDiag('Gamepad.pause completed for native text input');
} else {
_logGamepadDiag('calling Gamepad.resume after native text input');
if (TextInputDiagnostics.enabled) _logGamepadDiag('calling Gamepad.resume after native text input');
await Gamepad.instance.resume();
_logGamepadDiag('Gamepad.resume completed after native text input');
if (TextInputDiagnostics.enabled) _logGamepadDiag('Gamepad.resume completed after native text input');
}
} catch (e) {
appLogger.e('GamepadService: Failed to ${focused ? "pause" : "resume"} for native text input', error: e);
@@ -368,11 +374,15 @@ class GamepadService with WindowListener {
}
void _handleGamepadEvent(GamepadEvent event) {
_logGamepadDiag('event received type=${event.runtimeType} nativeTextInputFocused=$_nativeTextInputFocused');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('event received type=${event.runtimeType} nativeTextInputFocused=$_nativeTextInputFocused');
}
switch (event) {
case final GamepadConnectionEvent e:
appLogger.i('GamepadService: Gamepad ${e.connected ? "connected" : "disconnected"}: ${e.info.name}');
_logGamepadDiag('connection connected=${e.connected} info=${e.info.name}/${e.info.id}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('connection connected=${e.connected} info=${e.info.name}/${e.info.id}');
}
case final GamepadButtonEvent e:
_handleButton(e);
case final GamepadAxisEvent e:
@@ -381,15 +391,21 @@ class GamepadService with WindowListener {
}
void _handleButton(GamepadButtonEvent event) {
_logGamepadDiag(
'button received ${_describeGamepadButton(event)} windowFocused=$_windowFocused nativeTextInputFocused=$_nativeTextInputFocused',
);
if (TextInputDiagnostics.enabled) {
_logGamepadDiag(
'button received ${_describeGamepadButton(event)} windowFocused=$_windowFocused nativeTextInputFocused=$_nativeTextInputFocused',
);
}
if (!_windowFocused) {
_logGamepadDiag('button ignored because window is not focused ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button ignored because window is not focused ${_describeGamepadButton(event)}');
}
return;
}
if (isTvosEngineOwnedGamepadButton(isAppleTV: PlatformDetector.isAppleTV(), button: event.button)) {
_logGamepadDiag('button ignored because tvOS engine owns its key lifecycle ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button ignored because tvOS engine owns its key lifecycle ${_describeGamepadButton(event)}');
}
return;
}
@@ -408,7 +424,9 @@ class GamepadService with WindowListener {
if (event.pressed && !wasPressed) {
_pressedButtons.add(event.button);
if (_shouldSuppressButton(event.button)) {
_logGamepadDiag('button suppressed by duplicate guard ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button suppressed by duplicate guard ${_describeGamepadButton(event)}');
}
_suppressedButtons.add(event.button);
return;
}
@@ -416,32 +434,46 @@ class GamepadService with WindowListener {
// D-pad — navigate with auto-repeat while held
switch (event.button) {
case GamepadButton.dpadUp:
_logGamepadDiag('button starts direction repeat up ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button starts direction repeat up ${_describeGamepadButton(event)}');
}
_startDirectionRepeat(TraversalDirection.up);
return;
case GamepadButton.dpadDown:
_logGamepadDiag('button starts direction repeat down ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button starts direction repeat down ${_describeGamepadButton(event)}');
}
_startDirectionRepeat(TraversalDirection.down);
return;
case GamepadButton.dpadLeft:
_logGamepadDiag('button starts direction repeat left ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button starts direction repeat left ${_describeGamepadButton(event)}');
}
_startDirectionRepeat(TraversalDirection.left);
return;
case GamepadButton.dpadRight:
_logGamepadDiag('button starts direction repeat right ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button starts direction repeat right ${_describeGamepadButton(event)}');
}
_startDirectionRepeat(TraversalDirection.right);
return;
// Face buttons — send KeyDown on press, KeyUp on release
// so widget-level long-press timers work naturally
case GamepadButton.a:
_logGamepadDiag('button simulates key down enter ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button simulates key down enter ${_describeGamepadButton(event)}');
}
_simulateKeyDown(LogicalKeyboardKey.enter);
case GamepadButton.x:
_logGamepadDiag('button simulates key down context/menu ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button simulates key down context/menu ${_describeGamepadButton(event)}');
}
_simulateKeyDown(LogicalKeyboardKey.gameButtonX);
// Immediate actions on press
case GamepadButton.b:
_logGamepadDiag('button simulates key press back ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button simulates key press back ${_describeGamepadButton(event)}');
}
_simulateKeyPress(LogicalKeyboardKey.gameButtonB);
case GamepadButton.leftShoulder:
_dispatchTabNavigation(previous: true);
@@ -453,7 +485,9 @@ class GamepadService with WindowListener {
} else if (!event.pressed && wasPressed) {
_pressedButtons.remove(event.button);
if (_suppressedButtons.remove(event.button)) {
_logGamepadDiag('button release consumed by suppressed set ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button release consumed by suppressed set ${_describeGamepadButton(event)}');
}
return;
}
@@ -463,14 +497,20 @@ class GamepadService with WindowListener {
case GamepadButton.dpadDown:
case GamepadButton.dpadLeft:
case GamepadButton.dpadRight:
_logGamepadDiag('button stops direction repeat ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button stops direction repeat ${_describeGamepadButton(event)}');
}
_stopDirectionRepeat();
// Face button release — send KeyUp
case GamepadButton.a:
_logGamepadDiag('button simulates key up enter ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button simulates key up enter ${_describeGamepadButton(event)}');
}
_simulateKeyUp(LogicalKeyboardKey.enter);
case GamepadButton.x:
_logGamepadDiag('button simulates key up context/menu ${_describeGamepadButton(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('button simulates key up context/menu ${_describeGamepadButton(event)}');
}
_simulateKeyUp(LogicalKeyboardKey.gameButtonX);
default:
break;
@@ -481,16 +521,22 @@ class GamepadService with WindowListener {
bool _shouldSuppressButton(GamepadButton button) {
final syntheticKey = _syntheticKeyByButton[button];
final suppressed = syntheticKey != null && _duplicateInputGuard.shouldSuppressSyntheticKey(syntheticKey);
_logGamepadDiag('duplicate guard button=$button syntheticKey=$syntheticKey suppressed=$suppressed');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('duplicate guard button=$button syntheticKey=$syntheticKey suppressed=$suppressed');
}
return suppressed;
}
void _handleAxis(GamepadAxisEvent event) {
_logGamepadDiag(
'axis received ${_describeGamepadAxis(event)} windowFocused=$_windowFocused nativeTextInputFocused=$_nativeTextInputFocused',
);
if (TextInputDiagnostics.enabled) {
_logGamepadDiag(
'axis received ${_describeGamepadAxis(event)} windowFocused=$_windowFocused nativeTextInputFocused=$_nativeTextInputFocused',
);
}
if (!_windowFocused) {
_logGamepadDiag('axis ignored because window is not focused ${_describeGamepadAxis(event)}');
if (TextInputDiagnostics.enabled) {
_logGamepadDiag('axis ignored because window is not focused ${_describeGamepadAxis(event)}');
}
return;
}
@@ -512,18 +558,20 @@ class GamepadService with WindowListener {
/// Fire [direction] immediately, then auto-repeat after an initial delay.
void _startDirectionRepeat(TraversalDirection direction) {
_logGamepadDiag('startDirectionRepeat direction=$direction');
if (TextInputDiagnostics.enabled) _logGamepadDiag('startDirectionRepeat direction=$direction');
_stopDirectionRepeat();
final logicalKey = _directionToKey(direction);
_logGamepadDiag(
'moveFocus direction=$direction logicalKey=${logicalKey.keyLabel}/${logicalKey.keyId} nativeTextInputFocused=$_nativeTextInputFocused',
);
if (TextInputDiagnostics.enabled) {
_logGamepadDiag(
'moveFocus direction=$direction logicalKey=${logicalKey.keyLabel}/${logicalKey.keyId} nativeTextInputFocused=$_nativeTextInputFocused',
);
}
_simulator.startKeyRepeat(logicalKey, initialDelay: _repeatInitialDelay, interval: _repeatInterval);
}
void _stopDirectionRepeat() {
if (_keyEventSimulator?.isRepeating ?? false) {
_logGamepadDiag('stopDirectionRepeat');
if (TextInputDiagnostics.enabled) _logGamepadDiag('stopDirectionRepeat');
}
_keyEventSimulator?.stopKeyRepeat();
}
+22 -8
View File
@@ -60,7 +60,9 @@ class KeyEventSimulatorController {
/// Simulates a full key press (down and up) in one frame.
void simulateKeyPress(LogicalKeyboardKey logicalKey) {
if (_disposed) return;
_log('simulateKeyPress scheduled logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
if (TextInputDiagnostics.enabled) {
_log('simulateKeyPress scheduled logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
}
_schedule((focusNode) {
final physicalKey = _physicalKeyFor(logicalKey);
_dispatchKeyEvent(focusNode, _keyDownEvent(logicalKey, physicalKey));
@@ -71,7 +73,9 @@ class KeyEventSimulatorController {
/// Simulates key down and remembers its focus until key up.
void simulateKeyDown(LogicalKeyboardKey logicalKey) {
if (_disposed) return;
_log('simulateKeyDown scheduled logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
if (TextInputDiagnostics.enabled) {
_log('simulateKeyDown scheduled logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
}
_schedule((focusNode) {
_heldFocusNodes[logicalKey] = focusNode;
_dispatchKeyEvent(focusNode, _keyDownEvent(logicalKey, _physicalKeyFor(logicalKey)));
@@ -81,7 +85,9 @@ class KeyEventSimulatorController {
/// Simulates key up on the focus that received the matching key down.
void simulateKeyUp(LogicalKeyboardKey logicalKey) {
if (_disposed) return;
_log('simulateKeyUp scheduled logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
if (TextInputDiagnostics.enabled) {
_log('simulateKeyUp scheduled logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
}
scheduleFrameIfIdle();
SchedulerBinding.instance.addPostFrameCallback((_) {
if (!_disposed) _dispatchKeyUp(logicalKey);
@@ -147,7 +153,9 @@ class KeyEventSimulatorController {
final focusNode = heldFocusNode ?? FocusManager.instance.primaryFocus;
if (focusNode == null) return;
if (heldFocusNode != null && heldFocusNode.context == null) {
_log('simulateKeyUp dropped detached held focus logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
if (TextInputDiagnostics.enabled) {
_log('simulateKeyUp dropped detached held focus logical=${logicalKey.keyLabel}/${logicalKey.keyId}');
}
return;
}
@@ -173,21 +181,27 @@ class KeyEventSimulatorController {
}
void _dispatchKeyEvent(FocusNode focusNode, KeyEvent event) {
_log('dispatch start focus=${focusNode.debugLabel} key=(${_describeSimulatedKey(event)})');
if (TextInputDiagnostics.enabled) {
_log('dispatch start focus=${focusNode.debugLabel} key=(${_describeSimulatedKey(event)})');
}
FocusNode? node = focusNode;
while (node != null) {
if (node.onKeyEvent != null) {
final result = node.onKeyEvent!(node, event);
_log('dispatch node=${node.debugLabel} result=$result key=(${_describeSimulatedKey(event)})');
if (TextInputDiagnostics.enabled) {
_log('dispatch node=${node.debugLabel} result=$result key=(${_describeSimulatedKey(event)})');
}
if (result != KeyEventResult.ignored) {
_log('dispatch stopped node=${node.debugLabel} result=$result');
if (TextInputDiagnostics.enabled) _log('dispatch stopped node=${node.debugLabel} result=$result');
break;
}
}
node = node.parent;
}
if (node == null) {
_log('dispatch reached root ignored key=(${_describeSimulatedKey(event)})');
if (TextInputDiagnostics.enabled) {
_log('dispatch reached root ignored key=(${_describeSimulatedKey(event)})');
}
}
}
+3 -15
View File
@@ -1,15 +1,3 @@
/// Set to `true` to blur all artwork (for store screenshots).
const kBlurArtwork = false;
/// Rotates vowels (a→e, e→i, i→o, o→u, u→a) when [kBlurArtwork] is `true`.
String obfuscateText(String text) {
if (!kBlurArtwork) return text;
const from = 'aeiouAEIOU';
const to = 'eiouaEIOUA';
final buf = StringBuffer();
for (var i = 0; i < text.length; i++) {
final idx = from.indexOf(text[i]);
buf.write(idx >= 0 ? to[idx] : text[i]);
}
return buf.toString();
}
/// Blur all artwork (for store screenshots). Compile-time switch: run with
/// `--dart-define=PLEZY_BLUR_ARTWORK=true`; const-folded out of normal builds.
const kBlurArtwork = bool.fromEnvironment('PLEZY_BLUR_ARTWORK');
+5 -1
View File
@@ -2,7 +2,11 @@ import 'app_logger.dart';
import 'platform_detector.dart';
class TextInputDiagnostics {
static bool enabled = false;
/// Compile-time switch: run with
/// `--dart-define=PLEZY_TEXT_INPUT_DIAGNOSTICS=true` to enable. Const so the
/// guarded branches (and their log-string interpolation) compile out of
/// every normal build.
static const bool enabled = bool.fromEnvironment('PLEZY_TEXT_INPUT_DIAGNOSTICS');
static void log(String source, String message) {
if (!enabled || !PlatformDetector.isTV()) return;