Serialize display recovery checks

This commit is contained in:
Gabriel Brown
2026-08-18 02:55:43 -04:00
parent 0a18290137
commit c2cd79b547
2 changed files with 34 additions and 9 deletions
+16 -7
View File
@@ -85,6 +85,7 @@ Singleton {
if (!root.awaitingConfirmation) if (!root.awaitingConfirmation)
return; return;
if (root.revertQueued) { if (root.revertQueued) {
if (!query.running)
root.performRevert(); root.performRevert();
return; return;
} }
@@ -93,6 +94,7 @@ Singleton {
return; return;
} }
verifyTimer.attempts = 0; verifyTimer.attempts = 0;
verifyTimer.ticks = 0;
verifyTimer.restart(); verifyTimer.restart();
} }
} }
@@ -104,17 +106,20 @@ Singleton {
// success without applying a value, so exact readback decides. // success without applying a value, so exact readback decides.
root.revertVerificationActive = true; root.revertVerificationActive = true;
revertVerifyTimer.attempts = 0; revertVerifyTimer.attempts = 0;
revertVerifyTimer.ticks = 0;
revertVerifyTimer.restart(); revertVerifyTimer.restart();
} }
} }
Component.onCompleted: root.refresh() Component.onCompleted: root.refresh()
function refresh(): void { function refresh(): bool {
if (!query.running) { if (!query.running) {
query.generation = root.operationGeneration; query.generation = root.operationGeneration;
query.running = true; query.running = true;
return true;
} }
return false;
} }
function parse(text: string, generation: int): void { function parse(text: string, generation: int): void {
@@ -411,26 +416,29 @@ Singleton {
Timer { Timer {
id: verifyTimer id: verifyTimer
property int attempts: 0 property int attempts: 0
property int ticks: 0
interval: 120 interval: 120
repeat: true repeat: true
onTriggered: { onTriggered: {
attempts++; ticks++;
if (attempts > 25) { if (ticks > 50) {
root.revertWithMessage("The display did not apply that setting, so Panama restored the previous one."); root.revertWithMessage("The display did not apply that setting, so Panama restored the previous one.");
return; return;
} }
root.refresh(); if (root.refresh())
attempts++;
} }
} }
Timer { Timer {
id: revertVerifyTimer id: revertVerifyTimer
property int attempts: 0 property int attempts: 0
property int ticks: 0
interval: 120 interval: 120
repeat: true repeat: true
onTriggered: { onTriggered: {
attempts++; ticks++;
if (attempts > 25) { if (ticks > 50) {
stop(); stop();
root.revertVerificationActive = false; root.revertVerificationActive = false;
root.revertGeneration = -1; root.revertGeneration = -1;
@@ -439,7 +447,8 @@ Singleton {
root.lastError = "The previous display setting could not be verified. Open Displays and restore it manually."; root.lastError = "The previous display setting could not be verified. Open Displays and restore it manually.";
return; return;
} }
root.refresh(); if (root.refresh())
attempts++;
} }
} }
+17 -1
View File
@@ -225,8 +225,24 @@ KINDS
now="$(status)" now="$(status)"
[[ "$(jq -r .scale <<<"$now")" == "$original_scale" ]] || fail 'a refused change still altered the scale' [[ "$(jq -r .scale <<<"$now")" == "$original_scale" ]] || fail 'a refused change still altered the scale'
# ── An unconfirmed change reverts on its own and stores nothing ────────────── # An immediate Revert may race both the apply process and its first readback.
# It must queue until both are clear, then verify the original generation.
target_scale=$(awk -v s="$original_scale" 'BEGIN { print (s == 1.25) ? 1.5 : 1.25 }') target_scale=$(awk -v s="$original_scale" 'BEGIN { print (s == 1.25) ? 1.5 : 1.25 }')
[[ "$(run ipc call displays-test applyScale "$target_scale")" == "true" ]] \
|| fail 'the immediate-revert fixture could not apply'
run ipc call displays-test revertChange >/dev/null
immediate_reverted=false
for _ in $(seq 1 60); do
if display_is_restored && [[ "$(status | jq -r .awaiting)" == "false" ]]; then
immediate_reverted=true
break
fi
sleep 0.2
done
[[ "$immediate_reverted" == true ]] \
|| fail 'an immediate Revert raced the apply/readback and did not restore the display'
# ── An unconfirmed change reverts on its own and stores nothing ──────────────
[[ "$(run ipc call displays-test applyScale "$target_scale")" == "true" ]] \ [[ "$(run ipc call displays-test applyScale "$target_scale")" == "true" ]] \
|| fail 'a valid scale change was refused' || fail 'a valid scale change was refused'