From b0224d502aaefb7e43641ab6e5ddaba311c5a9d3 Mon Sep 17 00:00:00 2001 From: True Zhuanjia Date: Mon, 27 Apr 2026 23:15:08 +0800 Subject: [PATCH] button-combo available for folder --- VoidLink/Input/CommandManager.swift | 19 ++++++++++++++----- VoidLink/Input/OnScreenWidgetView.swift | 10 ++++++++-- VoidLink/Localization/Localizable.xcstrings | 8 ++++---- ...LayoutOnScreenControlsViewController.swift | 6 ++++-- .../ViewControllers/MainFrameViewController.m | 2 +- VoidLinkPreview/WidgetPickerView.swift | 12 ++++++------ 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/VoidLink/Input/CommandManager.swift b/VoidLink/Input/CommandManager.swift index d1baec87..07d83fab 100644 --- a/VoidLink/Input/CommandManager.swift +++ b/VoidLink/Input/CommandManager.swift @@ -162,11 +162,15 @@ import UIKit // @objc public static let specialGameWidgets: [String] = ["YSRSV", "YSLT", "YSRT", "YSRB", "YSB", "YSRT2", "YSRB2", "YSB2", "YSEM", "YSML", "YSMR", "YSWASD"] + @objc public static let shortcutAllowedFunctionalButtonMappings: [String: Int16] = [ + "BRUSH": 0xFF, + "ERASER": 0xFF, + "FOLDER": 0xFF, + ] + @objc public static let keyboardButtonMappings: [String: Int16] = [ // Windows Key Codes "NULL": 0xFF, - "BRUSH": 0xFF, - "ERASER": 0xFF, "CTRL": 0x11, // VK_CONTROL "RCTRL": 0xA3, // VK_RCONTROL "SHIFT": 0x10, // VK_SHIFT @@ -478,7 +482,8 @@ import UIKit @objc public func extractAutoReleaseButtonStrings(from cmd: String) -> [String]? { let cmd = cmd.uppercased() let mergedKeys = (Set(CommandManager.keyboardButtonMappings.keys) - .union(Set(CommandManager.mouseButtonMappings.keys))) + .union(Set(CommandManager.mouseButtonMappings.keys)) + .union(Set(CommandManager.shortcutAllowedFunctionalButtonMappings.keys))) let keys = mergedKeys.joined(separator: "|") let pattern = "^(?:(\(keys))(?:\\+(\(keys))*)*)$" @@ -505,7 +510,9 @@ import UIKit for key in keyStrings { if (CommandManager.keyboardButtonMappings.keys.contains(key) - || CommandManager.mouseButtonMappings.keys.contains(key)) { + || CommandManager.mouseButtonMappings.keys.contains(key) + || CommandManager.shortcutAllowedFunctionalButtonMappings.keys.contains(key) + ) { validKeyStrings.append(key) } else { print(" '\(key)' is not defined in key mappings") @@ -631,7 +638,9 @@ import UIKit @objc public func sendAutoReleaseComboCommand(cmdStrings: [String]?, delay: TimeInterval = 0.2, index: Int = 0, pressOnly: Bool = false, releaseOnly:Bool = false) { // we need a large delay for WAN streaming // 如果已处理完所有按键,则开始释放按键 - guard let cmdStrings = cmdStrings else { return } + guard var cmdStrings = cmdStrings else { return } + + cmdStrings = cmdStrings.filter { !CommandManager.shortcutAllowedFunctionalButtonMappings.keys.contains($0)} if releaseOnly { for keyStr in cmdStrings.reversed() { diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index 84bf585a..cda9f4f9 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -181,6 +181,7 @@ import ObjectiveC.runtime @objc public var isStickWheel: Bool = false @objc public var isFolder: Bool = false + @objc public var containsShortcutAction: Bool = false @objc public var hasNonEditableLabel: Bool = false // for all stick pads @@ -438,6 +439,9 @@ import ObjectiveC.runtime if self.cmdString.contains("ERASER"){ self.functionalButtonString = "ERASER" } + if self.cmdString.contains("FOLDER") { + self.functionalButtonString = "FOLDER" + } if self.isFunctionalButton { self.buttonMode = .movable if self.functionalButtonString == "PENCILHOVER" {self.buttonMode = .regular} @@ -517,8 +521,9 @@ import ObjectiveC.runtime self.hasWalkSprintKeys = self.isDirectionPad && (self.touchPadString == "WASDPAD" || self.touchPadString == "ARROWPAD") self.isStickWheel = self.widgetType == WidgetTypeEnum.touchPad && CommandManager.stickWheels.contains(self.touchPadString) - self.isFolder = self.cmdString == "FOLDER" - + self.isFolder = self.cmdString.contains("FOLDER") + self.containsShortcutAction = self.cmdString.contains("+") + self.hasComponent = self.isStickWheel self.hasL3R3Indicator = !self.isStickWheel && !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad @@ -2643,6 +2648,7 @@ import ObjectiveC.runtime break } } + switch self.functionalButtonString { case "FOLDER": self.folded = !self.folded diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index 216b63a3..b064f46b 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -2608,25 +2608,25 @@ } } }, - "Collect, fold & unfold other widgets or subfolders" : { + "Collect other widgets or subfolders. Button-combo available." : { "extractionState" : "manual", "localizations" : { "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "收纳、折叠和展开其他控件或子控件夹" + "value" : "收纳其他控件或子控件夹。允许组合其他按键。" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "收納、摺疊和展開其他控制項或子控制項夾" + "value" : "收納、摺疊其他控制項或子控制項夾。允許組合其他按鍵。" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "收納、摺疊和展開其他控制項或子控制項夾" + "value" : "收納、摺疊其他控制項或子控制項夾。允許組合其他按鍵。" } } } diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift index 191db307..ae5bdb71 100644 --- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift +++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift @@ -948,8 +948,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg buttonModeStack.isHidden = widgetView.widgetType != .button buttonModeSelector.setEnabled(!widgetView.isFunctionalButton, forSegmentAt: Int(ButtonMode.slideToToggle.rawValue)) - buttonModeSelector.setEnabled(!widgetView.isFunctionalButton || widgetView.isFolder, forSegmentAt: Int(ButtonMode.slideAndHold.rawValue)) - buttonModeSelector.setEnabled(!widgetView.isFolder, forSegmentAt: Int(ButtonMode.regular.rawValue)) + buttonModeSelector.setEnabled((!widgetView.isFunctionalButton || widgetView.isFolder) + && !widgetView.containsShortcutAction + , forSegmentAt: Int(ButtonMode.slideAndHold.rawValue)) + // buttonModeSelector.setEnabled(!widgetView.isFolder, forSegmentAt: Int(ButtonMode.regular.rawValue)) buttonModeSelector.setEnabled(!widgetView.isFunctionalButton || widgetView.isTapToToggleException, forSegmentAt: Int(ButtonMode.tapToToggle.rawValue)) buttonModeSelector.selectedSegmentIndex = Int(widgetView.buttonMode.rawValue) diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index c09cf510..a1ae934e 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -1717,7 +1717,7 @@ static NSMutableSet* hostList; settings.sdrPerformanceWorkaround = true; settings.framePacingMode = @(FramePacingModeQueue); settings.asyncFrameDequeue = false; - settings.touchMoveEventInterval = @(45); + settings.touchMoveEventInterval = @(0); break; case UIUserInterfaceIdiomPad: default: diff --git a/VoidLinkPreview/WidgetPickerView.swift b/VoidLinkPreview/WidgetPickerView.swift index 9acafab2..2d337804 100644 --- a/VoidLinkPreview/WidgetPickerView.swift +++ b/VoidLinkPreview/WidgetPickerView.swift @@ -521,11 +521,11 @@ struct WidgetPickerView: View { FunctionalButtonOption( label: SwiftLocalizationHelper.localizedString(forKey: "Folder"), cmd: "FOLDER", - tip: SwiftLocalizationHelper.localizedString(forKey: "Collect, fold & unfold other widgets or subfolders"), - allowsKeyboardCombination: false, - allowsGamepadCombination: false, - allowsSkillCombo: false, - allowsShortcutCombo: false, + tip: SwiftLocalizationHelper.localizedString(forKey: "Collect other widgets or subfolders. Button-combo available."), + allowsKeyboardCombination: true, + allowsGamepadCombination: true, + allowsSkillCombo: true, + allowsShortcutCombo: true, forcedComboMode: nil ), FunctionalButtonOption( @@ -2049,7 +2049,7 @@ struct WidgetPickerView: View { } private func submitWidgetPayload() { - var payload = makeWidgetPayload() + let payload = makeWidgetPayload() persistCurrentTabSelection() lastCreatedWidgetPayload = payload setTipMessage(SwiftLocalizationHelper.localizedString(forKey: "Widget config generated"))