Releases: ZhiHanyu-H57/InputStitch
Release list
Input Lab v0.3.0
Input Lab v0.3.0
Input Lab v0.3.0 makes the manual black-box tester much easier to use and adds a missing observation lane.
What changed
- Added a target-window Win32 message lane for keyboard and mouse (
WM_KEY*/WM_MOUSE*). This shows whether Input Lab itself, including focused child controls, actually received a normal window message. - Kept the existing low-level hook, Raw Input and XInput lanes so the same input can be compared across APIs.
- Redesigned the keyboard view into a larger six-row layout that uses substantially more of the window and places navigation/arrow keys in more familiar positions.
- Increased keycap size and contrast.
- Fixed the practical visibility problem where a quick tap could change to the active color and return to idle too quickly to see. Held keys remain strongly highlighted; releases now retain a 180 ms visual afterglow.
- Added independent
0.3.0file/product version metadata. - Added built-in self-tests for target-window message observation and keyboard highlight behavior.
- Added a packaging script that creates a standalone x64 EXE, ZIP and SHA-256 checksums.
Scope and limitations
Input Lab is still a developer/test utility, not a game input emulator. It observes low-level hooks, Raw Input, ordinary target-window messages and XInput, but it does not yet emulate or observe DirectInput/HID/DS4, GameInput, anti-cheat behavior, privilege-boundary behavior, exclusive-fullscreen behavior or game-specific input stacks.
InputStitch 1.4.1
InputStitch 1.4.1
概要
这是 1.4.0 的界面稳定性修复版:修复“管理映射层”弹出菜单关闭时过早释放 ContextMenuStrip,导致 WinForms 在菜单点击收尾阶段抛出 ObjectDisposedException 的问题。
1.4.1 不新增功能、不修改配置格式,也不改变 1.4.0 的手柄、Layer、宏并发或更新策略。
修复内容
1. 映射层管理菜单不再在 Closed 事件里同步释放
1.4.0 的“管理映射层”使用临时 ContextMenuStrip。菜单关闭时,旧代码会直接在 Closed 回调中执行 Dispose()。
但 WinForms 在触发 Closed 后仍可能继续执行当前菜单点击的内部收尾流程,例如 ToolStripDropDown.OnItemClicked、SetVisibleCore 和 ModalMenuFilter。这时对象已经被 InputStitch 提前释放,就会出现:
System.ObjectDisposedException: 无法访问已释放的对象。
对象名:“ContextMenuStrip”。
1.4.1 改为:
Closed发生时不立即 Dispose;- 通过 UI dispatcher 把释放动作排到下一轮 Windows 消息循环;
- 当前 ToolStrip 点击/关闭流程先完整结束,再释放临时菜单。
“快速创建”菜单也统一使用同一个延迟释放辅助函数,避免两套生命周期规则重新分叉。
2. 主窗口关闭时不再同步 Dispose 可能仍活跃的菜单
如果程序关闭动作恰好由菜单项触发,WinForms 的 ModalMenuFilter 在点击处理完全返回前仍可能保存对该下拉菜单的引用。
1.4.1 因此在主窗口退出清理阶段不再主动同步 Dispose() toolsMenu / trayMenu;程序正在退出,直接放弃应用层引用比在 ToolStrip 内部仍可能使用它们时强制销毁更安全。
回归验证
UI Safety/Diagnostics 专项从 23 项增加到 26 项,新增验证:
- ContextMenuStrip 的释放不会发生在当前 ToolStrip 事件内;
- 下一轮 UI 消息处理后才完成释放;
- dispatcher 已经释放时不会退化成同步销毁菜单。
完整回归、x64/x86 Release Verification、Stable 更新清单和 GitHub Windows CI 仍是 1.4.1 发布门槛。
其他说明
用户日志里更早出现过 1.3.0 的 Nefarius.ViGEm.Client FileNotFoundException。检查确认旧 1.3.0 备份和当前 1.4.x EXE 都实际内嵌了 InputStitch.ThirdParty.Nefarius.ViGEm.Client.dll,隔离探针也能成功执行 EmbeddedDependencyLoader.Register → GamepadOutput.NeutralizeAll。目前无法在 1.4.x 复现该程序集解析错误,因此 1.4.1 不对依赖加载器做未经证实的改动;后续如果再次出现会继续按独立问题调查。
English summary
InputStitch 1.4.1 is a UI-stability hotfix for 1.4.0. It fixes premature ContextMenuStrip disposal in Mapping Layer management, which could raise ObjectDisposedException while WinForms was still completing the current ToolStrip click/close sequence.
Changes:
- transient context menus are disposed on the next UI message turn instead of synchronously from
Closed; - Quick Create and Layer Management now share the same deferred-disposal rule;
- shutdown no longer synchronously disposes tools/tray context menus that may still be referenced by WinForms'
ModalMenuFilter; - no feature or configuration-format changes from 1.4.0;
- UI Safety/Diagnostics coverage increases from 23 to 26 checks.
InputStitch 1.4.0
InputStitch 1.4.0
概要
1.4.0 把 1.3.1 Beta 线里已经验证的手柄输入/路由、多映射层、运行观察、更新与配置安全能力正式纳入 Stable;实验性手柄接管继续保留,但仍明确标记为 Experimental。
这是从 v1.3.0 升级而来的新 minor release。它不是单纯修补几个问题,而是把键盘、鼠标和手柄输入进一步统一到同一套并发、可观察、可恢复的输入编排平台中。
主要变化
1. XInput 手柄成为正式输入来源
Windows 可见的 Xbox 兼容手柄现在可以直接作为宏触发来源:
- 正面按键、方向键、肩键、菜单键、摇杆按下;
- LT / RT 扳机;
- 按住类宏会记住真正启动它的那只手柄,另一只手柄松开同名按键不会误停止。
手柄触发仍然复用同一套宏执行系统,所以可以输出:
- 键盘;
- 鼠标;
- 虚拟手柄;
- 键盘 + 鼠标 + 手柄混合操作。
2. 多个外部 XInput 手柄可以汇总到 InputStitch 虚拟 Xbox
Router 会把每只外部 XInput 手柄作为独立来源送入 Output Ownership:
- 按键可以共同保持;
- 扳机按确定规则合并;
- 摇杆使用向量合并/归一化;
- 某一只手柄松开、回中或断开,只删除这一只手柄自己的贡献。
Router 本身并不隐藏原手柄,所以默认仍属于“汇总/增强”,不是拦截。
3. 可以完全不创建虚拟手柄
“虚拟手柄类型”新增:
不创建虚拟手柄 / Do not create a virtual controller
选择后:
- 键盘/鼠标宏仍然可用;
- 实体/其他 XInput 手柄仍可作为键鼠宏触发来源;
- 编辑手柄输出步骤不会因为保存配置而偷偷创建 ViGEm;
- 真正要求虚拟手柄输出的功能会明确拒绝,而不是静默覆盖用户偏好。
4. 映射层升级为任意多个可命名 Layer
基础层始终有效;除此之外可以创建任意多个自定义层。
支持:
- 新增、重命名、删除 Layer;
- 所有宏类型都可以分层;
- 每个 Layer(包括基础层)都能绑定键盘、鼠标或手柄快捷切换;
- 删除 Layer 时其中的宏安全移回基础层;
- 删除当前活动层时先回到“仅基础层”;
- 切层只停止旧层自己的运行来源,不误伤基础层或其他仍有效来源;
- 新层中原本已经按住的触发必须先松开再重新按,避免切层瞬间误触发。
同时修复了旧“映射层 1”删除后重启又自动出现的问题。新版 XML 中,明确保存的 Layer 列表就是权威数据;真正的旧配置仍能兼容迁移。
5. 并发宏继续使用统一 Output Ownership
1.4.0 继承并继续稳定使用 1.3.0 的并发架构:
- 多个普通时序宏;
- 多个 Toggle;
- 多个复杂 Hold;
- 多个轻量持续按住映射;
- Router、Idle 和宏输出;
都通过独立 SourceId / ownership 合并。
一个来源结束只释放自己的贡献,不会把另一个来源正在保持的键、鼠标或手柄状态一起清掉。
6. 运行观察和诊断更完整
运行观察/诊断现在能直接看到:
- 活动宏及 RunId / SourceId;
- 当前 step / phase / stop reason;
- 当前 Layer 名称;
- 活跃输出来源与 merged output;
- 虚拟 Xbox 当前槽位;
- Router 状态;
- 实验性接管状态;
- 健康监控最近结果、连续失败次数与恢复状态。
诊断本身不会为了“查看状态”而创建虚拟手柄。
7. 实验性 Controller Takeover 保留,但不宣称硬件成熟
工具 → 手柄接管(实验) 继续存在。
当前已实现:
- 在任何 HidHide 隐藏前先安全取得并硬验证 XInput 0 号槽位;
- 临时槽位重排与 HidHide 隐藏各自有独立恢复事务;
- 只隐藏用户明确选择的外部设备;
- 任一步失败都在隐藏前 fail closed 或尝试回滚;
- 崩溃恢复 journal;
- 接管运行期间持续检查槽位、Router、预期 XInput 来源、HidHide cloak/hidden-device/application whitelist;
- 一次瞬时失败容忍,连续两次失败才触发一次 fail-safe disengage;
- 确认失效后恢复 InputStitch 自己造成的隐藏变化、停止 Router 并清理受管输出,避免原输入 + 路由输入双份发送。
仍未完成的是实体手柄 + HidHide + 实际游戏的最终硬件验收。 当前开发机没有实体 XInput 测试手柄,因此 1.4.0 Stable 仍把这一入口明确标为 Experimental,而不会把它宣传成已完全验证的“手柄接管正式能力”。
8. 更新器的断网行为更安全
正式版自动更新现在对临时网络故障有明确边界:
- 请求有有限的无响应超时;
- 连接/DNS/接收中断等临时网络错误最多重试 2 次;
- 每次重试前删除上一轮半包;
- 三次都失败后不会写安装事务、不会关闭旧版、不会留下可执行半包;
- 完整下载并通过 SHA-256 + 产品/版本校验后,后续安装完全本地进行,之后断网不影响替换。
9. 配置保存和备份继续加固
配置保存继续采用 staged write + validate + replace,不做“先删旧文件再写新文件”。
同时修复快速连续保存时的备份排序边界问题:即使 Windows 墙钟分辨率很粗、连续保存看到相同时间、系统时钟短暂回拨或程序重启,也会稳定保留真正最近的 5 个有效配置备份,而不是让随机 GUID 决定新旧顺序。
自动验证
1.4.0 发布候选要求完整通过:
- 323 项键盘/触发检查;
- 58 项 Idle Gamepad 检查;
- 26 项 XInput 输入检查;
- 28 项 Gamepad Router 检查;
- 52 项 Controlled Replacement 事务/健康/恢复检查;
- 27 项槽位取得/PnP 恢复检查;
- 15 项“不创建虚拟手柄”偏好检查;
- 39 项 Layer/XML/运行观察检查;
- 7 项宏计时检查;
- 43 项更新安装/回滚检查;
- 18 项更新网络中断/重试检查;
- 23 项 UI 安全/诊断检查;
- 360 项配置/易用性检查;
- 303,716 项 Output Ownership / 并发合并检查;
- 中英文设置窗口、旧 XML 和手柄向量编辑冒烟检查。
Input Lab 现有真实键鼠/并发 lane 为:
18 PASS / failures=0
之后仍会在本开发机的已知 ViGEm→XInput 环境预检处报告 BLOCKED;这不是产品断言失败,也不会被伪装成实体手柄验收。
四槽位中立 ViGEm 探针已验证:
外部 0/1/2 + InputStitch 3 → InputStitch 0 + 外部 1/2/3
它只证明真实 Windows/ViGEm 槽位重新枚举顺序,不替代实体手柄 + HidHide + 游戏验收。
发布文件
InputStitch-1.4.0-Windows-x64.exeInputStitch-1.4.0-Windows-x86.exeInputStitch-1.4.0-Source.zipInputStitch-update.xmlSHA256SUMS.txt
English summary
InputStitch 1.4.0 promotes the validated controller-input/routing and flexible-Layer work from the 1.3.1 Beta line into Stable, while keeping controller takeover explicitly Experimental until physical-controller + HidHide + target-game acceptance is available.
Highlights:
- XInput controller buttons/triggers can start the same keyboard, mouse, virtual-controller and hybrid macros as other triggers.
- Multiple external XInput controllers can route into one InputStitch virtual Xbox through the existing deterministic Output Ownership merge model.
- Virtual-controller creation can be disabled completely for keyboard/mouse-only workflows.
- Base + arbitrary named mapping layers are supported, with keyboard/mouse/controller switch bindings and safe source-local cleanup on layer changes.
- Runtime Observation/diagnostics expose macro runs, sources, merged output, active layer, virtual slot, Router, takeover health and recovery state.
- Stable update downloads now have bounded network retries/timeout behavior and partial-download cleanup.
- Configuration backup ordering is deterministic even under same-clock rapid saves, clock rollback and restart.
- Controller takeover remains Experimental. Slot acquisition, HidHide transaction/rollback, crash recovery and runtime health monitoring are implemented, but final physical-controller + HidHide + real-game acceptance remains pending.
InputStitch 1.3.1-beta.2 (Beta)
InputStitch 1.3.1-beta.2
概要
现在映射层可以自由新增、命名、删除和设置快捷切换;实验性手柄接管也会在运行中持续自检,发现关键状态异常时自动退出接管并尝试恢复原手柄。
这是基于 v1.3.1-beta.1 继续开发的测试版。它不会替换正式版 v1.3.0,也不会修改正式版的自动更新通道。
这次最主要的变化
1. 映射层不再只有“基础层 + 映射层 1”
现在可以在主界面的“管理映射层”中:
- 新增任意数量的映射层;
- 给每个层起自己的名字;
- 重命名已有层;
- 删除不再需要的层;
- 为每个层设置切换快捷键;
- 给基础层本身设置“回到仅基础层”的快捷键。
每一个宏都可以选择属于哪个层,包括普通时序宏、按一次启动/停止的宏、复杂按住宏和轻量持续按住映射。
基础层始终有效;除此之外当前仍一次只激活一个额外层。切换层时,旧层正在运行的宏会停止,而且只释放旧层自己的输出。基础层和其他仍有效来源不会被误伤。
如果切入新层时某个触发键本来就已经按着,InputStitch 不会因为键盘自动重复或手柄轮询而突然启动宏;必须先松开,再重新按下。
2. Layer 可以用键盘、鼠标或手柄快捷切换
每个层都可以录制自己的切换方式,使用的是 InputStitch 已有的统一触发系统,因此可以是:
- 键盘键或组合键;
- 鼠标按钮;
- 手柄按键;
- 手柄扳机。
层切换本身不创建第二套宏执行器。它只改变“哪些宏当前有资格被触发”,之后仍然使用同一套并发运行、输出合并、停止和释放机制。
3. 删除 Layer 后不会再在重启时“自己复活”
开发中发现并修复了一个实际配置问题:旧的 XML 反序列化方式会先构造默认的“基础层 + 映射层 1”,再把保存文件里的层追加进去。因此即使用户已经删除“映射层 1”,重新启动后它仍有可能再次出现。
现在 Layer 列表使用替换式 XML 序列化:
- 真正的旧配置里完全没有 Layer 数据时,仍自动迁移为“基础层 + 映射层 1”;
- 新版配置一旦已经保存 Layer 列表,文件里的列表就是权威数据;
- 用户删除“映射层 1”后,保存、退出、重新启动,它不会再被默认值偷偷创建回来;
- 用户删除某个自定义层时,其中的宏会安全移回基础层,不会留下失效的层 ID。
这条行为已经用真实的 XML 保存 → 重新加载往返测试锁住。
4. 实验性手柄接管现在会持续自检
v1.3.1-beta.1 已经能在进入 HidHide 隐藏之前安全取得 XInput 0 号槽位,并在失败时回滚。beta.2 继续补上“接管已经运行以后怎么办”。
接管激活后,InputStitch 会在后台持续检查:
- InputStitch 虚拟 Xbox 是否仍然在目标 0 号槽位;
- 手柄汇总 Router 是否仍然就绪;
- 接管前记录的外部 XInput 来源是否仍然能被 InputStitch 自己读取;
- HidHide 总隐藏开关是否仍然开启;
- 用户选择接管的原手柄是否仍在隐藏列表;
- InputStitch 自己是否仍在 HidHide 应用白名单中。
这些检查不放在 10 ms 的 UI/手柄轮询线程里,避免 HidHide CLI 或设备枚举拖慢界面。健康检查在后台运行。
一次瞬时失败不会立即退出接管;当前需要连续两次检查失败才确认异常,减少设备枚举短暂抖动造成的误判。
5. 接管健康异常会自动脱离,而不是继续带病运行
如果连续健康检查确认异常,InputStitch 会:
- 停止健康监控,避免重复恢复;
- 调用接管事务恢复 InputStitch 自己造成的 HidHide 隐藏、总开关和白名单变化;
- 停止手柄汇总 Router;
- 清理 Router/宏当前持有的受管输出并让虚拟手柄回到中立;
- 把“手柄汇总”配置关闭,避免原手柄重新可见后又同时发送一份聚合输出,造成双输入;
- 记录明确的运行日志和状态提示。
如果恢复本身失败,恢复日志会继续保留,下次启动仍会尝试恢复,并向用户显示警告。
6. 运行观察和诊断信息更完整
“工具 → 运行观察”现在会直接显示:
- 当前活动映射层的用户名称;
- InputStitch 虚拟 Xbox 当前槽位;
- 手柄汇总是否开启、当前路由了几个来源;
- 手柄接管当前状态;
- 接管健康监控是否正在运行;
- 最近一次健康检查结果;
- 连续失败次数;
- 接管事务预期仍可见的 XInput 来源。
详细诊断信息还会列出:
- 每一个映射层的 ID、名称和切换快捷键;
- 接管恢复日志状态;
- 0 号槽位取得恢复日志状态;
- Router、接管和健康监控的内部状态。
诊断本身不会为了“查看状态”而创建或连接虚拟手柄。隔离测试宿主也不会因为打开运行观察而加载 ViGEm。
7. 配置备份在快速连续保存时也会稳定保留真正最近的版本
GitHub Windows runner 在发布验证中暴露出一个原有边界问题:Windows 的墙钟分辨率可能让多个极快连续保存得到完全相同的时间串。旧备份名在这种情况下只能靠后面的随机 GUID 区分,而清理逻辑又按文件名排序,因此“最近 5 个”可能偶尔删错一个较新的版本。
现在有效配置备份使用严格单调递增的排序时间戳。生成新备份名时会同时考虑当前 UTC、本进程刚分配过的最新时间以及备份目录中现存的最新时间,因此即使系统时钟粒度较粗、短暂回拨或程序重新启动,也不会让随机 GUID 决定备份新旧顺序。
自动测试会故意把连续保存的墙钟时间冻结成完全相同的值,确认仍只保留正确的最近 5 个版本。
beta.1 已有能力继续保留
本版本继续包含 v1.3.1-beta.1 的这些能力:
- 用可见 XInput 手柄按键/扳机直接触发宏;
- 把手柄输入转换成键盘、鼠标、虚拟手柄或混合操作;
- 把多个其他可见 XInput 手柄汇总到 InputStitch 自己的虚拟 Xbox;
- 设置中可以选择“不创建虚拟手柄”;
- 实验性接管在任何 HidHide 隐藏之前先安全取得并硬验证 XInput 0 号槽位;
- 临时槽位重排和 HidHide 隐藏使用独立的恢复事务;
- 更新器在检查/下载阶段遇到临时断网会有限重试,半包不会进入安装事务;完整下载并验证之后的安装完全离线完成。
仍然没有完成的硬件验收
当前开发机没有实体 XInput 手柄,也没有 HidHide 环境,因此:
“实体手柄 + HidHide + 实际游戏最终只看到 InputStitch 的受控 0 号虚拟手柄”仍然没有真实硬件验收。
这个限制不会用更多 ViGEm 虚拟手柄伪装成“实体设备验收完成”。已有四槽位中立 ViGEm 探针只证明 Windows/ViGEm 的槽位重新枚举顺序:
外部 0/1/2 + InputStitch 3 → InputStitch 0 + 外部 1/2/3
等以后有实体手柄时再补最终 HidHide + 游戏测试。
自动测试
本版本在发布前要求至少通过:
- 323 项键盘与触发测试;
- 58 项闲置手柄测试;
- 26 项 XInput 输入测试;
- 28 项多手柄汇总测试;
- 52 项接管安全 / 运行健康测试;
- 27 项 0 号槽位取得与恢复测试;
- 15 项“不创建虚拟手柄”偏好测试;
- 39 项 Layer / 多层 / XML 往返 / 运行观察测试;
- 7 项宏计时测试;
- 43 项更新安装测试;
- 18 项更新网络中断/重试测试;
- 23 项界面安全与诊断测试;
- 360 项配置与易用性测试;
- 303,716 项输出合并与并发运行测试;
- 中英文设置界面与旧 XML 配置冒烟测试。
自动测试使用注入状态或假后端,不会为了测试接管而禁用真实设备或调用真实 HidHide。
发布文件
InputStitch-1.3.1-beta.2-Windows-x64.exeInputStitch-1.3.1-beta.2-Windows-x86.exeInputStitch-1.3.1-beta.2-Source.zipInputStitch-beta.xmlSHA256SUMS.txt
English summary
Mapping layers can now be freely added, named, deleted and bound to switch shortcuts; experimental controller takeover also monitors its runtime safety state and automatically disengages/restores on confirmed failures.
Key changes:
- Base remains always eligible, with any number of additional named layers.
- Every layer, including Base, may have a keyboard, mouse, or controller switch trigger.
- Deleting a layer moves its macros back to Base.
- The Layer XML model now replaces serialized layer lists rather than appending into constructor defaults, so a deleted legacy Layer 1 does not reappear after restart while truly old configs still migrate to Base + Layer 1.
- Active takeover health monitoring checks slot 0, Router readiness, expected XInput source visibility, HidHide cloak state, selected hidden-device membership, and the InputStitch HidHide application whitelist.
- One transient health failure is tolerated; two consecutive failures trigger one fail-safe disengage.
- Confirmed failure restores InputStitch-owned HidHide changes, disables Router, clears managed routed output, and keeps recovery data if restoration cannot complete.
- Runtime observation/diagnostics expose active layer name, virtual slot, Router/takeover health and recovery state without creating a virtual device merely for observation.
- Real physical-controller + HidHide + target-game acceptance remains pending because no physical controller is available on the development machine.
- Stable
v1.3.0remains unchanged.
InputStitch 1.3.1-beta.1 (Beta)
InputStitch 1.3.1-beta.1
一句话看懂
现在 InputStitch 可以直接用手柄触发宏、把多个手柄汇总到自己的虚拟手柄,并在实验性接管模式下先安全取得 0 号槽位,再把所选原手柄交给 InputStitch 统一转发。
这是基于 v1.3.0 正式版继续开发的测试版。它不会替换 v1.3.0,也不会修改正式版的自动更新通道。
你现在可以做什么
1. 直接用手柄触发宏
Windows 能看到的 Xbox 兼容手柄现在可以直接作为宏触发来源。
例如:
- 手柄 A → 键盘 K;
- 手柄 LB → 鼠标左键;
- 手柄 RT → 一段键盘、鼠标和虚拟手柄混合操作;
- 按住一个手柄按键 → 持续运行按住宏,松开后停止。
配置时默认表示“任意手柄上的这个控制项”。一个按住宏真正启动后会绑定到实际启动它的那只手柄,因此另一只手柄松开相同按键不会误停它。
左右扳机也能作为触发方式。当前使用约 80% 按下 / 70% 松开的判断,减少临界位置反复抖动。
2. 如果只用键鼠功能,可以完全不创建虚拟手柄
“设置 → 输入与安全 → 虚拟手柄输出 → 手柄类型”现在有第三个选项:
“不创建虚拟手柄(仅使用键盘/鼠标功能)”
选中后:
- InputStitch 启动时不会因为配置里保存着虚拟手柄输出宏而创建 ViGEm 设备;
- 键盘/鼠标宏仍然正常运行;
- 实体或其他 XInput 手柄仍然可以作为键盘/鼠标宏的触发来源;
- 保存/编辑一个虚拟手柄输出步骤本身也不会为了编辑配置而创建设备;
- 真正需要虚拟手柄输出、手柄汇总、闲置自动手柄输入或手柄接管时,需要重新选择 Xbox 360 或 PS4 / DualShock 4;手柄汇总/接管使用 Xbox 360。
如果用户先选择“不创建”,临时开启“手柄汇总”会自动切到 Xbox 360;取消汇总后会恢复之前的“不创建”选择。
3. 把多个手柄汇总到 InputStitch 自己的虚拟手柄
设置中新增测试选项:
“把其他 XInput 手柄的操作汇总到 InputStitch 虚拟手柄(测试)”
开启后,其他可见手柄的:
- 普通按键;
- 方向键;
- 左右摇杆;
- 左右扳机;
会持续汇总到 InputStitch 自己的虚拟 Xbox 360 手柄。
多个手柄可以同时提供输入。一个手柄松开、回中或断开时,只撤销这一只手柄自己的部分,不会把其他手柄或宏正在保持的状态一起释放。
4. 映射层现在支持所有宏类型
第一版映射层提供:
- 基础层:始终有效;
- 映射层 1:可以在运行时启用或关闭。
现在以下宏都可以选择所属层:
- 普通时序宏;
- 按一次启动/停止的宏;
- 复杂的按住运行宏;
- 轻量的持续按住映射。
离开一个映射层时,该层仍在运行的宏会停止,并只释放这个层自己的输出;基础层继续保留。
切入新层时,如果某个触发键原本已经按着,不会立刻产生意外触发。必须先松开,再重新按下。
当前激活层只是运行时状态,重启 InputStitch 后回到“仅基础层”。
5. 更新时断网更安全、更明确
正式版的内置更新器现在对临时断网更耐受:检查更新或下载更新遇到连接失败、DNS 失败、接收中断或无响应时,会在有限范围内自动再尝试 2 次。单次连接/读写连续约 8 秒没有进展就会结束这一轮尝试,不会无限等下去。
下载重试不会续写旧半包:每一次重新尝试前都会先删除上一轮留下的部分文件;三次都失败时也会清掉最终半包,不会进入安装事务、更不会替换当前 InputStitch。后台自动检查阶段断网仍保持安静;一旦用户已经确认更新并进入下载阶段,失败会明确显示“下载更新失败”。如果新 EXE 已完整下载并通过 SHA-256/版本校验,之后即使网络断开,备份、替换和重新启动都在本地完成,不再依赖 GitHub。
实验性手柄接管与 0 号槽位
Windows 的 XInput 接口只提供 0、1、2、3 四个手柄槽位,而且槽位由系统自动分配,InputStitch 不能直接写一个“把我设成 0 号”的命令。
本版本已经加入安全的槽位取得流程。你主动在“工具 → 手柄接管(实验)”中开始接管时:
- InputStitch 会先停止正在受管的手柄输出;
- 短暂断开自己的虚拟 Xbox,用重新枚举结果排除“自己的设备”,避免误隐藏自己;
- 如果当前不在 0 号,会临时让所有外部 XInput/XUSB 手柄离开枚举;
- InputStitch 先重新连接,并硬验证自己确实成为 0 号;
- 立即恢复所有外部手柄,再次确认它们全部重新可读,而且 InputStitch 仍保持 0 号;
- 只有这些检查全部通过,才允许 HidHide 隐藏用户明确选择的原手柄。
任何一步失败都会中止接管并尝试恢复原状态。程序不会先隐藏原 0 号手柄,再赌 InputStitch 能不能抢到 0。
为了取得 0 号,未被选中长期隐藏的外部 XInput 手柄也可能被短暂重新枚举;但最终 HidHide 只处理用户明确选择的设备。当前最多支持 3 个外部 XInput 手柄 + 1 个 InputStitch 虚拟手柄,超过四槽位总上限会在修改设备前拒绝接管。
槽位顺序已经在本机用 4 个中立 ViGEm 测试手柄做过真实验证:初始“外部 0/1/2 + InputStitch 3”,按接管顺序重新枚举后得到“InputStitch 0 + 外部 1/2/3”。这个探针不发送按钮、摇杆或扳机输入。
**仍然需要注意:**真正把原设备对普通程序隐藏依赖用户自行安装的 HidHide;当前开发机没有 HidHide 和实体测试手柄,因此“实体手柄 + HidHide + 实际游戏只看到 InputStitch”的最终硬件验收仍未完成。
多个输入如何合并
本版本继续使用 v1.3.0 已验证的统一输出合并机制,并把每个被汇总的手柄也作为独立输入来源。
普通用户只需要知道:
- 多个来源都按住同一个数字按键时,一个来源结束不会提前松开;
- 多个来源控制同一个扳机时,保留更大的力度;
- 多个来源控制同一个摇杆时,方向会合并,并限制在正常摇杆范围内;
- 方向键同一轴上的相反方向会互相抵消;
- 紧急停止仍然可以一次释放全部受管输入,并会关闭手柄汇总,防止下一次轮询重新把手柄状态按回去。
手柄输入可靠性
本版本还加入了这些保护:
- 同时读取最多四个可见 XInput 槽位;
- 自动排除 InputStitch 自己创建的虚拟 Xbox 手柄,避免“自己输出又触发自己”;
- 启动或手柄重新连接时先记录当前状态,不会因为一个本来就按住的按钮凭空启动宏;
- 手柄断开时会清理该手柄正在保持的触发和汇总状态;
- 多手柄汇总采用整帧更新,避免一个手柄状态变化时产生不必要的中间状态;
- 相同手柄状态不会每 10 ms 重复向虚拟手柄发送完全一样的数据。
自动测试
在生成发布包前,本版本的源码回归已通过:
- 323 项键盘与触发测试;
- 58 项闲置手柄测试;
- 26 项实体/虚拟 XInput 输入测试;
- 28 项多手柄汇总测试;
- 33 项接管安全事务测试;
- 15 项“不创建虚拟手柄”偏好测试;
- 24 项全类型映射层测试;
- 7 项宏计时漂移测试;
- 43 项更新安装测试;
- 23 项界面安全与诊断测试;
- 358 项易用性与配置测试;
- 303,716 项输出合并与并发运行测试;
- 其他修饰键、发布通道和兼容性测试。
这些自动测试使用注入状态或假输出后端,不会发送真实键鼠输入,也不会创建真实测试用虚拟手柄。最终发布前还会对实际生成的 x64/x86 EXE、设置界面、版本信息、更新清单和 SHA-256 校验执行发布包验证。
技术细节
普通用户不需要阅读这一节。
- 物理/已有虚拟 Xbox 兼容手柄通过 Windows XInput 接口读取。
- 每个非 InputStitch 自身的槽位以独立路由来源进入统一输出合并器。
- InputStitch 自己的 ViGEm Xbox 用户槽位会动态排除,避免反馈循环。
- 手柄汇总采用一次完整状态替换一个来源的方式更新,而不是逐按钮修改。
- v1.3.1-beta.1 的“路由”已经可以把 1/2/3 等其他可见槽位持续镜像到 InputStitch 自己的虚拟 Xbox 手柄。
- 新增可恢复的 XInput 槽位取得事务:临时重排所有外部 XUSB 设备、让 InputStitch 先重新连接并验证 0 号,再恢复外部设备;PnP 临时禁用不使用持久禁用标志,并有独立崩溃恢复日志。
- 槽位取得与 HidHide 隐藏是两道独立事务。只有槽位、Router、外部源身份全部再次通过验证,HidHide 阶段才可达。
- 当前开发机只安装了 ViGEmBus,没有 HidHide,因此已经完成真实 ViGEm 槽位顺序验证,但还不会宣称实体原手柄隐藏已经在本机完成硬件验收。
系统要求
- Windows
- .NET Framework 4.7.2 或兼容的更高版本
- 只使用键盘/鼠标宏,或只把实体/其他 XInput 手柄作为键鼠宏触发来源,并选择“不创建虚拟手柄”时,不需要为了这些功能创建 ViGEm 虚拟设备
- 使用虚拟手柄输出、手柄汇总、闲置自动手柄输入或手柄接管时需要 ViGEmBus
InputStitch 仍是便携式、未签名程序。
发布文件
InputStitch-1.3.1-beta.1-Windows-x64.exeInputStitch-1.3.1-beta.1-Windows-x86.exeInputStitch-1.3.1-beta.1-Source.zipInputStitch-beta.xmlSHA256SUMS.txt
English summary
InputStitch can now use connected controllers to trigger macros, merge multiple XInput controllers into its own virtual Xbox controller, and in experimental takeover mode safely acquire XInput slot 0 before handing selected original controllers to the routed virtual controller.
Key points:
- Controller buttons and triggers can start keyboard, mouse, gamepad, or hybrid macros.
- Settings can choose Do not create a virtual controller. Keyboard/mouse macros and controller-triggered keyboard/mouse macros still work, while saved gamepad-output macros no longer force ViGEm creation at startup.
- Stable-channel update networking now uses bounded timeout/retry handling for transient outages. Partial executables are deleted before every retry and after final failure; once a verified executable has downloaded, installation is fully local and no longer needs GitHub/network access.
- Optional controller merging mirrors buttons, D-pad, sticks, and triggers from all other visible XInput slots into the InputStitch virtual Xbox controller.
- Experimental takeover now has a recoverable slot-acquisition transaction. If InputStitch is not already slot 0, all present external XUSB controllers are temporarily re-enumerated, InputStitch reconnects first and must verify slot 0, then the external controllers are restored and re-verified before HidHide is allowed to hide any selected device.
- Unselected controllers may be temporarily cycled to make slot 0 available, but only explicitly selected external device identities are passed to HidHide.
- The current XInput backend supports at most three external controllers plus the InputStitch virtual Xbox controller.
- Base is always active; timed, toggle, complex Hold, and lightweight Held Mapping macros can all belong to Layer 1.
- Leaving a layer stops that layer's active runs and removes only their owned output.
- A neutral four-controller ViGEm probe on this development machine verified the real ordering transition
external 0/1/2 + InputStitch 3 -> InputStitch 0 + external 1/2/3without submitting button/stick/trigger input. - Real physical-controller + HidHide + target-game takeover is still pending because HidHide and a physical XInput test controller are not available on this development laptop.
- Stable v1.3.0 and its automatic update channel remain unchanged.
InputStitch 1.3.0
InputStitch 1.3.0
InputStitch 1.3.0 promotes the Input Ownership and universal Concurrent Macro Runtime work from the 1.3 Beta line to Stable.
Highlights
- Universal normal-macro concurrency. Multiple distinct ordinary timed/Toggle macros, Advanced/complex Hold timelines, and state-only Parallel Held Mappings can run at the same time.
- Independent runtime ownership. Worker-backed runs have independent
RunId/SourceId/ stop / timing / progress state, while final keyboard, mouse, and virtual-gamepad output is merged through Output Ownership. - Source-local cleanup. Stopping, completing, or releasing one macro no longer clears unrelated active sources. Emergency Stop remains the global fail-safe and releases everything.
- Advanced Hold is concurrent. Keyboard/mouse Hold output, gamepad Press/Up sequencing, finite Hold, and Hold steps with fixed/random delays use the concurrent runtime instead of an exclusive worker.
- Modifier-chord Hold. Triggers such as
Shift+E,Ctrl+F, andCtrl+Shift+Kcan be used with Hold mode. Releasing the terminal key or any required modifier stops only that Hold source; lost-KeyUp fallback evaluates the complete chord. - Shift-friendly ordinary triggers. If no more-specific explicit chord exists, a bare ordinary key such as
Ecan still trigger while Shift is physically held. ExplicitShift+Eremains higher priority. Ctrl/Alt/Win stay strict for bare-key fallback. - Quick Create follows the same rules. Modifier-chord Held Mapping triggers are accepted; wheel directions remain ineligible for physical Hold triggering because they have no persistent down state.
- Clearer runtime eligibility. The editor uses the same authoritative
MacroRuntimeClassifieras execution and now distinguishes manual/UI execution from physical Hold-trigger eligibility. - Runtime observation and single-step. Runtime Observation lists active runs/sources/merged state. Single-step remains an intentionally exclusive diagnostic mode, not a normal concurrency restriction.
- Project link in the gear menu.
Open Project on GitHub/打开项目 GitHubopens the InputStitch repository in the default browser.
Deterministic overlap behavior
Persistent digital ownership is state-first. If one source already holds a key/button, another source's pulse/click on the same control does not force an artificial release/repress bounce. The persistent state stays down until its final owner releases.
Analog controller merging remains deterministic:
- triggers: maximum requested value;
- sticks: source vectors sum and normalize to the circular range;
- D-pad: opposing directions cancel per axis;
- digital keyboard/mouse/controller buttons: reference ownership.
Reliability and compatibility
- Emergency Stop, shutdown, and backend failure retain fail-closed cleanup.
- UI edit protection suspends/resumes only affected worker-backed sources instead of globally neutralizing unrelated Held Mappings.
- Starting macro recording now treats state-only Parallel Held Mapping as active runtime and stops active runtime before capture.
- Removed obsolete singleton-era helpers/events/localization and one unused legacy configuration field; old XML containing the removed field remains covered by compatibility tests.
- One active run per
MacroDefinitionremains intentional. - Duplicate physical triggers continue to use macro-list priority.
- Wheel directions remain unsupported as physical Hold triggers; a wheel-triggered Hold definition may still be run manually from the UI.
Validation
The exact Stable 1.3.0 source passed the full isolated regression suite and Windows x64/x86 release verification before publication. The final release gate includes:
- 323 keyboard checks;
- 58 Idle Gamepad assertions;
- 43 updater checks;
- 23 UI safety / diagnostics checks;
- 358 productivity/UI checks, including the localized gear-menu GitHub item;
- 303,716 Output Ownership/runtime checks;
- zh-CN / en-US Settings smoke tests at normal and narrow sizes;
- old XML compatibility;
- gamepad vector editor smoke coverage.
Input Lab's real-SendInput pre-XInput concurrency lanes also remain part of the 1.3 validation history. This laptop can intermittently enumerate the ViGEm Xbox controller while XInput remains neutral; that environment condition is reported as BLOCKED with zero product assertion failures rather than being misreported as an InputStitch failure.
Requirements
- Windows
- .NET Framework 4.7.2 or a compatible later release
- ViGEmBus is required only for virtual-controller output
- Keyboard/mouse-only macros do not require ViGEmBus
InputStitch remains portable and unsigned.
Assets
InputStitch-1.3.0-Windows-x64.exeInputStitch-1.3.0-Windows-x86.exeInputStitch-1.3.0-Source.zipInputStitch-update.xmlSHA256SUMS.txt
中文说明
InputStitch 1.3.0 将 1.3 Beta 阶段完成并验证的 Input Ownership + 统一 Concurrent Macro Runtime 正式晋升到 Stable。
主要变化:
- 多个不同的普通时序 / Toggle 宏、多个高级/复杂 Hold、多个 Parallel Held Mapping 可以同时运行;
- 每个 worker 运行实例拥有独立 RunId / SourceId / 停止 / 时序 / 进度状态,一个宏结束或停止不会清除其他来源;
- 高级 Hold 不再独占,键鼠 Hold、Press/Up、非零或随机延迟、有限/无限 Hold 都可进入并发运行时;
Shift+E、Ctrl+F、Ctrl+Shift+K等修饰键组合可以作为 Hold 触发器,组合中任意必需按键松开都只停止对应 Hold;- 按住 Shift 时,如果不存在更具体的显式
Shift+E,单独配置的裸E仍可正常触发;Ctrl/Alt/Win 不做这种裸键 fallback; - Quick Create 与高级编辑器使用同一套 Hold 规则;滚轮因为没有持续按下状态,仍不能作为物理 Hold 触发器;
- 运行资格提示与实际执行使用同一个 classifier,并明确区分“可手动运行”和“可由物理 Hold 触发”;
- 齿轮菜单新增 “打开项目 GitHub”,可一键在默认浏览器中打开 InputStitch 项目主页;
- Emergency Stop 继续保持最高优先级,可一次释放全部受管输出。
下一阶段的最高优先级是 Physical Gamepad Input + Hybrid Controller Routing:先让 Windows XInput 手柄成为正式触发/输入源,再逐步实现 Controller → Keyboard/Mouse 的混合映射;Layer 继续后移。
InputStitch 1.3.0-beta.2 (Beta)
InputStitch 1.3.0-beta.2
Pre-release / 预发布。 Stable 仍为 v1.2.0。本 Beta 使用独立的
InputStitch-beta.xml,不会替换 Stable 的releases/latest或InputStitch-update.xml。
简体中文
这一版的重点:任意正常宏类型多并发
beta.2 在 beta.1 的 Input Ownership 基础上完成了统一 Concurrent Macro Runtime。现在多个不同宏可以真正同时运行,而不再只允许“多个 Held Mapping + 一个普通宏”。
当前支持同时存在:
- 多个普通时序 / Toggle 宏;
- 多个高级 / 复杂 Hold 宏;
- 多个纯状态型 Parallel Held Mapping;
- 键盘、鼠标、虚拟手柄输出混合;
Down / Up / Press;- 固定延迟或随机延迟;
- 有限循环或无限运行。
每个 worker 运行实例都有独立 RunId / SourceId / Stop / timing / progress。复杂 Hold 还会按 Run 独立保存物理触发键与 lost-KeyUp 松键恢复状态,因此松开一个 Hold 只停止它自己,不会误伤其他并发宏。
Held Mapping 与复杂 Hold 的区别
简单的无限 Hold、即时手柄 Down、零延迟映射继续使用轻量 Parallel Held Mapping 快速路径。
一旦 Hold 包含键盘/鼠标输出、Press/Up 时序、非零/随机延迟或有限次数执行,就会由统一 classifier 归类为 可并发高级 Hold / Concurrent Advanced Hold,进入独立时间线运行时,但仍可与其他宏和 Parallel Held Mapping 同时存在。
有限 Hold 保留旧语义:达到配置的循环次数后可以自然结束;如果尚未结束,物理触发键松开会提前停止该 Run。
运行资格实时提示
编辑器里的“运行类别 / 并发能力”不再维护单独的 UI 规则,而是直接读取执行时使用的 MacroRuntimeClassifier。
因此取消无限循环、切换 Hold/Toggle、加入键鼠步骤、Press/Up、延迟或随机延迟时,界面会实时显示当前真实运行类别,不会出现“UI 说能并发、Runtime 却不能”的分叉。
冲突与安全语义
- 每个 Run 只清理自己的 Output Ownership Source;
- 一个复杂 Hold 的 KeyUp/MouseUp 或 lost-KeyUp fallback 只停止对应 Run;
- 同一数字输出被多个 Source 持有时继续使用引用所有权;
- 如果一个 Source 已持续持有某键/按钮,另一个宏对同一输出执行 pulse/click,不会强制制造 release/repress 抖动;该 pulse 会被确定性屏蔽;
- 同一个
MacroDefinition仍最多有一个活动 Run,避免重复触发同一宏产生不可控重入; - 同一物理触发键对应多个宏时仍按宏列表顺序决定优先级;
- Single-step 仍刻意保持独占,因为它是诊断执行模式,不是正常宏并发类别;
- Emergency Stop 和退出清理始终保持全局最高优先级。
自动验证
beta.2 发布前完整回归通过:
- 323 keyboard checks;
- 58 Idle Gamepad assertions;
- 43 updater checks;
- 23 UI safety / diagnostics checks;
- 351 productivity checks;
- 303,700 Output Ownership checks;
- 中英文 Settings、窄窗口、旧 XML 配置兼容、已保存手柄向量初始化/编辑 smoke tests。
新的 Ownership / Runtime 测试覆盖普通时序宏 + 多个 Advanced Hold + Parallel Held 混跑、逐 Hold 松键、独立 lost-KeyUp probe、定义修改只停止目标 Run、有限 Hold 自然完成、同输出引用所有权、pulse masking,以及混合状态 Emergency Stop。
Input Lab 还使用真实 SendInput 验证了复杂 Hold 黑盒并发:F9 → K 与 F10 → Mouse X2 两条带延迟的 Advanced Hold 同时保持;Runtime Observation 同时显示两个 Concurrent Advanced Hold;松开 F9 后 K 被释放而 F10/X2 继续保持;松开 F10 后 X2 再释放。进入 XInput 预检前 18/18 checks PASS,0 failures。
本测试电脑仍存在间歇性的 ViGEm/XInput 环境问题:虚拟 Xbox 可以枚举,但 XInput 偶尔停留在 neutral packet=1。Acceptance 会把它报告为 SUMMARY: BLOCKED / failures=0,而不是伪装成产品 PASS 或误判为 InputStitch FAIL。
仍需真实游戏验收
beta.2 的下一步是重点实测新增路径,而不是机械重测没改动的底层 SendInput/ViGEm 基础兼容性:
- 两个以上复杂 Hold 同时保持;
- 复杂 Hold + 普通时序/Toggle + Parallel Held 混跑;
- 分别松键/停止,确认只清自己的输出;
- 一个有限复杂 Hold 与一个无限 Hold 共存;
- 至少一次 Alt+Tab 后在后台松开多个 Hold/Held 触发键,确认 lost-KeyUp fallback 按 Source 清理;
- 混合状态下 Emergency Stop 回到完全中立。
如果这轮真实使用验收干净,下一步就是 Stable v1.3.0。
English
Main change: universal normal-macro concurrency
beta.2 extends beta.1's Input Ownership foundation into a unified Concurrent Macro Runtime. Multiple distinct macros may now run at the same time instead of being limited to “multiple Held Mappings + one ordinary macro”.
Supported concurrent execution includes:
- multiple ordinary timed / Toggle macros;
- multiple Advanced / complex Hold macros;
- multiple state-only Parallel Held Mappings;
- mixed keyboard, mouse and virtual-gamepad output;
Down / Up / Presssequencing;- fixed or random delays;
- finite or infinite execution.
Every worker-backed run has independent RunId / SourceId / Stop / timing / progress state. Complex Hold runs additionally snapshot their physical trigger and lost-KeyUp release probe per run, so releasing one Hold stops only that run.
Parallel Held vs Advanced Hold
Simple infinite, immediate gamepad-Down, zero-delay mappings retain the lightweight Parallel Held Mapping fast path.
Hold macros containing keyboard/mouse output, Press/Up sequencing, non-zero/random delay or finite execution are classified by the authoritative runtime classifier as Concurrent Advanced Hold. They use independent timelines but can coexist with ordinary macros, other Advanced Hold runs and Parallel Held Mappings.
Finite Hold preserves historical semantics: it may complete naturally when its configured repetitions finish; physical release stops it early only while the run is still active.
Live runtime capability display
The editor's runtime/concurrency eligibility display now reads the same MacroRuntimeClassifier used by execution. Editing Hold/Toggle mode, infinite/finite behavior, output type, Press/Up sequencing or delay immediately updates the real runtime category instead of maintaining a separate UI rule table.
Deterministic safety semantics
- one run ending/stopping/failing clears only its own Output Ownership source;
- terminal release and lost-KeyUp fallback target the matching Hold run only;
- shared digital output keeps reference ownership;
- pulse/click on a key/button already persistently held by another source is deterministically masked instead of forcing a release/repress bounce;
- one active run per
MacroDefinitionremains intentional; - duplicate physical triggers still use macro-list priority;
- Single-step remains intentionally exclusive as a diagnostic mode;
- Emergency Stop and shutdown remain the global highest-priority cleanup paths.
Verification
Pre-release regression passed:
- 323 keyboard checks;
- 58 Idle Gamepad assertions;
- 43 updater checks;
- 23 UI safety / diagnostics checks;
- 351 productivity checks;
- 303,700 Output Ownership checks;
- bilingual Settings, narrow-layout, legacy XML compatibility and saved gamepad-vector smoke tests.
Input Lab also validated real-SendInput complex-Hold overlap: delayed F9 → K and F10 → Mouse X2 Advanced Hold timelines overlap, Runtime Observation lists both as Concurrent Advanced Hold, releasing F9 removes only K while F10/X2 remains, and releasing F10 clears X2. All 18 pre-XInput checks PASS with 0 failures.
This laptop still has an intermittent local ViGEm/XInput observation issue where the virtual Xbox enumerates but XInput may stay at neutral packet=1. Acceptance reports this as SUMMARY: BLOCKED with failures=0, distinct from an InputStitch product failure.
Remaining real-game gate
Focus live testing on the newly affected paths: multiple complex Holds, complex Hold + ordinary timed/Toggle + Parallel Held coexistence, independent release order, finite + infinite Hold overlap, one Alt+Tab/lost-KeyUp sample, and mixed-state Emergency Stop. If that gate is clean, the next promotion target is Stable v1.3.0.
Files / 文件
InputStitch-1.3.0-beta.2-Windows-x64.exeInputStitch-1.3.0-beta.2-Windows-x86.exeInputStitch-1.3.0-beta.2-Source.zipInputStitch-beta.xmlSHA256SUMS.txt
InputStitch 1.3.0-beta.1 (Beta)
InputStitch 1.3.0-beta.1
Pre-release / 预发布。 Stable 仍为 v1.2.0。本 Beta 使用独立的
InputStitch-beta.xml,不会替换 Stable 的releases/latest或InputStitch-update.xml。
简体中文
这一版解决什么
1.3.0-beta.1 是 InputStitch 第一次引入 Input Ownership / 输入所有权 的结构性版本。旧版本的运行时本质上只有一个当前宏;现在持续输出由独立 Source 拥有,再由统一合并器计算最终键鼠/虚拟手柄状态。
最直接的结果是:多个符合 Held Mapping 形态的按住映射可以同时保持,并且还能同时运行最多一个普通时序宏。
例如可以同时使用:
W → 左摇杆向前A → 左摇杆向左S → 左摇杆向后D → 左摇杆向右Shift → RTCtrl → LTMouse X1 → LBMouse X2 → RB
按住多个触发键时,每个映射只拥有自己的输出贡献;松开其中一个不会再把其他映射的状态一起清零。
合并规则
统一 Output Ownership 当前采用以下规则:
- 键盘 / 鼠标按钮 / 手柄数字按钮:引用所有权。只要还有任意 Source 持有,最终状态就继续保持 Down。
- LT / RT 扳机:取所有来源请求值的 最大值。
- 摇杆:所有来源的 X/Y 向量先相加,再按圆形摇杆范围归一化;相反方向自然抵消。
- D-pad:上下、左右分别作为两个轴处理;同轴相反方向相互取消,正交方向可以组成斜向。
- Emergency Stop:高于普通合并规则,直接清空所有 Source,并强制释放键鼠与中立化手柄。
普通宏、并行 Held Mapping 和 Idle Gamepad 已统一使用同一 ownership 核心。普通宏结束、UI 编辑保护暂时释放自身输出、Idle pulse 结束时,都不会再误伤其他仍然有效的 Source。
并行范围
本 Beta 没有开放“任意多个普通宏并行”。边界刻意保持较窄:
- 多个 Held Mapping 可以并行;
- 最多一个普通 Toggle / 时序宏 可以与这些 Held Mapping 同时存在;
- 高级/复杂 Hold 宏仍保持独占,不与并行 Held Mapping 混跑;
- 同一个物理触发键对应多个已启用宏时,仍按照宏列表从上到下决定优先级;不会因为 ownership 自动把同触发键的多个宏一起启动;
- Emergency Stop 始终拥有绝对优先级。
第一版可并行 Held Mapping 的运行时形态是:Hold + Infinite、单键/单独 Ctrl/Shift/Alt/Win 或鼠标按钮触发、不使用修饰键组合/滚轮,执行内容为即时的手柄 Down 状态。快捷创建 → 按住映射生成的就是这种形态。
轻量运行观察
工具菜单新增 运行观察…。这是一个轻量、实时刷新且非模态的观察窗口,可以看到:
- 当前普通时序宏、RunId、执行阶段、迭代和步骤;
- 当前并行 Held Mapping;
- 每个 Output Source 的贡献;
- Source 是否因 UI 安全保护而暂时 Suspended;
- 合并后的最终输出;
- 最近停止原因 / ownership 最近变化原因。
它不是断点调试器,也不会持续记录用户的普通键盘输入。
单步执行
普通时序宏新增 单步执行:
- 点击“单步执行”开始;
- 第一条步骤执行完后等待;
- 点击“下一步”继续;
- 最后一步结束后自动退出。
单步模式只执行一轮,不使用步骤之间的普通 Delay 作为自动推进;每个步骤内部的 Press Hold 时间仍按原设置执行。正常“停止当前宏”和 Emergency Stop 在等待期间仍然有效。Held Mapping 不使用单步按钮,应继续通过物理触发键测试。
安全边界
- 修改正在活动的 Held Mapping 的关键定义(触发方式、触发键、循环方式、步骤、禁用、删除等)时,会先停止该映射,再修改配置,避免“界面定义已经变化、旧输出 Source 还活着”。
- UI 编辑保护现在只 Suspend 普通宏自己的 Source;其他并行 Held Mapping 的手柄贡献不会因为普通宏暂停而被一起清除。
- ownership 后端发生发送失败时会 fail closed:清空逻辑 Source、释放已知键鼠状态并中立化虚拟手柄,然后向上报告错误。
- 退出程序时 ownership 也作为最终清理权威,避免普通 worker 未及时结束时残留已按住输出。
- Emergency Stop 会解除单步等待、停止普通 worker、清除所有并行映射,并再次强制中立化手柄。
Layer / 映射层
Layer 已经完成下一阶段设计,但没有在 beta.1 中启用。这是有意的:Input Ownership 是第一次结构性并发改造,在缺少真实游戏验收前再叠加 Layer,会让问题定位困难。
当前架构已经为 Layer 做好准备。拟定的第一版是 Base + 一个活动 Layer,只筛选 Held Mapping;切层时先移除旧层 Source,不会为切层前已经按住的键自动补触发,必须松开后重新按下。详细设计见 docs/LAYER_DESIGN.md。
自动验证
当前源码完整回归通过:
- 323 keyboard checks;
- 58 idle-gamepad assertions;
- 43 updater checks;
- 23 UI-safety / diagnostics checks;
- 348 productivity checks;
- 303,643 output-ownership checks;
- 中英文 Settings、604×441 窄窗口、旧 XML 配置兼容、已保存手柄向量初始化/编辑 smoke tests。
Ownership 测试包含数字输出多来源引用、trigger max、摇杆/D-pad 冲突、后端故障 fail-closed、10,000 次随机来源操作、5 种混合来源的完整激活/释放顺序组合、实际 MainForm 路径下 2 Held Mapping + 1 ordinary、单步 + Emergency Stop、UI safety suspend/resume。测试使用 fake backend,不会发送真实键鼠输入,也不会创建真实虚拟手柄。
因此这些测试不能替代真实游戏验收。请重点测试:WASD 组合、Shift/Ctrl 扳机、鼠标侧键按钮、不同松开顺序、普通时序宏共存、Alt+Tab 后释放、Emergency Stop,以及多次启停后是否存在残留状态。
虚拟手柄仍依赖 ViGEmBus;EXE 仍未签名。Beta 与 Stable 共用 %APPDATA%\InputStitch,请不要同时运行两个版本。
English
What this beta changes
1.3.0-beta.1 introduces InputStitch's first explicit Input Ownership runtime. Persistent output now belongs to independent sources and a central merge layer computes the final keyboard/mouse/virtual-controller state.
The practical result is that multiple qualifying Held Mappings can remain active together while one ordinary timed macro also runs. Releasing one mapping removes only its contribution instead of neutralizing unrelated mappings.
Typical simultaneous mappings include WASD → left-stick directions, Shift/Ctrl → triggers, and mouse side buttons → shoulders.
Merge rules
- Keyboard, mouse buttons, and digital gamepad buttons: reference ownership; output remains Down while any source owns it.
- Analog triggers: maximum requested value wins.
- Sticks: source X/Y vectors are summed and then normalized to the circular stick range; opposing vectors cancel naturally.
- D-pad: opposite directions cancel per axis; orthogonal directions can remain together as a diagonal.
- Emergency Stop: bypasses ordinary merge rules, clears every source, releases keyboard/mouse state and forces the virtual pad neutral.
Ordinary macros, parallel Held Mappings and Idle Gamepad now share the same ownership core, so one source finishing or being UI-suspended no longer clears another source.
Concurrency boundary
This beta does not enable arbitrary concurrent timed macros:
- multiple qualifying Held Mappings may run together;
- at most one ordinary Toggle/timed worker may coexist with them;
- advanced/complex Hold workers remain exclusive;
- duplicate physical triggers still use macro-list priority rather than launching every duplicate;
- Emergency Stop remains absolute priority.
Quick Create → Held Mapping produces the intended parallel shape: supported single terminal trigger, Hold + Infinite, and immediate gamepad Down output.
Runtime observation
Tools now includes Runtime observation..., a lightweight non-modal live view of active sources, each source contribution, merged output, ordinary macro RunId/phase/step, suspended state and recent stop/ownership reasons. It is not a full debugger and does not continuously record ordinary typing.
Single-step execution
Ordinary timed macros gain Single-step / Next Step. Single-step runs one iteration, pauses between steps until Next Step is pressed, and remains interruptible by normal Stop and Emergency Stop. Per-step Press hold duration is still honored; the normal automatic post-step delay is not used to advance to the next step. Hold mappings continue to be tested with their physical triggers.
Safety boundaries
- Definition edits that would invalidate a live Held Mapping stop that mapping before mutation.
- UI edit protection suspends only the ordinary macro source and leaves unrelated Held Mapping contributions intact.
- Ownership backend failure fails closed and clears every logical/physical output state it can own.
- Shutdown performs a final ownership ClearAll even if a worker did not finish within the bounded join.
- Emergency Stop releases single-step waits, the ordinary worker and all parallel mappings.
Layer status
Layer / Mapping Layer is designed but intentionally deferred until this first ownership beta receives real-game acceptance. The proposed first design is Base + one active mapping layer, scoped to Held Mapping only. Switching removes old-layer sources and does not synthesize a trigger for keys that were already held before the switch. See docs/LAYER_DESIGN.md.
Verification and limits
The current full suite passes 323 keyboard checks, 58 idle-gamepad assertions, 43 updater checks, 23 UI-safety/diagnostic checks, 348 productivity checks and 303,643 ownership checks, plus bilingual Settings, narrow-layout, legacy-config and gamepad-vector smoke tests.
Ownership coverage includes same-output reference ownership, trigger max, stick/D-pad conflict resolution, fail-closed faults, 10,000 randomized source operations, exhaustive activation/release ordering across five mixed sources, real MainForm composition with two Held Mappings + one ordinary worker, single-step/Emergency Stop, and UI-safety suspend/resume through a fake backend. These tests send no real keyboard/mouse input and create no real virtual controller, so game acceptance still requires live testing.
Virtual gamepad output still requires ViGEmBus. Executables are unsigned. Beta and Stable share %APPDATA%\InputStitch; do not run both at the same time.
Files / 文件
InputStitch-1.3.0-beta.1-Windows-x64.exeInputStitch-1.3.0-beta.1-Windows-x86.exeInputStitch-1.3.0-beta.1-Source.zipInputStitch-beta.xmlSHA256SUMS.txt
InputStitch 1.2.0
InputStitch 1.2.0
简体中文
InputStitch 1.2.0 将 1.1.1 Beta 1–4 中经过实际使用和回归验证的可靠性、配置安全和易用性改进正式晋升为 Stable。
配置与安全
config.xml采用暂存写入、刷新到磁盘、重新反序列化验证后再替换主配置;失败时尽量保留上一份有效配置。- 自动保留最近 5 份有效主配置备份;保存失败会明确显示“未保存”。
- 强化前台/后台切换、修饰键状态和 Held Mapping 释放逻辑;Alt+Tab 等情况下即使丢失 KeyUp,也有物理状态兜底释放。
- Emergency Stop、编辑保护和有限运行诊断继续保留。
更容易创建和编辑宏
- “新增”菜单提供 按住映射 / 定次数连按 / 顺序执行 三种快捷创建方式,同时保留空白宏高级编辑。
- Held Mapping 支持普通键盘键、鼠标按钮和单独的左右 Ctrl / Shift / Alt / Win。
- 原始触发输入继续透传;多个已启用宏共用同一触发键时,宏列表靠上的优先,↑ / ↓ 会立即改变优先级。
- 步骤编辑支持 Undo / Redo,覆盖添加、删除、编辑、移动和批量操作,最多 50 次历史。
闲置自动手柄输入
- 真实鼠标移动改由 Raw Input 判断,游戏自己锁定/重定位光标不会再被误认为持续操作。
- “设置 → 自动化”中加入独立的挂机目标,不依赖也不会修改主界面的目标窗口、UI 运行切换或自动方案切换。
- 设置挂机目标后,在浏览器、聊天软件等其他程序中打字或移动鼠标,不会阻止后台目标程序按时收到挂机手柄脉冲。
- 已设置的挂机目标不存在时,闲置输出完全暂停;目标重新出现后从完整空闲周期重新计时。
- 正式默认值:关闭、120 秒、左摇杆向下、150 ms。已有用户保存的自定义值不会被覆盖。
- 窄设置窗口下,过长目标名称保持单行省略显示,按钮不会被覆盖;悬停可查看完整名称。
升级提示
- 已经使用过 InputStitch 的用户,在升级到新版本后首次启动时,会看到一次简短的“本次更新内容”摘要。
- 同一个版本只显示一次;全新安装仍只显示普通 Welcome,不会连续弹两个提示框。
更新与发布
- 1.2.0 恢复 Stable 自动更新通道,正式清单为
InputStitch-update.xml,下载仍执行 SHA-256 校验。 - Beta 以后继续使用独立 prerelease /
InputStitch-beta.xml,不会混入 Stable 更新提醒。
验证与已知边界
当前源码通过:323 项 keyboard checks、58 项 idle-gamepad assertions、43 项 updater checks、23 项 UI safety/diagnostics checks、348 项 productivity checks,以及中英文 Settings / 旧配置兼容 / 手柄参数 smoke tests。
自动测试不会发送真实键鼠输入或创建真实虚拟手柄,因此不能证明所有游戏兼容。当前仍保持普通时序宏一次只运行一个;多来源 Held Mapping / Input Ownership 将进入 1.3.0 开发周期。
虚拟手柄输出仍依赖 ViGEmBus;EXE 未签名。
English
InputStitch 1.2.0 promotes the reliability, configuration-safety and productivity work validated through the 1.1.1 Beta 1–4 cycle to Stable.
Configuration and safety
config.xmlis staged, flushed and deserialized for verification before the main file is replaced; failures preserve/recover the previous valid configuration when possible.- Keep the five most recent valid main-config backups and surface an explicit Not saved warning on failure.
- Harden foreground/background, modifier-state and Held Mapping release behavior. A physical-state fallback releases Hold mappings even if a KeyUp is lost around Alt+Tab.
- Emergency Stop, edit protection and bounded runtime diagnostics remain in place.
Easier creation and editing
- New Quick Create options: Held Mapping / Repeat a fixed number of times / Sequence, while preserving Blank macro advanced editing.
- Held Mapping accepts normal keyboard keys, mouse buttons and standalone left/right Ctrl / Shift / Alt / Win.
- The original physical trigger passes through. When multiple enabled macros share a trigger, the first macro in list order wins; Up / Down changes that priority immediately.
- Step Undo / Redo covers add, delete, edit, move and batch operations with a 50-operation history cap.
Idle gamepad input
- Physical mouse movement uses Raw Input, so games that lock/recenter the cursor no longer fake continuous user activity.
- Settings → Automation now has an independent Idle target that does not depend on or modify the main target window, UI-run activation or automatic profile switching.
- Typing/moving the mouse in other apps does not block the background target's idle pulse.
- If a configured Idle target is absent, idle output pauses completely; when it returns, a fresh full idle interval begins.
- Formal defaults: off, 120 seconds, left stick down, 150 ms. Existing saved custom values are not overwritten.
- Long target names ellipsize on one line in narrow Settings windows; buttons remain visible and a Tooltip exposes the full name.
Upgrade summary
- Existing users see a short What's new summary once after upgrading to a new version.
- The same version is never shown twice; fresh installs still show only the normal Welcome dialog.
Updates and release channel
- Stable 1.2.0 uses
InputStitch-update.xmland the existing SHA-256-verified Stable update path. - Future Beta builds remain separate prereleases with
InputStitch-beta.xmland do not replace Stable update notifications.
Verification and limits
The current source passes 323 keyboard checks, 58 idle-gamepad assertions, 43 updater checks, 23 UI-safety/diagnostic checks, 348 productivity checks, plus bilingual Settings / legacy-config / gamepad-vector smoke tests.
Automated tests send no real keyboard/mouse input and create no real virtual controller, so universal game compatibility is not claimed. Ordinary timed macros remain single-active; multi-source Held Mapping / Input Ownership is planned for the 1.3.0 development cycle.
Virtual gamepad output still requires ViGEmBus. The executables are unsigned.
Files / 文件
- InputStitch-1.2.0-Windows-x64.exe
- InputStitch-1.2.0-Windows-x86.exe
- InputStitch-1.2.0-Source.zip
- InputStitch-update.xml
- SHA256SUMS.txt
InputStitch 1.1.1-beta.3 (Beta)
InputStitch 1.1.1-beta.3
简体中文
公开测试版,正式版 v1.1.0 与自动更新入口不变。手动下载,不覆盖旧发行记录。
前台热键修复
旧版会把“鼠标悬停在按钮、列表、表格上”也视为正在编辑,直接忽略热键,状态却可能保持空闲。本版移除此已确认的静默拦截路径:
- 空闲时仅悬停、选中按钮/列表不再阻止启动;执行前将非编辑焦点移到安全输入控件。
- 实际编辑名称、备注、数值或下拉设置,以及模态编辑窗口,仍受保护;明确显示原因而不是空闲。点击空白区域/分区标题/底部可结束编辑。
- 每次物理触发和排队执行前刷新保护状态,避免短暂沿用旧焦点/前台状态。
- 已运行宏仍保护有焦点的操作控件;鼠标/滚轮宏仍防止误点或滚动鼠标指向的控件,首步也受保护。没有关闭编辑保护。
后续稳定性开发:运行诊断
诊断窗口新增最近 64 条内存事件:匹配热键接受/拦截、执行启动、首次输出提交、停止请求、完成/取消/错误。不会记录未匹配的普通打字,不逐帧/逐循环写盘,退出后清空。分享诊断前仍应检查其中已有的配置路径等信息。
“首次输出提交”仅表示输出调用返回,不证明游戏接收。可用于区分未触发、被保护拦截、已经运行三个阶段。
验证和边界
新增 23 项 UI 保护/诊断检查,含真实控件分类和 1 万次并发诊断事件的容量测试;原有键盘、闲置手柄、修饰键、更新故障、双语设置及手柄参数测试保留。测试不等同于真实桌面/游戏完整重放,不宣称排除所有偶发故障。
测试前退出旧版,备份整个 %APPDATA%\InputStitch。Beta 与正式版共用配置;不同时运行。Beta 不自动检查更新,手动检查经确认打开 GitHub。EXE 未签名,手柄输出需要 ViGEmBus。
建议依次测试:悬停按钮时触发;选中宏列表后触发;编辑名称时确认显示保护;点击空白后再触发。若仍异常,在关闭程序前复制诊断中的 RecentRuntimeEvents。
English
Public opt-in Beta. Stable v1.1.0 and automatic-update assets are unchanged.
- Remove silent idle-hover/non-editing-focus hotkey blocks. Transfer safe non-editor focus before execution; refresh protection on physical trigger and before queued dispatch.
- Focused text/numeric/combo editors and modal editing stay protected with a visible explanation. Empty areas, section labels and footer clicks finish editing. Running macros retain control-focus protection; mouse/wheel output keeps pointer-hover protection, including its first step.
- Continue reliability work with a bounded, memory-only 64-event runtime trace in diagnostics: matched-trigger decisions, worker start, first output submission, stop, completion/cancellation/error. No ordinary typing or per-loop disk log. Submission does not establish game acceptance.
- Add 23 UI-policy/control/trace checks including 10,000 concurrent events; existing regression suites remain. These are not full live desktop/game playback tests and do not establish that every intermittent failure is eliminated.
- Close InputStitch and back up %APPDATA%\InputStitch before testing; versions share configuration. Manual Beta downloads only; unsigned EXEs; ViGEmBus required for gamepad output. If the issue persists, copy RecentRuntimeEvents from diagnostics before closing.
Files / 文件
- InputStitch-1.1.1-beta.3-Windows-x64.exe
- InputStitch-1.1.1-beta.3-Windows-x86.exe
- InputStitch-1.1.1-beta.3-Source.zip
- InputStitch-beta.xml
- SHA256SUMS.txt