Screen size sync (#23)

* allow choosing any screen configuration.

* add screen sync option.

* round size to int.

* lint.
This commit is contained in:
Miroslav Šedivý 2023-02-14 21:20:05 +01:00 committed by GitHub
parent ae80753378
commit 9b579a8cbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 14 deletions

View File

@ -92,6 +92,8 @@
import Screencast from './screencast.vue' import Screencast from './screencast.vue'
import Cursors from './cursors.vue' import Cursors from './cursors.vue'
const SCREEN_SYNC_THROTTLE = 500 // wait 500ms before reacting to automatic screen size change
@Component({ @Component({
name: 'neko-canvas', name: 'neko-canvas',
components: { components: {
@ -189,6 +191,7 @@
rate: 30, rate: 30,
}, },
configurations: [], configurations: [],
sync: false,
}, },
session_id: null, session_id: null,
sessions: {}, sessions: {},
@ -571,6 +574,32 @@
this.connection.websocket.send(EVENT.KEYBOARD_MODIFIERS, modifiers) 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') @Watch('state.screen.size')
onResize() { onResize() {
const { width, height } = this.state.screen.size const { width, height } = this.state.screen.size
@ -658,6 +687,7 @@
Vue.set(this.state.control, 'host_id', null) 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, 'size', { width: 1280, height: 720, rate: 30 })
Vue.set(this.state.screen, 'configurations', []) Vue.set(this.state.screen, 'configurations', [])
Vue.set(this.state.screen, 'sync', false)
Vue.set(this.state, 'session_id', null) Vue.set(this.state, 'session_id', null)
Vue.set(this.state, 'sessions', {}) Vue.set(this.state, 'sessions', {})
Vue.set(this.state, 'settings', { Vue.set(this.state, 'settings', {

View File

@ -91,6 +91,7 @@ export interface Keyboard {
export interface Screen { export interface Screen {
size: ScreenSize size: ScreenSize
configurations: ScreenSize[] configurations: ScreenSize[]
sync: boolean
} }
export interface ScreenSize { export interface ScreenSize {

View File

@ -317,28 +317,38 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<select <input
:value="Object.values(neko.state.screen.size).join()" list="screen-configuration"
@input=" v-model="screenConfiguration"
a = String($event.target.value).split(',') style="width: 100%; box-sizing: border-box"
neko.setScreenSize(parseInt(a[0]), parseInt(a[1]), parseInt(a[2])) />
" <datalist id="screen-configuration">
>
<option <option
v-for="{ width, height, rate } in neko.state.screen.configurations" v-for="{ width, height, rate } in neko.state.screen.configurations"
:key="String(width) + String(height) + String(rate)" :key="String(width) + 'x' + String(height) + '@' + String(rate)"
:value="[width, height, rate].join()" :value="String(width) + 'x' + String(height) + '@' + String(rate)"
> />
{{ width }}x{{ height }}@{{ rate }} </datalist>
</option> <button @click="setScreenConfiguration">set</button>
</select> </td>
<button @click="screenChangingToggle">screenChangingToggle</button> </tr>
<tr>
<th class="middle">screen.sync</th>
<td>
<div class="space-between">
<span>{{ neko.state.screen.sync }}</span>
<button @click="neko.state.screen.sync = !neko.state.screen.sync">
<i class="fas fa-toggle-on"></i>
</button>
</div>
</td> </td>
</tr> </tr>
</template> </template>
<tr v-else> <tr v-else>
<th>screen.configurations</th> <th>screen.configurations</th>
<td>Session is not admin.</td> <td>Session is not admin.</td>
<th>screen.sync</th>
<td>Session is not admin.</td>
</tr> </tr>
<tr> <tr>
@ -440,6 +450,13 @@
</div> </div>
</td> </td>
</tr> </tr>
<tr>
<th>chaos monkey</th>
<td>
<button @click="cursorMovingToggle">cursor moving</button>
<button @click="screenChangingToggle">screen cfg changing</button>
</td>
</tr>
</table> </table>
</div> </div>
</template> </template>
@ -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) { async updateSettings(settings: any) {
try { try {
await this.neko.room.settingsSet(settings) await this.neko.room.settingsSet(settings)