全屏键位接管
基本信息
| 属性 | 值 |
|---|---|
| 本 mod 新增的键位 | 0 个可用键位(占位键绑到 KEY_NONE) |
| 被接管的原版键位 | Minecraft.gameSettings.field_152395_am(原版全屏键) |
| 占位键位类 | ClientProxy#ignoreKeyBinding(public static) |
| 占位键位键码 | Keyboard.KEY_NONE |
| 占位键位分类 | key.categories.misc |
| 注册时机 | init(FullscreenWindowed#init → proxy.registerKeyBindings()) |
| 兼容 Minecraft 版本声明 | Reference.MC_VERSIONS = "[1.7,)" |
这个 mod 不给自己注册任何键位。它做的是相反的事:把原版全屏键抢过来藏起来, 再让玩家用原版那个键位来触发无边框切换。
为什么必须抢
源码注释写得很直接(ClientProxy.java:36-39):
This keybind replaces the default MC fullscreen keybind in their logic handler. Without it, the game crashes. If this is set to any valid key, problems may occur.
Minecraft 的 keyBindFullscreen 逻辑处理器会在该键按下时无条件调用 LWJGL 的
真全屏切换,这与本 mod 的"永远 Display.setFullscreen(false)"策略直接冲突。
把该字段替换成一个绑定到 KEY_NONE 的 KeyBinding 对象,
isKeyDown(-1) 恒为 false,于是原版处理器变成永不触发的死代码。
注释同时警告:占位键位不能绑到任何有效按键,否则会出问题。
接管与归还
registerKeyBindings()(ClientProxy.java:52-75)是幂等的状态机,
每次调用只有两个互斥分支:
接管(fullscreenKeyBinding == null 且总开关开):
fullscreenKeyBinding = mc.gameSettings.field_152395_am; // 备份原版键位
mc.gameSettings.field_152395_am = ignoreKeyBinding; // 换成永不触发的占位
if (Display.isFullscreen()) toggleFullScreen(true, Reference.AUTOMATIC_MONITOR_SELECTION);
最后一行处理"进游戏时 LWJGL 已经在真全屏"的情况,直接转成无边框。
归还(fullscreenKeyBinding != null 且总开关关):
mc.gameSettings.field_152395_am = fullscreenKeyBinding; // 还原
fullscreenKeyBinding = null;
if (currentState) mc.toggleFullscreen(); // 交回原版处理
注意归还路径调的是 mc.toggleFullscreen() 而非本 mod 的 toggleFullScreen——
此时配置已关、handler 不再接管,交给原版恢复。
状态判定的两处不一致
fullscreenKeyBinding 是 public static KeyBinding,两处读取它的判定写法不同:
| 位置 | 判定式 | 语义 |
|---|---|---|
KeyInputEventHandler#isCorrectKeyBinding |
fullscreenKeyBinding != null && fullscreenKeyBinding.isPressed() |
游戏中:按下沿触发一次 |
DrawScreenEventHandler#isCorrectKeyBinding |
fullscreenKeyBinding != null && Keyboard.isKeyDown(fullscreenKeyBinding.getKeyCode()) |
GUI 中:按住才触发 |
KeyInputEventHandler 额外做了一次 != null 判空(DrawScreenEventHandler 也做了),
两者都安全。GUI 路径用 getKeyCode() 绕过了 KeyBinding 自身的状态,
配合 _lastState 取沿——细节见 全屏切换流程 的"触发路径不一致"。
按下沿在未接管时天然失效
即便 fullscreenKeyBinding 仍指向原版键位对象(已被备份),
GUI 路径读到的 getKeyCode() 仍是原版键码、依然会触发;
isPressed() 路径则不受影响地读同一个对象。
但由于归还分支会把 fullscreenKeyBinding 置 null,
两条路径在关闭状态下都会因判空而直接返回。