diff --git a/packages/frontend/src/components/RemoteDesktopModal.vue b/packages/frontend/src/components/RemoteDesktopModal.vue index 9d45a4b..157a43a 100644 --- a/packages/frontend/src/components/RemoteDesktopModal.vue +++ b/packages/frontend/src/components/RemoteDesktopModal.vue @@ -15,23 +15,26 @@ const props = defineProps<{ const emit = defineEmits(['close']); const rdpDisplayRef = ref(null); +const rdpContainerRef = ref(null); // Added ref for the container // eslint-disable-next-line @typescript-eslint/no-explicit-any const guacClient = ref(null); const connectionStatus = ref<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected'); const statusMessage = ref(''); const keyboard = ref(null); const mouse = ref(null); -const inputWidth = ref(1024); -const inputHeight = ref(768); +// const inputWidth = ref(1024); // Removed, size determined by container +// const inputHeight = ref(768); // Removed, size determined by container // const modalStyle = ref({}); // Replaced by computedModalStyle -const rdpContainerStyle = ref<{ height?: string }>({}); // Only height is needed now -const modalWidth = ref(1064); // Initial default based on 1024 + padding -const modalHeight = ref(858); // Initial default based on 768 + padding +// const rdpContainerStyle = ref<{ height?: string }>({}); // Removed, size determined by flex-1 +const desiredModalWidth = ref(1064); // User sets the desired TOTAL modal width (1024 + 40 padding) +const desiredModalHeight = ref(858); // User sets the desired TOTAL modal height (768 + chrome) const RDP_BACKEND_API_BASE = 'http://localhost:9090'; const RDP_BACKEND_WEBSOCKET_URL = 'ws://localhost:8081'; +const LOCAL_STORAGE_MODAL_WIDTH_KEY = 'rdpModalWidth'; // Reverted key name +const LOCAL_STORAGE_MODAL_HEIGHT_KEY = 'rdpModalHeight'; // Reverted key name -const connectRdp = async (useInputValues = false) => { +const connectRdp = async () => { // Removed useInputValues parameter if (!props.connection || !rdpDisplayRef.value) { statusMessage.value = t('remoteDesktopModal.errors.missingInfo'); connectionStatus.value = 'error'; @@ -57,39 +60,26 @@ const connectRdp = async (useInputValues = false) => { } statusMessage.value = t('remoteDesktopModal.status.connectingWs'); - let widthToSend = 1024; - let heightToSend = 768; + // Get RDP container dimensions after DOM update + await nextTick(); + + let widthToSend = 800; // Default/fallback width + let heightToSend = 600; // Default/fallback height const dpiToSend = 96; - if (useInputValues) { - widthToSend = parseInt(String(inputWidth.value), 10) || widthToSend; - heightToSend = parseInt(String(inputHeight.value), 10) || heightToSend; + if (rdpContainerRef.value) { + // Use clientWidth/clientHeight as they represent the inner dimensions available for content + widthToSend = rdpContainerRef.value.clientWidth; + heightToSend = rdpContainerRef.value.clientHeight + 1; // Subtract 1 based on feedback + // Ensure minimum dimensions, adjust if necessary based on backend requirements + widthToSend = Math.max(100, widthToSend); + heightToSend = Math.max(100, heightToSend); + console.log(`Calculated RDP dimensions: ${widthToSend}x${heightToSend}`); } else { - if (rdpDisplayRef.value && rdpDisplayRef.value.clientWidth > 0 && rdpDisplayRef.value.clientHeight > 0) { - widthToSend = rdpDisplayRef.value.clientWidth; - heightToSend = rdpDisplayRef.value.clientHeight; - } else { - widthToSend = parseInt(String(inputWidth.value), 10) || widthToSend; - heightToSend = parseInt(String(inputHeight.value), 10) || heightToSend; - } + console.warn("RDP container ref not available to get dimensions. Using defaults."); + // Consider setting an error state or notifying the user } - inputWidth.value = widthToSend; - inputHeight.value = heightToSend; - - const extraWidth = 40; - const headerHeight = 45; - const footerHeight = 35; - - // Update modal size refs based on RDP size + padding - modalWidth.value = widthToSend + extraWidth; - modalHeight.value = heightToSend + headerHeight + footerHeight + 10; - - rdpContainerStyle.value = { - // width: `${widthToSend}px`, // Remove width setting - height: `${heightToSend}px`, - }; - const tunnelUrl = `${RDP_BACKEND_WEBSOCKET_URL}/?token=${encodeURIComponent(token)}&width=${widthToSend}&height=${heightToSend}&dpi=${dpiToSend}`; // @ts-ignore const tunnel = new Guacamole.WebSocketTunnel(tunnelUrl); @@ -214,7 +204,10 @@ const removeInputListeners = () => { }; +// Removed stopResizeObserver as ResizeObserver is no longer used + const disconnectRdp = () => { + // stopResizeObserver(); // Removed removeInputListeners(); if (guacClient.value) { guacClient.value.disconnect(); @@ -232,40 +225,44 @@ const disconnectRdp = () => { }; -const reconnectWithNewSize = () => { - const width = parseInt(String(inputWidth.value), 10); - const height = parseInt(String(inputHeight.value), 10); - if (!width || width <= 0 || !height || height <= 0) { - statusMessage.value = t('remoteDesktopModal.errors.invalidSize'); - return; - } - disconnectRdp(); - nextTick(() => { - connectRdp(true); - - const headerHeight = 45; - const footerHeight = 35; - const extraWidth = 40; - - rdpContainerStyle.value = { - // width: `${width}px`, // Remove width setting - height: `${height}px`, - }; - // Update modal size refs based on new RDP size + padding - modalWidth.value = width + extraWidth; - modalHeight.value = height + headerHeight + footerHeight + 10; - }); -}; +// Removed reconnectWithNewSize function const closeModal = () => { disconnectRdp(); emit('close'); }; +// Removed setupResizeObserver as ResizeObserver is no longer used + + +// Load desired MODAL size from localStorage on mount +const loadDesiredModalSize = () => { + const savedWidth = localStorage.getItem(LOCAL_STORAGE_MODAL_WIDTH_KEY); + const savedHeight = localStorage.getItem(LOCAL_STORAGE_MODAL_HEIGHT_KEY); + if (savedWidth) { + desiredModalWidth.value = parseInt(savedWidth, 10) || desiredModalWidth.value; + } + if (savedHeight) { + desiredModalHeight.value = parseInt(savedHeight, 10) || desiredModalHeight.value; + } +}; + +// Save desired MODAL size to localStorage when changed +watch(desiredModalWidth, (newWidth) => { + localStorage.setItem(LOCAL_STORAGE_MODAL_WIDTH_KEY, String(newWidth)); +}); +watch(desiredModalHeight, (newHeight) => { + localStorage.setItem(LOCAL_STORAGE_MODAL_HEIGHT_KEY, String(newHeight)); +}); + + onMounted(() => { + loadDesiredModalSize(); // Load saved size first + if (props.connection) { - nextTick(() => { - connectRdp(false); + nextTick(async () => { + await connectRdp(); // Connect using initial size + // No need to setup observer anymore }); } else { statusMessage.value = t('remoteDesktopModal.errors.noConnection'); @@ -274,13 +271,14 @@ onMounted(() => { }); onUnmounted(() => { - disconnectRdp(); + disconnectRdp(); // This already calls stopResizeObserver }); watch(() => props.connection, (newConnection, oldConnection) => { if (newConnection && newConnection.id !== oldConnection?.id) { - nextTick(() => { - connectRdp(false); + nextTick(async () => { + await connectRdp(); // Connect using initial size + // No need to setup observer anymore }); } else if (!newConnection) { disconnectRdp(); @@ -289,10 +287,18 @@ watch(() => props.connection, (newConnection, oldConnection) => { } }); -const computedModalStyle = computed(() => ({ - width: `${modalWidth.value}px`, - height: `${modalHeight.value}px`, -})); +// Use the desired modal size directly for the style +const computedModalStyle = computed(() => { + // const extraWidth = 40; // Removed from here as well + // const headerHeight = 45; // Defined in connectRdp + // const footerHeight = 35; // Defined in connectRdp + // const extraHeight = headerHeight + footerHeight + 10; // Defined in connectRdp + + return { + width: `${desiredModalWidth.value}px`, // Width is direct + height: `${desiredModalHeight.value}px`, // Height is direct + }; +});