全屏键位接管

基本信息

属性 值
本 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, 两条路径在关闭状态下都会因判空而直接返回。

相关条目