mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 18:11:47 +00:00
Fix wonky window dragging when using fancy tgui in some special cases (#46111)
This pull request fixes the Issue #44038, where TGUI windows get stuck at the bottom of the screen in this very special case: Windows 10 taskbar is not located at the bottom of the screen (in my case, taskbar was on top); Fancy UI is enabled. This is because BYOND uses and reports only the "usable" screen resolution instead of an actual physical resolution [citation needed], and therefore window coordinate space is offset by 40px or more (a size of a Windows 10 taskbar), which causes that rapid uncontrolled propulsion of TGUI windows away from the taskbar. I also took the liberty to refactor some of the code in 'util/byond' to my liking and adding a few helper methods, including runCommand(command) and callByond(url, params) -> Promise. Promise-based interface is a first step to start using async/await and making more dynamic calls in tgui. Why It's Good For The Game Window dragging is now more robust with the (currently default) fancy TGUI. Code accounts for the screen space offset between BYOND and the in-game browser. Changelog cl fix: fixed wonky window dragging when using fancy tgui in some special cases /cl
This commit is contained in:
@@ -9,3 +9,7 @@ indent_size = 2
|
|||||||
|
|
||||||
[*.py]
|
[*.py]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
|
[/tgui/**/*.{js,styl,ract,json,html}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { UI_INTERACTIVE, UI_UPDATE, UI_DISABLED } from 'util/constants'
|
import { UI_INTERACTIVE, UI_UPDATE, UI_DISABLED } from 'util/constants'
|
||||||
import { href, winset } from 'util/byond'
|
import { href, winget, winset, runCommand } from 'util/byond'
|
||||||
import { drag } from 'util/dragresize'
|
import { drag } from 'util/dragresize'
|
||||||
|
|
||||||
component.exports = {
|
component.exports = {
|
||||||
@@ -15,6 +15,21 @@ component.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
oninit () {
|
oninit () {
|
||||||
|
// Calculate offset between the "browser's screen space" and
|
||||||
|
// "BYOND screen space".
|
||||||
|
// This is necessary, because Windows 10 taskbar decreases the effective
|
||||||
|
// height by about 40px. If taskbar is located at the top and you try
|
||||||
|
// to drag a TGUI window, it rapidly propels itself to the bottom of
|
||||||
|
// the screen and gets stuck.
|
||||||
|
// See: https://github.com/tgstation/tgstation/issues/44038
|
||||||
|
this.set('screenOffsetX', 0);
|
||||||
|
this.set('screenOffsetY', 0);
|
||||||
|
winget(this.get('config.window'), 'pos')
|
||||||
|
.then(pos => {
|
||||||
|
this.set('screenOffsetX', window.screenX - pos.x);
|
||||||
|
this.set('screenOffsetY', window.screenY - pos.y);
|
||||||
|
});
|
||||||
|
|
||||||
const ondrag = drag.bind(this)
|
const ondrag = drag.bind(this)
|
||||||
const onrelease = (event) => this.set({ drag: false, x: null, y: null })
|
const onrelease = (event) => this.set({ drag: false, x: null, y: null })
|
||||||
|
|
||||||
@@ -36,7 +51,7 @@ component.exports = {
|
|||||||
},
|
},
|
||||||
close () {
|
close () {
|
||||||
winset(this.get('config.window'), 'is-visible', false)
|
winset(this.get('config.window'), 'is-visible', false)
|
||||||
window.location.href = href({command: `uiclose ${this.get('config.ref')}`}, 'winset')
|
runCommand(`uiclose ${this.get('config.ref')}`)
|
||||||
},
|
},
|
||||||
minimize () {
|
minimize () {
|
||||||
winset(this.get('config.window'), 'is-minimized', true)
|
winset(this.get('config.window'), 'is-minimized', true)
|
||||||
|
|||||||
@@ -1,16 +1,70 @@
|
|||||||
const encode = encodeURIComponent
|
const encode = encodeURIComponent
|
||||||
|
|
||||||
// Helper to generate a BYOND href given 'params' as an object (with an optional 'url' for eg winset).
|
// Helper to generate a BYOND href given 'params' as an object
|
||||||
export function href (params = {}, url = '') {
|
// (with an optional 'url' for eg winset).
|
||||||
return `byond://${url}?` + Object.keys(params).map(key => `${encode(key)}=${encode(params[key])}`).join('&')
|
export const href = (url, params = {}) => {
|
||||||
}
|
return `byond://${url || ''}?`
|
||||||
|
+ Object.keys(params)
|
||||||
|
.map(key => `${encode(key)}=${encode(params[key])}`)
|
||||||
|
.join('&');
|
||||||
|
};
|
||||||
|
|
||||||
// Helper to make a BYOND ui_act() call on the UI 'src' given an 'action' and optional 'params'.
|
// Helper to make a BYOND ui_act() call on the UI 'src' given an 'action'
|
||||||
export function act (src, action, params = {}) {
|
// and optional 'params'.
|
||||||
window.location.href = href(Object.assign({ src, action }, params))
|
export const act = (src, action, params = {}) => {
|
||||||
|
window.location.href = href('', Object.assign({ src, action }, params))
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A high-level abstraction of BYJAX. Makes a call to BYOND and returns
|
||||||
|
* a promise, which (if endpoint has a callback parameter) resolves
|
||||||
|
* with the return value of that call.
|
||||||
|
*/
|
||||||
|
export const callByond = (url, params = {}) => {
|
||||||
|
// Create a callback array if it doesn't exist yet
|
||||||
|
window.byondCallbacks = window.byondCallbacks || [];
|
||||||
|
// Create a Promise and push its resolve function into callback array
|
||||||
|
const callbackIndex = window.byondCallbacks.length;
|
||||||
|
const promise = new Promise(resolve => {
|
||||||
|
// TODO: Fix a potential memory leak
|
||||||
|
window.byondCallbacks.push(resolve);
|
||||||
|
});
|
||||||
|
// Call BYOND client
|
||||||
|
window.location.href = href(url || '', Object.assign({}, params, {
|
||||||
|
callback: `byondCallbacks[${callbackIndex}]`,
|
||||||
|
}));
|
||||||
|
// Return promise (awaitable)
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const runCommand = command => callByond('winset', { command });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple debug print.
|
||||||
|
*
|
||||||
|
* TODO: Find a better way to debug print.
|
||||||
|
* Right now we just print into the game chat.
|
||||||
|
*/
|
||||||
|
export const debugPrint = (...args) => {
|
||||||
|
const str = args
|
||||||
|
.map(arg => {
|
||||||
|
if (typeof arg === 'string') {
|
||||||
|
return arg
|
||||||
}
|
}
|
||||||
|
return JSON.stringify(arg);
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
return runCommand('Me [debugPrint] ' + str);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const winget = (win, key) => {
|
||||||
|
return callByond('winget', { id: win, property: key })
|
||||||
|
.then(obj => obj[key]);
|
||||||
|
};
|
||||||
|
|
||||||
// Helper to make a BYOND winset() call on 'window', setting 'key' to 'value'
|
// Helper to make a BYOND winset() call on 'window', setting 'key' to 'value'
|
||||||
export function winset (win, key, value) {
|
export const winset = (win, key, value) => {
|
||||||
window.location.href = href({[`${win}.${key}`]: value}, 'winset')
|
window.location.href = href('winset', {
|
||||||
}
|
[`${win}.${key}`]: value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -22,8 +22,14 @@ export function drag (event) {
|
|||||||
if (!this.get('drag')) return
|
if (!this.get('drag')) return
|
||||||
|
|
||||||
if (this.get('x')) {
|
if (this.get('x')) {
|
||||||
let x = (event.screenX - this.get('x')) + window.screenLeft
|
let x = event.screenX
|
||||||
let y = (event.screenY - this.get('y')) + window.screenTop
|
- this.get('x')
|
||||||
|
+ window.screenLeft
|
||||||
|
- this.get('screenOffsetX')
|
||||||
|
let y = event.screenY
|
||||||
|
- this.get('y')
|
||||||
|
+ window.screenTop
|
||||||
|
- this.get('screenOffsetY')
|
||||||
if (this.get('config.locked')) ({x, y} = lock(x, y)) // Lock to primary monitor.
|
if (this.get('config.locked')) ({x, y} = lock(x, y)) // Lock to primary monitor.
|
||||||
winset(this.get('config.window'), 'pos', `${x},${y}`)
|
winset(this.get('config.window'), 'pos', `${x},${y}`)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user