diff --git a/web-nodejs/public/css/remote.css b/web-nodejs/public/css/remote.css index 68e9a768..ab3fedd9 100644 --- a/web-nodejs/public/css/remote.css +++ b/web-nodejs/public/css/remote.css @@ -866,8 +866,42 @@ /* ---- Monitors & Virtual Displays ---- */ #monitors-menu.toolbar-dropdown-menu { + display: flex; + flex-direction: column; min-width: 240px; max-width: min(300px, calc(100vw - 24px)); + max-height: min(75vh, calc(100dvh - 120px)); + overflow: hidden; + padding: 4px; +} + +#monitors-menu > .dropdown-label { + flex-shrink: 0; +} + +.monitors-menu-list { + flex: 1 1 auto; + min-height: 0; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: var(--border-primary, #30363d) transparent; +} + +.monitors-menu-list::-webkit-scrollbar { + width: 6px; +} + +.monitors-menu-list::-webkit-scrollbar-thumb { + background: var(--border-primary, #30363d); + border-radius: 3px; +} + +.monitors-menu-vd { + flex-shrink: 0; + border-top: 1px solid var(--border-primary, #30363d); + margin-top: 4px; + padding-top: 4px; + background: var(--bg-secondary, #161b22); } .monitor-item { diff --git a/web-nodejs/public/js/remote.js b/web-nodejs/public/js/remote.js index 39fc523e..492d7e14 100644 --- a/web-nodejs/public/js/remote.js +++ b/web-nodejs/public/js/remote.js @@ -1486,6 +1486,9 @@ menu.innerHTML = ''; if (label) menu.appendChild(label); + const listWrap = document.createElement('div'); + listWrap.className = 'monitors-menu-list'; + // Physical monitors monitors.forEach(m => { const item = document.createElement('button'); @@ -1506,19 +1509,20 @@ item.classList.add('active'); refreshMonitorButton(session); }); - menu.appendChild(item); + listWrap.appendChild(item); }); + menu.appendChild(listWrap); + // Virtual displays (RustDesk IDD / Amyuni IDD) if (vd && vd.supported) { - const divider = document.createElement('div'); - divider.className = 'dropdown-divider'; - menu.appendChild(divider); + const vdWrap = document.createElement('div'); + vdWrap.className = 'monitors-menu-vd'; const vdLabel = document.createElement('div'); vdLabel.className = 'dropdown-label'; vdLabel.textContent = t('remote.virtual_displays', 'Virtual displays'); - menu.appendChild(vdLabel); + vdWrap.appendChild(vdLabel); if (vd.impl === 'rustdesk_idd') { const active = Array.isArray(vd.rustdeskDisplays) ? vd.rustdeskDisplays : []; @@ -1533,7 +1537,7 @@ item.addEventListener('click', () => { session.client.toggleVirtualDisplay(idx, !on); }); - menu.appendChild(item); + vdWrap.appendChild(item); } } else if (vd.impl === 'amyuni_idd') { const count = (typeof vd.amyuniCount === 'number') ? vd.amyuniCount : 0; @@ -1565,7 +1569,7 @@ row.appendChild(minus); row.appendChild(num); row.appendChild(plus); - menu.appendChild(row); + vdWrap.appendChild(row); } // Plug out all @@ -1576,7 +1580,8 @@ plugOut.addEventListener('click', () => { session.client.toggleVirtualDisplay(-1, false); }); - menu.appendChild(plugOut); + vdWrap.appendChild(plugOut); + menu.appendChild(vdWrap); } }