From 9b579a8cbd28124b811d245f5c632ce092134a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Tue, 14 Feb 2023 21:20:05 +0100 Subject: [PATCH] Screen size sync (#23) * allow choosing any screen configuration. * add screen sync option. * round size to int. * lint. --- src/component/main.vue | 30 ++++++++++++++ src/component/types/state.ts | 1 + src/page/components/events.vue | 76 +++++++++++++++++++++++++++------- 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/src/component/main.vue b/src/component/main.vue index b0aae617..2d0c43df 100644 --- a/src/component/main.vue +++ b/src/component/main.vue @@ -92,6 +92,8 @@ import Screencast from './screencast.vue' import Cursors from './cursors.vue' + const SCREEN_SYNC_THROTTLE = 500 // wait 500ms before reacting to automatic screen size change + @Component({ name: 'neko-canvas', components: { @@ -189,6 +191,7 @@ rate: 30, }, configurations: [], + sync: false, }, session_id: null, sessions: {}, @@ -571,6 +574,32 @@ this.connection.websocket.send(EVENT.KEYBOARD_MODIFIERS, modifiers) } + @Watch('state.screen.sync') + onScreenSyncChange() { + if (this.state.screen.sync) { + this.syncScreenSize() + window.addEventListener('resize', this.syncScreenSize) + } else { + window.removeEventListener('resize', this.syncScreenSize) + } + } + + syncScreenSizeTimeout = 0 + public syncScreenSize() { + if (this.syncScreenSizeTimeout) { + window.clearTimeout(this.syncScreenSizeTimeout) + } + this.syncScreenSizeTimeout = window.setTimeout(() => { + this.syncScreenSizeTimeout = 0 + const { offsetWidth, offsetHeight } = this._component + this.setScreenSize( + Math.round(offsetWidth * window.devicePixelRatio), + Math.round(offsetHeight * window.devicePixelRatio), + 60, // TODO: make it configurable? + ) + }, SCREEN_SYNC_THROTTLE) + } + @Watch('state.screen.size') onResize() { const { width, height } = this.state.screen.size @@ -658,6 +687,7 @@ Vue.set(this.state.control, 'host_id', null) Vue.set(this.state.screen, 'size', { width: 1280, height: 720, rate: 30 }) Vue.set(this.state.screen, 'configurations', []) + Vue.set(this.state.screen, 'sync', false) Vue.set(this.state, 'session_id', null) Vue.set(this.state, 'sessions', {}) Vue.set(this.state, 'settings', { diff --git a/src/component/types/state.ts b/src/component/types/state.ts index ccffc2a1..ad727808 100644 --- a/src/component/types/state.ts +++ b/src/component/types/state.ts @@ -91,6 +91,7 @@ export interface Keyboard { export interface Screen { size: ScreenSize configurations: ScreenSize[] + sync: boolean } export interface ScreenSize { diff --git a/src/page/components/events.vue b/src/page/components/events.vue index 1e3f042d..a8ad0060 100644 --- a/src/page/components/events.vue +++ b/src/page/components/events.vue @@ -317,28 +317,38 @@ - + - - + :key="String(width) + 'x' + String(height) + '@' + String(rate)" + :value="String(width) + 'x' + String(height) + '@' + String(rate)" + /> + + + + + + screen.sync + +
+ {{ neko.state.screen.sync }} + +
screen.configurations Session is not admin. + screen.sync + Session is not admin. @@ -440,6 +450,13 @@ + + chaos monkey + + + + + @@ -521,6 +538,37 @@ } } + screenConfiguration = '' + setScreenConfiguration() { + let [width, height, rate] = this.screenConfiguration.split(/[@x]/) + this.neko.setScreenSize(parseInt(width), parseInt(height), parseInt(rate)) + } + + @Watch('neko.state.screen.size', { immediate: true }) + onScreenSizeChange(val: any) { + this.screenConfiguration = `${val.width}x${val.height}@${val.rate}` + } + + // fast cursor moving test + cursor_interval = null + cursorMovingToggle() { + if (this.cursor_interval === null) { + let len = this.neko.state.screen.size.width + + //@ts-ignore + this.cursor_interval = setInterval(() => { + let x = Math.floor(Math.random() * len) + let y = Math.floor(Math.random() * len) + + this.neko.control.move({ x, y }) + }, 10) + } else { + //@ts-ignore + clearInterval(this.cursor_interval) + this.cursor_interval = null + } + } + async updateSettings(settings: any) { try { await this.neko.room.settingsSet(settings)