diff --git a/packages/frontend/src/components/RemoteDesktopModal.vue b/packages/frontend/src/components/RemoteDesktopModal.vue index 5fd7584..b1d4773 100644 --- a/packages/frontend/src/components/RemoteDesktopModal.vue +++ b/packages/frontend/src/components/RemoteDesktopModal.vue @@ -31,6 +31,13 @@ const mouse = ref(null); const desiredModalWidth = ref(1064); const desiredModalHeight = ref(858); const isKeyboardDisabledForInput = ref(false); // 标记键盘是否因输入框聚焦而禁用 +const isMinimized = ref(false); +const restoreButtonRef = ref(null); +const isDraggingRestoreButton = ref(false); +const restoreButtonPosition = ref({ x: 16, y: window.innerHeight / 2 - 25 }); // 16px from left, vertically centered +let dragOffsetX = 0; +let dragOffsetY = 0; +let hasDragged = false; // 新增 hasDragged 标志 const MIN_MODAL_WIDTH = 1024; const MIN_MODAL_HEIGHT = 768; @@ -338,6 +345,55 @@ const enableRdpKeyboard = () => { }); }; +const minimizeModal = () => { + isMinimized.value = true; +}; + +const restoreModal = () => { + isMinimized.value = false; +}; + +const onRestoreButtonMouseDown = (event: MouseEvent) => { + if (!restoreButtonRef.value) return; + hasDragged = false; // 重置拖拽标志 + isDraggingRestoreButton.value = true; + dragOffsetX = event.clientX - restoreButtonRef.value.getBoundingClientRect().left; + dragOffsetY = event.clientY - restoreButtonRef.value.getBoundingClientRect().top; + event.preventDefault(); + document.addEventListener('mousemove', onRestoreButtonMouseMove); + document.addEventListener('mouseup', onRestoreButtonMouseUp); +}; + +const onRestoreButtonMouseMove = (event: MouseEvent) => { + if (!isDraggingRestoreButton.value) return; + hasDragged = true; // 如果鼠标移动则设置拖拽标志 + let newX = event.clientX - dragOffsetX; + let newY = event.clientY - dragOffsetY; + + const buttonWidth = 50; + const buttonHeight = 50; + newX = Math.max(0, Math.min(newX, window.innerWidth - buttonWidth)); + newY = Math.max(0, Math.min(newY, window.innerHeight - buttonHeight)); + + restoreButtonPosition.value = { x: newX, y: newY }; +}; + +const onRestoreButtonMouseUp = () => { + isDraggingRestoreButton.value = false; + document.removeEventListener('mousemove', onRestoreButtonMouseMove); + document.removeEventListener('mouseup', onRestoreButtonMouseUp); + // click 事件会在 mouseup 后触发。如果我们拖拽了,我们不希望 click 事件恢复模态框。 + // handleClickRestoreButton 会检查 hasDragged。 +}; + +const handleClickRestoreButton = () => { + if (!hasDragged) { + restoreModal(); + } + // 为下一次交互重置 + hasDragged = false; +}; + const disconnectGuacamole = () => { removeInputListeners(); isKeyboardDisabledForInput.value = false; // 确保状态重置 @@ -444,6 +500,8 @@ onMounted(() => { onUnmounted(() => { disconnectGuacamole(); // 这里已经调用了 removeInputListeners + document.removeEventListener('mousemove', onRestoreButtonMouseMove); + document.removeEventListener('mouseup', onRestoreButtonMouseUp); }); watch(() => props.connection, (newConnection, oldConnection) => { @@ -473,17 +531,35 @@ const computedModalStyle = computed(() => {