diff --git a/kasmweb/app/ui.js b/kasmweb/app/ui.js index 897cd00..4a41b6e 100644 --- a/kasmweb/app/ui.js +++ b/kasmweb/app/ui.js @@ -22,7 +22,7 @@ window.addEventListener("load", function() { import * as Log from '../core/util/logging.js'; import _, { l10n } from './localization.js'; -import { isTouchDevice, isSafari, isIOS, isAndroid, dragThreshold } +import { isTouchDevice, isSafari, hasScrollbarGutter, dragThreshold } from '../core/util/browser.js'; import { setCapture, getPointerEvent } from '../core/util/events.js'; import KeyTable from "../core/input/keysym.js"; @@ -1618,8 +1618,9 @@ const UI = { // Can't be clipping if viewport is scaled to fit UI.forceSetting('view_clip', false); UI.rfb.clipViewport = false; - } else if (isIOS() || isAndroid()) { - // iOS and Android usually have shit scrollbars + } else if (!hasScrollbarGutter) { + // Some platforms have scrollbars that are difficult + // to use in our case, so we always use our own panning UI.forceSetting('view_clip', true); UI.rfb.clipViewport = true; } else { diff --git a/kasmweb/core/util/browser.js b/kasmweb/core/util/browser.js index 4b371e3..9a6d2c8 100644 --- a/kasmweb/core/util/browser.js +++ b/kasmweb/core/util/browser.js @@ -52,6 +52,31 @@ try { } export const supportsImageMetadata = _supportsImageMetadata; +let _hasScrollbarGutter = true; +try { + // Create invisible container + const container = document.createElement('div'); + container.style.visibility = 'hidden'; + container.style.overflow = 'scroll'; // forcing scrollbars + document.body.appendChild(container); + + // Create a div and place it in the container + const child = document.createElement('div'); + container.appendChild(child); + + // Calculate the difference between the container's full width + // and the child's width - the difference is the scrollbars + const scrollbarWidth = (container.offsetWidth - child.offsetWidth); + + // Clean up + container.parentNode.removeChild(container); + + _hasScrollbarGutter = scrollbarWidth != 0; +} catch (exc) { + Log.Error("Scrollbar test exception: " + exc); +} +export const hasScrollbarGutter = _hasScrollbarGutter; + export function isMac() { return navigator && !!(/mac/i).exec(navigator.platform); } @@ -67,10 +92,6 @@ export function isIOS() { !!(/ipod/i).exec(navigator.platform)); } -export function isAndroid() { - return navigator && !!(/android/i).exec(navigator.userAgent); -} - export function isSafari() { return navigator && (navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1);