mojira.dev
MC-156810

Binding inventory key to mouse buttons does not allow the inventory to close without pressing ESC

When the inventory button is binded to its default button, E, the inventory can open and close normally via this button. When I rebind this to Mouse 4 (the button on the mouse that's off to the side by my thumb and closest to me), I can only open the inventory with this button and not close. This isn't like the other issues where they're binding to TAB, which is default the button to open player menu, this is a button that is not reserved for any other function by default. 

Code Analysis:

Code analysis by @unknown can be found in this comment.

Related issues

Comments

qwerty23495

Relates to MC-145691

violine1101

Can confirm. Only happened in the creative search menu, and I was experiencing MC-159967 as well.

migrated

I play dota 2 and there i use mouse button 5 to open inventory. I'd like to open my inventory with mb5 on minecraft aswell, so that i get that worked into my memory and dont have to switch which button i use when i switch between the games. However, i cant close the inventory with mb5. Same problem with mb4.

migrated

Comfirmed for 20w27a.

Open/Close Inventory Button bound to 'Button 4' does not close the inventory, only open

migrated

Update: I've discovered a workaround. I run the Logitech G Suite to create custom keybinds so it might not work for everyone. I've designated the OPEN/CLOSE option in Minecraft to be bound to "G" and designated Mouse Button 4 to function as my "G" key through G Suite. Works flawlessly. I do still think it should be a functioning product just through the Minecraft control options but for now I can open/close seamlessly with my mouse. Hope that can help someone!

It feels entirely too natural to me to think that I've never been able to do this. I've even attempted to bind the escape key to another key on my mouse through my mouse program without luck. In order to close inventory no matter how it's opened (unless using default) I must press the ESC key. I'm sure there's a mod to fix it but I'm not sure why it's an issue to begin with when all other functions work appropriately when bound to additional mouse buttons. 

migrated

Still an issue, 4 years after being reported.

Apollo30

Code Analysis:

The following is based on a decompiled version of Minecraft 1.20.1 using MCP-Reborn.

net.minecraft.client.MouseHandler.java // Original

public class MouseHandler {
    ...
    private void onPress(long p_91531_, int p_91532_, int p_91533_, int p_91534_) {
        if (p_91531_ == this.minecraft.getWindow().getWindow()) {
            if (this.minecraft.screen != null) {
                this.minecraft.setLastInputType(InputType.MOUSE);
            }
 
            boolean flag = p_91533_ == 1;
            if (Minecraft.ON_OSX && p_91532_ == 0) {
                if (flag) {
                    if ((p_91534_ & 2) == 2) {
                        p_91532_ = 1;
                        ++this.fakeRightMouse;
                    }
                } else if (this.fakeRightMouse > 0) {
                    p_91532_ = 1;
                    --this.fakeRightMouse;
                }
            }
 
            int i = p_91532_;
            if (flag) {
                if (this.minecraft.options.touchscreen().get() && this.clickDepth++ > 0) {
                    return;
                }
 
                this.activeButton = i;
                this.mousePressedTime = Blaze3D.getTime();
            } else if (this.activeButton != -1) {
                if (this.minecraft.options.touchscreen().get() && --this.clickDepth > 0) {
                    return;
                }                this.activeButton = -1;
            }
 
            boolean[] aboolean = new boolean[] {
                false
            };
             
            if (this.minecraft.getOverlay() == null) {
                if (this.minecraft.screen == null) {
                    if (!this.mouseGrabbed && flag) {
                        this.grabMouse();
                    }
                } else {
                    double d0 = this.xpos * (double) this.minecraft.getWindow().getGuiScaledWidth() / (double) this.minecraft.getWindow().getScreenWidth();
                    double d1 = this.ypos * (double) this.minecraft.getWindow().getGuiScaledHeight() / (double) this.minecraft.getWindow().getScreenHeight();
                    Screen screen = this.minecraft.screen;
                    if (flag) {
                        screen.afterMouseAction();
                        Screen.wrapScreenError(() - > {
                            aboolean[0] = screen.mouseClicked(d0, d1, i);
                        }, "mouseClicked event handler", screen.getClass().getCanonicalName());
                    } else {
                        Screen.wrapScreenError(() - > {
                            aboolean[0] = screen.mouseReleased(d0, d1, i);
                        }, "mouseReleased event handler", screen.getClass().getCanonicalName());
                    }
                }
            }
 
            if (!aboolean[0] && this.minecraft.screen == null && this.minecraft.getOverlay() == null) {
                if (i == 0) {
                    this.isLeftPressed = flag;
                } else if (i == 2) {
                    this.isMiddlePressed = flag;
                } else if (i == 1) {
                    this.isRightPressed = flag;
                }                KeyMapping.set(InputConstants.Type.MOUSE.getOrCreate(i), flag);
                if (flag) {
                    if (this.minecraft.player.isSpectator() && i == 2) {
                        this.minecraft.gui.getSpectatorGui().onMouseMiddleClick();
                    } else {
                        KeyMapping.click(InputConstants.Type.MOUSE.getOrCreate(i));
                    }
                }
            }
        }
    }
    ...
}

As we can see, we create a variable called flag, flag represents a boolean which is either true or false. I couldn't find the determination of what makes flag true, but my assumption is if the player has no external screen opened. If flag is false, then it will trigger the method Screen#wrapScreenError which will unpress the mouse keybind as it is setting aboolean[0] to true.

My solution is to remove that else statement, but there could be underlying bugs as I don't quite understand what that statement does. But that piece of code should be the root problem of why keybinds don't work with any mouse input since it's being occupied with an opened inventory.

migrated

you wont believe it - but it's still an issue in 2024 (1.20.4) - can only open, but not close inventory with custom mouse bottom - need to use ESC to close it...

works flawlessly on bedrock...

migrated

(Unassigned)

Community Consensus

Platform

Low

Input, UI

Minecraft 1.14.3, Minecraft 1.14.4 Pre-Release 5, 1.15.2, 20w21a, 1.16 Release Candidate 1, ..., 1.17.1, 1.20.1, 1.20.4, 1.21.1, 1.21.3

Retrieved