Feature: Support switching remote desktop input language
This commit is contained in:
@@ -336,6 +336,9 @@ inline std::string GetWebPageHTML() {
|
|||||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
max-width: 100%; opacity: 0.8;
|
max-width: 100%; opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
.device-card .active-window.busy {
|
||||||
|
color: #e94560; opacity: 1; font-weight: 500;
|
||||||
|
}
|
||||||
.device-card .meta-row { display: flex; gap: 12px; margin-top: 6px; font-size: 12px; color: #666; }
|
.device-card .meta-row { display: flex; gap: 12px; margin-top: 6px; font-size: 12px; color: #666; }
|
||||||
.device-card .meta-item { display: flex; align-items: center; gap: 4px; }
|
.device-card .meta-item { display: flex; align-items: center; gap: 4px; }
|
||||||
.device-card .meta-item.rtt { font-weight: 500; }
|
.device-card .meta-item.rtt { font-weight: 500; }
|
||||||
@@ -854,6 +857,7 @@ inline std::string GetWebPageHTML() {
|
|||||||
<button class="shortcut-btn" data-key="190" tabindex="-1">.</button>
|
<button class="shortcut-btn" data-key="190" tabindex="-1">.</button>
|
||||||
<button class="shortcut-btn" data-key="188" tabindex="-1">,</button>
|
<button class="shortcut-btn" data-key="188" tabindex="-1">,</button>
|
||||||
<button class="shortcut-btn" data-key="191" data-shift="1" tabindex="-1">?</button>
|
<button class="shortcut-btn" data-key="191" data-shift="1" tabindex="-1">?</button>
|
||||||
|
<button class="shortcut-btn" data-key="32" data-ctrl="1" tabindex="-1" title="Ctrl+Space">中</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="touch-indicator" id="touch-indicator"></div>
|
<div class="touch-indicator" id="touch-indicator"></div>
|
||||||
@@ -1221,6 +1225,13 @@ inline std::string GetWebPageHTML() {
|
|||||||
return 'rtt-poor'; // Red: > 300ms
|
return 'rtt-poor'; // Red: > 300ms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isWindowBusy(activeWindow) {
|
||||||
|
if (!activeWindow || activeWindow.trim() === '') return false;
|
||||||
|
const lower = activeWindow.toLowerCase();
|
||||||
|
if (lower.includes('locked') || lower.includes('inactive')) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function updateDeviceInfo(deviceId, rtt, activeWindow) {
|
function updateDeviceInfo(deviceId, rtt, activeWindow) {
|
||||||
// Update device in array
|
// Update device in array
|
||||||
const device = devices.find(d => d.id === deviceId || d.id === String(deviceId));
|
const device = devices.find(d => d.id === deviceId || d.id === String(deviceId));
|
||||||
@@ -1258,6 +1269,7 @@ inline std::string GetWebPageHTML() {
|
|||||||
}
|
}
|
||||||
winEl.textContent = activeWindow;
|
winEl.textContent = activeWindow;
|
||||||
winEl.title = activeWindow;
|
winEl.title = activeWindow;
|
||||||
|
winEl.className = 'active-window' + (isWindowBusy(activeWindow) ? ' busy' : '');
|
||||||
} else if (winEl) {
|
} else if (winEl) {
|
||||||
winEl.remove();
|
winEl.remove();
|
||||||
}
|
}
|
||||||
@@ -1303,7 +1315,7 @@ inline std::string GetWebPageHTML() {
|
|||||||
'<span class="meta-item">Ver: ' + escapeHtml(ver) + '</span>' +
|
'<span class="meta-item">Ver: ' + escapeHtml(ver) + '</span>' +
|
||||||
'<span class="meta-item">' + screenInfo + '</span>' +
|
'<span class="meta-item">' + screenInfo + '</span>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
(activeWin ? '<div class="active-window" title="' + escapeHtml(activeWin) + '">' + escapeHtml(activeWin) + '</div>' : '') +
|
(activeWin ? '<div class="active-window' + (isWindowBusy(activeWin) ? ' busy' : '') + '" title="' + escapeHtml(activeWin) + '">' + escapeHtml(activeWin) + '</div>' : '') +
|
||||||
'</div>';
|
'</div>';
|
||||||
}).join('');
|
}).join('');
|
||||||
}
|
}
|
||||||
@@ -2584,10 +2596,13 @@ inline std::string GetWebPageHTML() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const keyCode = parseInt(btn.dataset.key);
|
const keyCode = parseInt(btn.dataset.key);
|
||||||
const needShift = btn.dataset.shift === '1';
|
const needShift = btn.dataset.shift === '1';
|
||||||
|
const needCtrl = btn.dataset.ctrl === '1';
|
||||||
|
if (needCtrl) sendShortcutKey(17, true); // Ctrl down
|
||||||
if (needShift) sendShortcutKey(16, true); // Shift down
|
if (needShift) sendShortcutKey(16, true); // Shift down
|
||||||
sendShortcutKey(keyCode, true);
|
sendShortcutKey(keyCode, true);
|
||||||
sendShortcutKey(keyCode, false);
|
sendShortcutKey(keyCode, false);
|
||||||
if (needShift) sendShortcutKey(16, false); // Shift up
|
if (needShift) sendShortcutKey(16, false); // Shift up
|
||||||
|
if (needCtrl) sendShortcutKey(17, false); // Ctrl up
|
||||||
});
|
});
|
||||||
btn.addEventListener('click', function(e) {
|
btn.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2595,10 +2610,13 @@ inline std::string GetWebPageHTML() {
|
|||||||
if (!('ontouchstart' in window)) {
|
if (!('ontouchstart' in window)) {
|
||||||
const keyCode = parseInt(btn.dataset.key);
|
const keyCode = parseInt(btn.dataset.key);
|
||||||
const needShift = btn.dataset.shift === '1';
|
const needShift = btn.dataset.shift === '1';
|
||||||
|
const needCtrl = btn.dataset.ctrl === '1';
|
||||||
|
if (needCtrl) sendShortcutKey(17, true); // Ctrl down
|
||||||
if (needShift) sendShortcutKey(16, true);
|
if (needShift) sendShortcutKey(16, true);
|
||||||
sendShortcutKey(keyCode, true);
|
sendShortcutKey(keyCode, true);
|
||||||
sendShortcutKey(keyCode, false);
|
sendShortcutKey(keyCode, false);
|
||||||
if (needShift) sendShortcutKey(16, false);
|
if (needShift) sendShortcutKey(16, false);
|
||||||
|
if (needCtrl) sendShortcutKey(17, false); // Ctrl up
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user