bayaraa / d2gl

Diablo 2 LoD Glide/DDraw to OpenGL Wrapper
GNU General Public License v3.0
178 stars 30 forks source link

keys and clicks are being held down during window switching #108

Closed BeLikeLeBron closed 9 months ago

BeLikeLeBron commented 1 year ago

Keys and clicks are being held down during window switching. So you can be casting something or walking somewhere and swap windows or alt+tab/win+# away while holding the click and it will continue to walk/cast in the background. Can be very dangerous and get you killed in HC. Reproducible The below code fixes it for unlocked cursor users only but it's still broken for locked cursor users. i noticed it 'locks' cursor on the right side of d2 window in lobby as well though even with unlocked cursor.(credit Ajtos)

image

tried the below for locked cursor users and it fixes it but breaks a ton of border issues with locked cursors, so it's a no-go

image

Hope that's helpful. Thank you! D2GL is amazing!

youbetterdont commented 1 year ago

I looked at this issue for awhile today and then talked with @IAmTrial, and he had a suggestion that seems to fix the issue as well as the issue with alt+tab window switching occasionally requiring an extra click.

The modifications are to the WndProc function in win32.cpp as follows:

        case WM_ACTIVATEAPP: {
            const bool fps_capped = !App.vsync && App.foreground_fps.active;

            if (wParam) {
                App.context->setFpsLimit(fps_capped, App.foreground_fps.range.value);
                CallWindowProcA(App.wndproc, hWnd, WM_SYSKEYUP, VK_MENU, 0);
                if (!option::Menu::instance().isVisible()) {
                    setCursorLock();
                }
            } else {
                App.context->setFpsLimit(App.background_fps.active || fps_capped, App.background_fps.active ? App.background_fps.range.value : App.foreground_fps.range.value);
                if (App.window.fullscreen && App.window.auto_minimize)
                    PostMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
                POINTS points;
                points.x = *d2::mouse_x;
                points.y = *d2::mouse_y;
                LPARAM xy = MAKELPARAM(points.x, points.y);
                SendMessage(hWnd, WM_LBUTTONUP, 0, xy);
                setCursorUnlock();
            }
            return 0;
        }
ajtos commented 1 year ago

Based on discussion with @youbetterdont , more cleaner and better long term solution would be to pass WM_ACTIVATEAPP message unconditionally to D2 (this is what D2DX does by default as reference), like that:

        case WM_ACTIVATEAPP: {
            (...)
            break;
        }

Only issue is that most versions of D2, will minimize, when they receive WM_ACTIVATEAPP with wParam == FALSE, when in fullscreen. This isn't a problem for D2DX, since I assume it patches this behavior out in D2 somewhere. D2GL seems to be using most of code edits present in D2DX at first glance and I wasn't able to trace where difference is.

@IAmTrial pointed out that he has code edits that disable "auto minimize" in form of https://github.com/mir-diablo-ii-tools/SlashGaming-Diablo-II-Free-DeMin I didn't do much testing, but with those applied to base D2 v1.10, WM_ACTIVATEAPP can be passed directly do underlying D2, which fixes issue with keys/mouse button being "stuck", while alt+tabbing in D2GL.

bayaraa commented 9 months ago

Fixed in 1.3.2.