From 376bfc04f478ecd57477d7e48c12aba4035e29f7 Mon Sep 17 00:00:00 2001 From: ShadowLarkens Date: Sun, 1 Jun 2025 12:22:44 -0700 Subject: [PATCH] Update tgui-core and some backend tgui stuff (#17778) * Update tgui-core and some backend tgui stuff * Fix digitigrade not showing in char menu --- code/__defines/tgui.dm | 10 ++++ code/modules/tgui/tgui.dm | 47 +++++++++++++------ code/modules/tgui/tgui_window.dm | 44 ----------------- tgui/packages/tgui-bench/package.json | 2 +- tgui/packages/tgui-panel/package.json | 2 +- tgui/packages/tgui-say/package.json | 2 +- tgui/packages/tgui/backend.ts | 25 ---------- .../bay_prefs/general/SubtabBody.tsx | 20 ++++---- tgui/packages/tgui/package.json | 2 +- tgui/yarn.lock | 16 +++---- 10 files changed, 63 insertions(+), 107 deletions(-) diff --git a/code/__defines/tgui.dm b/code/__defines/tgui.dm index 96664cf2b3..127f7859ec 100644 --- a/code/__defines/tgui.dm +++ b/code/__defines/tgui.dm @@ -28,6 +28,16 @@ "%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \ ) +/// Though not the maximum renderable ByondUis within tgui, this is the maximum that the server will manage per-UI +#define TGUI_MANAGED_BYONDUI_LIMIT 10 + +// These are defines instead of being inline, as they're being sent over +// from tgui-core, so can't be easily played with +#define TGUI_MANAGED_BYONDUI_TYPE_RENDER "renderByondUi" +#define TGUI_MANAGED_BYONDUI_TYPE_UNMOUNT "unmountByondUi" + +#define TGUI_MANAGED_BYONDUI_PAYLOAD_ID "renderByondUi" + /// Max length for Modal Input #define TGUI_MODAL_INPUT_MAX_LENGTH 1024 /// Max length for Modal Input for names diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index e2fd46c67d..e965b4f69b 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -37,8 +37,8 @@ var/datum/tgui_state/state = null /// Rate limit client refreshes to prevent DoS. COOLDOWN_DECLARE(refresh_cooldown) - /// Are byond mouse events beyond the window passed in to the ui - var/mouse_hooked = FALSE + /// The id of any ByondUi elements that we have opened + var/list/open_byondui_elements /// The map z-level to display. var/map_z_level = 1 /// The Parent UI @@ -50,6 +50,7 @@ /// If the window should be closed with other windows when requested var/closeable = TRUE + /** * public * @@ -128,8 +129,6 @@ window.send_message("update", get_payload( with_data = TRUE, with_static_data = TRUE)) - if(mouse_hooked) - window.set_mouse_macro() SStgui.on_open(src) return TRUE @@ -172,12 +171,29 @@ window.close(can_be_suspended, logout) src_object.tgui_close(user) SStgui.on_close(src) + + if(user.client) + terminate_byondui_elements() + state = null if(parent_ui) parent_ui.children -= src parent_ui = null qdel(src) +/** + * public + * + * Closes all ByondUI elements, left dangling by a forceful TGUI exit, + * such as via Alt+F4, closing in non-fancy mode, or terminating the process + * + */ +/datum/tgui/proc/terminate_byondui_elements() + set waitfor = FALSE + + for(var/byondui_element in open_byondui_elements) + winset(user.client, byondui_element, list("parent" = "")) + /** * public * @@ -188,17 +204,6 @@ /datum/tgui/proc/set_autoupdate(autoupdate) src.autoupdate = autoupdate -/** - * public - * - * Enable/disable passing through byond mouse events to the window - * - * required value bool Enable/disable hooking. - */ -/datum/tgui/proc/set_mouse_hook(value) - src.mouse_hooked = value - //Handle unhooking/hooking on already open windows ? - /** * public * @@ -422,6 +427,18 @@ log_tgui(user, "Fallback Triggered: [href_list["payload"]], Window: [window.id], Source: [src_object]") #endif src_object.tgui_fallback(payload) + if(TGUI_MANAGED_BYONDUI_TYPE_RENDER) + var/byond_ui_id = payload[TGUI_MANAGED_BYONDUI_PAYLOAD_ID] + if(!byond_ui_id || LAZYLEN(open_byondui_elements) > TGUI_MANAGED_BYONDUI_LIMIT) + return + + LAZYOR(open_byondui_elements, byond_ui_id) + if(TGUI_MANAGED_BYONDUI_TYPE_UNMOUNT) + var/byond_ui_id = payload[TGUI_MANAGED_BYONDUI_PAYLOAD_ID] + if(!byond_ui_id) + return + + LAZYREMOVE(open_byondui_elements, byond_ui_id) /// Wrapper for behavior to potentially wait until the next tick if the server is overloaded /datum/tgui/proc/on_act_message(act_type, payload, state) diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm index 06ebd09478..38675b150d 100644 --- a/code/modules/tgui/tgui_window.dm +++ b/code/modules/tgui/tgui_window.dm @@ -27,19 +27,6 @@ var/initial_inline_css var/list/oversized_payloads = list() - var/mouse_event_macro_set = FALSE - - /** - * Static list used to map in macros that will then emit execute events to the tgui window - * A small disclaimer though I'm no tech wiz: I don't think it's possible to map in right or middle - * clicks in the current state, as they're keywords rather than modifiers. - */ - var/static/list/byondToTguiEventMap = list( - "MouseDown" = "byond/mousedown", - "MouseUp" = "byond/mouseup", - "Ctrl" = "byond/ctrldown", - "Ctrl+UP" = "byond/ctrlup", - ) /** * public @@ -235,8 +222,6 @@ /datum/tgui_window/proc/close(can_be_suspended = TRUE) if(!client) return - if(mouse_event_macro_set) - remove_mouse_macro() if(can_be_suspended && can_be_suspended()) #ifdef TGUI_DEBUGGING log_tgui(client, "[id]/close: suspending") @@ -441,32 +426,3 @@ /datum/tgui_window/proc/remove_oversized_payload(payload_id) oversized_payloads -= payload_id - - -/datum/tgui_window/proc/set_mouse_macro() - if(mouse_event_macro_set) - return - - for(var/mouseMacro in byondToTguiEventMap) - var/command_template = ".output CONTROL PAYLOAD" - var/event_message = TGUI_CREATE_MESSAGE(byondToTguiEventMap[mouseMacro], null) - var target_control = is_browser \ - ? "[id]:update" \ - : "[id].browser:update" - var/with_id = replacetext(command_template, "CONTROL", target_control) - var/full_command = replacetext(with_id, "PAYLOAD", event_message) - - var/list/params = list() - params["parent"] = "default" //Technically this is external to tgui but whatever - params["name"] = mouseMacro - params["command"] = full_command - - winset(client, "[mouseMacro]Window[id]Macro", params) - mouse_event_macro_set = TRUE - -/datum/tgui_window/proc/remove_mouse_macro() - if(!mouse_event_macro_set) - stack_trace("Unsetting mouse macro on tgui window that has none") - for(var/mouseMacro in byondToTguiEventMap) - winset(client, null, "[mouseMacro]Window[id]Macro.parent=null") - mouse_event_macro_set = FALSE diff --git a/tgui/packages/tgui-bench/package.json b/tgui/packages/tgui-bench/package.json index 674ba315bb..71d1b8a09b 100644 --- a/tgui/packages/tgui-bench/package.json +++ b/tgui/packages/tgui-bench/package.json @@ -11,7 +11,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^4.0.1" + "tgui-core": "^4.0.2" }, "devDependencies": { "@types/react": "^19.1.0", diff --git a/tgui/packages/tgui-panel/package.json b/tgui/packages/tgui-panel/package.json index 15b171b3d7..c78d06f6da 100644 --- a/tgui/packages/tgui-panel/package.json +++ b/tgui/packages/tgui-panel/package.json @@ -8,7 +8,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^4.0.1", + "tgui-core": "^4.0.2", "tgui-dev-server": "workspace:*" }, "devDependencies": { diff --git a/tgui/packages/tgui-say/package.json b/tgui/packages/tgui-say/package.json index bb1cb416e4..ea06a4ef03 100644 --- a/tgui/packages/tgui-say/package.json +++ b/tgui/packages/tgui-say/package.json @@ -7,7 +7,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^4.0.1" + "tgui-core": "^4.0.2" }, "devDependencies": { "@types/react": "^19.1.0", diff --git a/tgui/packages/tgui/backend.ts b/tgui/packages/tgui/backend.ts index 09a8a4c49d..a18bbe4156 100644 --- a/tgui/packages/tgui/backend.ts +++ b/tgui/packages/tgui/backend.ts @@ -13,7 +13,6 @@ import { perf } from 'common/perf'; import { createAction } from 'common/redux'; -import { globalEvents } from 'tgui-core/events'; import type { BooleanLike } from 'tgui-core/react'; import { setupDrag } from './drag'; @@ -97,14 +96,6 @@ export const backendReducer = (state = initialState, action) => { }; } - if (type === 'byond/ctrldown') { - globalEvents.emit('byond/ctrldown'); - } - - if (type === 'byond/ctrlup') { - globalEvents.emit('byond/ctrlup'); - } - if (type === 'backend/suspendStart') { return { ...state, @@ -154,22 +145,6 @@ export const backendMiddleware = (store) => { return; } - if (type === 'byond/mousedown') { - globalEvents.emit('byond/mousedown'); - } - - if (type === 'byond/mouseup') { - globalEvents.emit('byond/mouseup'); - } - - if (type === 'byond/ctrldown') { - globalEvents.emit('byond/ctrldown'); - } - - if (type === 'byond/ctrlup') { - globalEvents.emit('byond/ctrlup'); - } - if (type === 'backend/suspendStart' && !suspendInterval) { logger.log(`suspending (${Byond.windowId})`); // Keep sending suspend messages until it succeeds. diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabBody.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabBody.tsx index a94ba59f61..f91020fcd0 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabBody.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabBody.tsx @@ -121,17 +121,15 @@ export const SubtabBody = (props: { ) : null} - { - - - - } + + +