Avoid visual Phone harness teardown
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
// Nonvisual owner of Phone Controls' stable action model and enablement rules.
|
||||||
|
// Keeping this logic free of delegates and icons makes it safe to exercise in
|
||||||
|
// disposable diagnostic engines.
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property var actionModels: [
|
||||||
|
{ id: "share", glyph: "\u{F0142}", label: "Send file" },
|
||||||
|
{ id: "clipboard", glyph: "\u{F014C}", label: "Clipboard" },
|
||||||
|
{ id: "ring", glyph: "\u{F009A}", label: "Ring" },
|
||||||
|
{ id: "messages", glyph: "\u{F0365}", label: "Messages" }
|
||||||
|
]
|
||||||
|
|
||||||
|
function actionEnabled(action: string): bool {
|
||||||
|
if (action === "messages")
|
||||||
|
return SystemSettings.bluebubblesAvailable;
|
||||||
|
return KdeConnect.phoneReachable
|
||||||
|
&& !KdeConnect.transferActive
|
||||||
|
&& KdeConnect.supports(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,14 +10,11 @@ Item {
|
|||||||
signal toggleExpanded
|
signal toggleExpanded
|
||||||
|
|
||||||
readonly property var phone: KdeConnect.preferredPhone
|
readonly property var phone: KdeConnect.preferredPhone
|
||||||
// Keep the four slots stable. The KDE actions can become unavailable when
|
readonly property var actionModels: phoneActions.actionModels
|
||||||
// the phone disconnects, but the layout should not shift beneath Messages.
|
|
||||||
readonly property var actionModels: [
|
PhoneActions {
|
||||||
{ id: "share", glyph: "\u{F0142}", label: "Send file" },
|
id: phoneActions
|
||||||
{ id: "clipboard", glyph: "\u{F014C}", label: "Clipboard" },
|
}
|
||||||
{ id: "ring", glyph: "\u{F009A}", label: "Ring" },
|
|
||||||
{ id: "messages", glyph: "\u{F0365}", label: "Messages" }
|
|
||||||
]
|
|
||||||
|
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
@@ -288,11 +285,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function actionEnabled(action: string): bool {
|
function actionEnabled(action: string): bool {
|
||||||
if (action === "messages")
|
return phoneActions.actionEnabled(action);
|
||||||
return SystemSettings.bluebubblesAvailable;
|
|
||||||
return KdeConnect.phoneReachable
|
|
||||||
&& !KdeConnect.transferActive
|
|
||||||
&& KdeConnect.supports(action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function actionAccessibleDescription(action: string): string {
|
function actionAccessibleDescription(action: string): string {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ HomeBrightnessSlider 1.0 HomeBrightnessSlider.qml
|
|||||||
HomeControls 1.0 HomeControls.qml
|
HomeControls 1.0 HomeControls.qml
|
||||||
HomeTile 1.0 HomeTile.qml
|
HomeTile 1.0 HomeTile.qml
|
||||||
IconButton 1.0 IconButton.qml
|
IconButton 1.0 IconButton.qml
|
||||||
|
PhoneActions 1.0 PhoneActions.qml
|
||||||
PhoneControls 1.0 PhoneControls.qml
|
PhoneControls 1.0 PhoneControls.qml
|
||||||
QuickSettings 1.0 QuickSettings.qml
|
QuickSettings 1.0 QuickSettings.qml
|
||||||
QuickSettingsPanel 1.0 QuickSettingsPanel.qml
|
QuickSettingsPanel 1.0 QuickSettingsPanel.qml
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ import qs.services
|
|||||||
// Component-only diagnostic surface. The contract replaces the two services in
|
// Component-only diagnostic surface. The contract replaces the two services in
|
||||||
// its copied configuration with fixture singletons before this file is run.
|
// its copied configuration with fixture singletons before this file is run.
|
||||||
ShellRoot {
|
ShellRoot {
|
||||||
PhoneControls {
|
PhoneActions {
|
||||||
id: phoneControls
|
id: phoneActions
|
||||||
width: 408
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
@@ -46,9 +45,9 @@ ShellRoot {
|
|||||||
|
|
||||||
function status(): string {
|
function status(): string {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
actions: phoneControls.actionModels.map(action => ({
|
actions: phoneActions.actionModels.map(action => ({
|
||||||
id: action.id,
|
id: action.id,
|
||||||
enabled: phoneControls.actionEnabled(action.id)
|
enabled: phoneActions.actionEnabled(action.id)
|
||||||
})),
|
})),
|
||||||
bluebubblesAvailable: SystemSettings.bluebubblesAvailable,
|
bluebubblesAvailable: SystemSettings.bluebubblesAvailable,
|
||||||
appLaunches: SystemSettings.launchCount,
|
appLaunches: SystemSettings.launchCount,
|
||||||
|
|||||||
@@ -85,16 +85,16 @@ rg -Fq 'visible: KdeConnect.phoneReachable' \
|
|||||||
"$source_config_path/modules/bar/StatusCluster.qml" \
|
"$source_config_path/modules/bar/StatusCluster.qml" \
|
||||||
|| fail 'reachable phone state is absent from the bar'
|
|| fail 'reachable phone state is absent from the bar'
|
||||||
|
|
||||||
for component in ControlSectionHeader HomeBrightnessSlider HomeControls HomeTile PhoneControls RecentExchange; do
|
for component in ControlSectionHeader HomeBrightnessSlider HomeControls HomeTile PhoneActions PhoneControls RecentExchange; do
|
||||||
[[ -f "$quicksettings_path/$component.qml" ]] \
|
[[ -f "$quicksettings_path/$component.qml" ]] \
|
||||||
|| fail "$component is missing"
|
|| fail "$component is missing"
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ "$(rg -c 'id: "(share|clipboard|ring|messages)"' "$quicksettings_path/PhoneControls.qml")" -eq 4 ]] \
|
[[ "$(rg -c 'id: "(share|clipboard|ring|messages)"' "$quicksettings_path/PhoneActions.qml")" -eq 4 ]] \
|
||||||
|| fail 'Phone controls do not expose four stable action models'
|
|| fail 'Phone controls do not expose four stable action models'
|
||||||
rg -Fq 'columns: 4' "$quicksettings_path/PhoneControls.qml" \
|
rg -Fq 'columns: 4' "$quicksettings_path/PhoneControls.qml" \
|
||||||
|| fail 'Phone actions are not arranged in four equal columns'
|
|| fail 'Phone actions are not arranged in four equal columns'
|
||||||
if rg -Fq '.filter(' "$quicksettings_path/PhoneControls.qml"; then
|
if rg -Fq '.filter(' "$quicksettings_path/PhoneActions.qml"; then
|
||||||
fail 'Phone action columns change when a KDE capability is unavailable'
|
fail 'Phone action columns change when a KDE capability is unavailable'
|
||||||
fi
|
fi
|
||||||
rg -Fq 'SystemSettings.bluebubblesAvailable' "$quicksettings_path/PhoneControls.qml" \
|
rg -Fq 'SystemSettings.bluebubblesAvailable' "$quicksettings_path/PhoneControls.qml" \
|
||||||
@@ -107,6 +107,9 @@ rg -Fq 'KdeConnect.phoneReachable' "$quicksettings_path/PhoneControls.qml" \
|
|||||||
rg -Fq 'HomeBrightnessSlider 1.0 HomeBrightnessSlider.qml' \
|
rg -Fq 'HomeBrightnessSlider 1.0 HomeBrightnessSlider.qml' \
|
||||||
"$quicksettings_path/qmldir" \
|
"$quicksettings_path/qmldir" \
|
||||||
|| fail 'brightness slider is not registered in the quick-settings module'
|
|| fail 'brightness slider is not registered in the quick-settings module'
|
||||||
|
rg -Fq 'PhoneActions 1.0 PhoneActions.qml' \
|
||||||
|
"$quicksettings_path/qmldir" \
|
||||||
|
|| fail 'Phone actions model is not registered in the quick-settings module'
|
||||||
|
|
||||||
[[ "$(rg -c '^[[:space:]]*columns: 2$' "$quicksettings_path/HomeControls.qml")" -ge 2 ]] \
|
[[ "$(rg -c '^[[:space:]]*columns: 2$' "$quicksettings_path/HomeControls.qml")" -ge 2 ]] \
|
||||||
|| fail 'resting and expanded Home shelves are not both two-column grids'
|
|| fail 'resting and expanded Home shelves are not both two-column grids'
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ set -euo pipefail
|
|||||||
|
|
||||||
project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
phone_controls="$project_root/config/dot/quickshell/modules/quicksettings/PhoneControls.qml"
|
phone_controls="$project_root/config/dot/quickshell/modules/quicksettings/PhoneControls.qml"
|
||||||
|
phone_actions="$project_root/config/dot/quickshell/modules/quicksettings/PhoneActions.qml"
|
||||||
|
quicksettings_qmldir="$project_root/config/dot/quickshell/modules/quicksettings/qmldir"
|
||||||
system_settings="$project_root/config/dot/quickshell/services/SystemSettings.qml"
|
system_settings="$project_root/config/dot/quickshell/services/SystemSettings.qml"
|
||||||
harness="$project_root/config/dot/quickshell/phone-controls-harness.qml"
|
harness="$project_root/config/dot/quickshell/phone-controls-harness.qml"
|
||||||
kde_fixture="$project_root/tests/quickshell/fixtures/PhoneControlsKdeConnect.qml"
|
kde_fixture="$project_root/tests/quickshell/fixtures/PhoneControlsKdeConnect.qml"
|
||||||
@@ -17,11 +19,24 @@ fail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[ -f "$phone_controls" ]] || fail 'Phone controls component is missing'
|
[[ -f "$phone_controls" ]] || fail 'Phone controls component is missing'
|
||||||
|
[[ -f "$phone_actions" ]] || fail 'Nonvisual Phone actions component is missing'
|
||||||
[[ -f "$system_settings" ]] || fail 'System settings service is missing'
|
[[ -f "$system_settings" ]] || fail 'System settings service is missing'
|
||||||
[[ -f "$harness" ]] || fail 'Phone controls runtime harness is missing'
|
[[ -f "$harness" ]] || fail 'Phone controls runtime harness is missing'
|
||||||
[[ -f "$kde_fixture" ]] || fail 'Phone controls KDE fixture is missing'
|
[[ -f "$kde_fixture" ]] || fail 'Phone controls KDE fixture is missing'
|
||||||
[[ -f "$settings_fixture" ]] || fail 'Phone controls System Settings fixture is missing'
|
[[ -f "$settings_fixture" ]] || fail 'Phone controls System Settings fixture is missing'
|
||||||
|
|
||||||
|
rg -Fq 'PhoneActions 1.0 PhoneActions.qml' "$quicksettings_qmldir" \
|
||||||
|
|| fail 'Phone actions component is not registered'
|
||||||
|
rg -Fq 'PhoneActions {' "$phone_controls" \
|
||||||
|
|| fail 'Phone controls do not consume the shared action model'
|
||||||
|
rg -Fq 'readonly property var actionModels: phoneActions.actionModels' "$phone_controls" \
|
||||||
|
|| fail 'Phone controls do not render the shared action models'
|
||||||
|
rg -Fq 'PhoneActions {' "$harness" \
|
||||||
|
|| fail 'Runtime harness does not use the nonvisual action model'
|
||||||
|
if rg -Fq 'PhoneControls {' "$harness"; then
|
||||||
|
fail 'Runtime harness still instantiates the visual Phone controls tree'
|
||||||
|
fi
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
XDG_STATE_HOME="$state_home" QS_DISABLE_CRASH_HANDLER=1 \
|
XDG_STATE_HOME="$state_home" QS_DISABLE_CRASH_HANDLER=1 \
|
||||||
qs -p "$config_path/phone-controls-harness.qml" kill >/dev/null 2>&1 || true
|
qs -p "$config_path/phone-controls-harness.qml" kill >/dev/null 2>&1 || true
|
||||||
@@ -76,11 +91,11 @@ rg -Fq 'command: ["flatpak", "info", "app.bluebubbles.BlueBubbles"]' "$system_se
|
|||||||
|| fail 'BlueBubbles installed-state probe is missing'
|
|| fail 'BlueBubbles installed-state probe is missing'
|
||||||
|
|
||||||
for action in share clipboard ring messages; do
|
for action in share clipboard ring messages; do
|
||||||
rg -Fq "id: \"$action\"" "$phone_controls" \
|
rg -Fq "id: \"$action\"" "$phone_actions" \
|
||||||
|| fail "Phone actions do not include $action"
|
|| fail "Phone actions do not include $action"
|
||||||
done
|
done
|
||||||
|
|
||||||
if rg -Fq '.filter(' "$phone_controls"; then
|
if rg -Fq '.filter(' "$phone_actions"; then
|
||||||
fail 'Phone actions are filtered instead of keeping four stable columns'
|
fail 'Phone actions are filtered instead of keeping four stable columns'
|
||||||
fi
|
fi
|
||||||
rg -Fq 'columns: 4' "$phone_controls" \
|
rg -Fq 'columns: 4' "$phone_controls" \
|
||||||
@@ -93,7 +108,7 @@ rg -Fq 'KdeConnect.phoneReachable' "$phone_controls" \
|
|||||||
|| fail 'KDE action reachability semantics are missing'
|
|| fail 'KDE action reachability semantics are missing'
|
||||||
rg -Fq 'function actionEnabled(action: string): bool' "$phone_controls" \
|
rg -Fq 'function actionEnabled(action: string): bool' "$phone_controls" \
|
||||||
|| fail 'Phone controls do not expose action enablement'
|
|| fail 'Phone controls do not expose action enablement'
|
||||||
rg -Fq 'KdeConnect.supports(action)' "$phone_controls" \
|
rg -Fq 'KdeConnect.supports(action)' "$phone_actions" \
|
||||||
|| fail 'KDE action capability semantics are missing'
|
|| fail 'KDE action capability semantics are missing'
|
||||||
rg -Fq 'else if (action === "messages")' "$phone_controls" \
|
rg -Fq 'else if (action === "messages")' "$phone_controls" \
|
||||||
|| fail 'Messages has no independent invocation branch'
|
|| fail 'Messages has no independent invocation branch'
|
||||||
|
|||||||
Reference in New Issue
Block a user