백라이트 즉시 적용 동작 개선
This commit is contained in:
@@ -104,7 +104,7 @@ API 응답의 `battery.enabled`는 false, `battery.removed`는 true로 내려가
|
||||
- 팬 이상감지: 기준 표본 수, 최신 표본 제외 수, RPM/온도 이상 감지 차이, RPM/온도 복구 차이, RPM 감시 시작 PWM, alert 유지 중 반복 기록, 반복 기록 간격, 하강 변화 원인 후보 표시 여부
|
||||
- UPS/배터리 설정: 현재 UPS 제거 상태에서는 설정 모달에서 숨겨지고, `battery.enabled=true`일 때만 배터리 예측 항목을 노출합니다.
|
||||
|
||||
디스플레이 회전/터치 좌표 설정은 DB가 아니라 라즈베리파이 부팅 파일에 저장합니다. 저장 전 기존 파일을 `.control-YYYYMMDD-HHMMSS.bak` 형식으로 백업하고, 변경 사항은 재부팅 후 적용됩니다. 구형 정품 7인치 Touch Display의 콘솔 회전은 `cmdline.txt`의 `video=DSI-1:800x480@60,rotate=...`를 사용하며, 터치 좌표 보정이 필요하면 `config.txt`의 `vc4-kms-dsi-7inch` overlay로 전환합니다. 백라이트 밝기와 백라이트 전원은 `/sys/class/backlight` 장치를 통해 즉시 적용되며 재부팅이 필요 없습니다.
|
||||
디스플레이 회전/터치 좌표 설정은 DB가 아니라 라즈베리파이 부팅 파일에 저장합니다. 저장 전 기존 파일을 `.control-YYYYMMDD-HHMMSS.bak` 형식으로 백업하고, 변경 사항은 재부팅 후 적용됩니다. 구형 정품 7인치 Touch Display의 콘솔 회전은 `cmdline.txt`의 `video=DSI-1:800x480@60,rotate=...`를 사용하며, 터치 좌표 보정이 필요하면 `config.txt`의 `vc4-kms-dsi-7inch` overlay로 전환합니다. 백라이트 밝기와 백라이트 전원은 `/sys/class/backlight` 장치를 통해 슬라이더/토글 조작 직후 debounce 후 즉시 적용되며 재부팅이 필요 없습니다. 백라이트 전원을 끄면 brightness도 0으로 함께 맞춰 상태 일관성을 유지합니다.
|
||||
|
||||
설정 모달이 열려 있는 동안 1초 상태 갱신은 폼 DOM을 다시 만들지 않습니다. 입력 중인 값은 저장, 기본값 초기화, 닫기 전까지 유지되며, 백그라운드 snapshot은 내부 설정 payload만 갱신합니다. 단순 boolean 설정은 `켜기`/`끄기` 세그먼트로 표시합니다.
|
||||
|
||||
|
||||
@@ -3700,6 +3700,9 @@ function touch_display_set_runtime(array $input): array
|
||||
$maxBrightness = touch_display_read_int($backlightPath . '/max_brightness') ?? 255;
|
||||
$brightness = max(0, min($maxBrightness, (int)($input['brightness'] ?? $maxBrightness)));
|
||||
$enabled = touch_display_bool($input['backlight_enabled'] ?? '1');
|
||||
if (!$enabled) {
|
||||
$brightness = 0;
|
||||
}
|
||||
|
||||
touch_display_write_value($backlightPath . '/brightness', (string)$brightness);
|
||||
if (is_writable($backlightPath . '/bl_power') || is_readable($backlightPath . '/bl_power')) {
|
||||
|
||||
+48
-16
@@ -70,6 +70,9 @@
|
||||
fanApplying: false,
|
||||
fanApplyTimer: null,
|
||||
fanApplyPending: null,
|
||||
touchRuntimeApplying: false,
|
||||
touchRuntimeTimer: null,
|
||||
touchRuntimePending: null,
|
||||
latestFanPwm: 0,
|
||||
fanCauseTick: 0,
|
||||
dmesgOpen: false,
|
||||
@@ -208,8 +211,6 @@
|
||||
touchBacklight: 'Backlight',
|
||||
touchBrightness: 'Brightness',
|
||||
touchBacklightEnabled: 'Backlight power',
|
||||
touchRuntimeSave: 'Apply brightness now',
|
||||
touchRuntimeSaved: 'Brightness applied.',
|
||||
touchDisplayOverlay: 'Manual overlay',
|
||||
touchDisplayAutoDetect: 'Auto detect',
|
||||
touchDisplayEnabled: 'LCD output',
|
||||
@@ -384,8 +385,6 @@
|
||||
touchBacklight: '백라이트',
|
||||
touchBrightness: '밝기',
|
||||
touchBacklightEnabled: '백라이트 전원',
|
||||
touchRuntimeSave: '밝기 즉시 적용',
|
||||
touchRuntimeSaved: '밝기를 적용했습니다.',
|
||||
touchDisplayOverlay: '수동 overlay',
|
||||
touchDisplayAutoDetect: '자동 감지',
|
||||
touchDisplayEnabled: 'LCD 출력',
|
||||
@@ -768,10 +767,6 @@
|
||||
${numberField('touch_sizex', t('touchSizeX'), config.touch_sizex || 800, 100, 4096)}
|
||||
${numberField('touch_sizey', t('touchSizeY'), config.touch_sizey || 480, 100, 4096)}
|
||||
</div>
|
||||
<div class="settings-inline-actions">
|
||||
<button id="touchDisplaySave" class="btn" type="button">${escapeHtml(t('touchDisplaySave'))}</button>
|
||||
<span class="settings-note">/boot/firmware/config.txt, /boot/firmware/cmdline.txt</span>
|
||||
</div>
|
||||
${backlight.available ? `
|
||||
<div class="touch-runtime-box">
|
||||
<h4>${escapeHtml(t('touchBacklight'))}</h4>
|
||||
@@ -784,12 +779,12 @@
|
||||
</div>
|
||||
${checkboxField('backlight_enabled', t('touchBacklightEnabled'), backlight.enabled !== false).replaceAll('data-display-key', 'data-display-runtime-key')}
|
||||
</div>
|
||||
<div class="settings-inline-actions">
|
||||
<button id="touchRuntimeSave" class="btn secondary" type="button">${escapeHtml(t('touchRuntimeSave'))}</button>
|
||||
<span class="settings-note">${escapeHtml(backlight.path || '')}</span>
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
<div class="settings-inline-actions">
|
||||
<button id="touchDisplaySave" class="btn" type="button">${escapeHtml(t('touchDisplaySave'))}</button>
|
||||
<span class="settings-note">/boot/firmware/config.txt, /boot/firmware/cmdline.txt</span>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
@@ -907,13 +902,29 @@
|
||||
});
|
||||
});
|
||||
$('#touchDisplaySave', els.settingsBody)?.addEventListener('click', saveTouchDisplaySettings);
|
||||
$('#touchRuntimeSave', els.settingsBody)?.addEventListener('click', saveTouchDisplayRuntime);
|
||||
const brightnessSlider = els.settingsBody.querySelector('[data-display-runtime-key="brightness"]');
|
||||
const brightnessValue = $('#touchBrightnessValue', els.settingsBody);
|
||||
brightnessSlider?.addEventListener('input', () => {
|
||||
if (brightnessValue) {
|
||||
brightnessValue.textContent = `${brightnessSlider.value} / ${brightnessSlider.max}`;
|
||||
}
|
||||
scheduleTouchDisplayRuntimeApply();
|
||||
});
|
||||
brightnessSlider?.addEventListener('change', scheduleTouchDisplayRuntimeApply);
|
||||
const backlightToggle = els.settingsBody.querySelector('[data-display-runtime-key="backlight_enabled"]');
|
||||
backlightToggle?.addEventListener('change', () => {
|
||||
if (!backlightToggle.checked && brightnessSlider) {
|
||||
brightnessSlider.value = '0';
|
||||
if (brightnessValue) {
|
||||
brightnessValue.textContent = `0 / ${brightnessSlider.max}`;
|
||||
}
|
||||
} else if (backlightToggle.checked && brightnessSlider && Number(brightnessSlider.value) <= 0) {
|
||||
brightnessSlider.value = brightnessSlider.max || '255';
|
||||
if (brightnessValue) {
|
||||
brightnessValue.textContent = `${brightnessSlider.value} / ${brightnessSlider.max}`;
|
||||
}
|
||||
}
|
||||
scheduleTouchDisplayRuntimeApply();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -972,6 +983,9 @@
|
||||
? (input.checked ? '1' : '0')
|
||||
: input.value;
|
||||
});
|
||||
if (values.backlight_enabled === '0') {
|
||||
values.brightness = '0';
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -994,18 +1008,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function saveTouchDisplayRuntime() {
|
||||
function scheduleTouchDisplayRuntimeApply(values = currentTouchDisplayRuntimeValues()) {
|
||||
clearTimeout(state.touchRuntimeTimer);
|
||||
state.touchRuntimeTimer = setTimeout(() => {
|
||||
applyTouchDisplayRuntime(values);
|
||||
}, 150);
|
||||
}
|
||||
|
||||
async function applyTouchDisplayRuntime(values = currentTouchDisplayRuntimeValues()) {
|
||||
if (state.touchRuntimeApplying) {
|
||||
state.touchRuntimePending = values;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
state.touchRuntimeApplying = true;
|
||||
const data = await api('touch_display_runtime_save', {
|
||||
runtime: JSON.stringify(currentTouchDisplayRuntimeValues()),
|
||||
runtime: JSON.stringify(values),
|
||||
});
|
||||
state.settingsDirty = false;
|
||||
state.touchRuntimeApplying = false;
|
||||
render(data);
|
||||
renderSettings(data.settings, { force: true });
|
||||
notice(t('touchRuntimeSaved'), 'success');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
notice(e.message || t('settingsSaveFailed'), 'error');
|
||||
} finally {
|
||||
state.touchRuntimeApplying = false;
|
||||
const pending = state.touchRuntimePending;
|
||||
state.touchRuntimePending = null;
|
||||
if (pending) applyTouchDisplayRuntime(pending);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -365,7 +365,7 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/app.js?v=20260723_touch_display2"></script>
|
||||
<script src="/assets/app.js?v=20260723_touch_display3"></script>
|
||||
<script src="/assets/wakelock.js?v=20260607_prefs1"></script>
|
||||
<?php endif; ?>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user