From 87b441e890e6694e7efbebcce87326ce9c297145 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 3 Oct 2012 20:07:54 -0400 Subject: [PATCH 1/5] Fix no cursor on window frame and title bar. Remove mouse capture and handle visibility via WM_SETCURSOR messages instead of window activation events. See https://bitbucket.org/Skoader/cwe-ou/changeset/aed7e97d0df737dfd7bb6184011f00b91d92238b for original implementation --- Sources/Plasma/Apps/plClient/winmain.cpp | 21 ++++++++++++++++ .../PubUtilLib/plInputCore/plInputDevice.cpp | 24 ------------------- .../PubUtilLib/plInputCore/plInputDevice.h | 1 - .../PubUtilLib/plInputCore/plInputManager.cpp | 4 ---- .../PubUtilLib/plPipeline/plDXPipeline.cpp | 3 --- 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index 36ef2cf6..4efe1809 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -59,6 +59,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pfCrashHandler/plCrashCli.h" #include "plNetClient/plNetClientMgr.h" #include "plNetClient/plNetLinkingMgr.h" +#include "plInputCore/plInputDevice.h" #include "plInputCore/plInputManager.h" #include "plUnifiedTime/plUnifiedTime.h" #include "plPipeline.h" @@ -457,6 +458,26 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; + case WM_SETCURSOR: + { + static bool winCursor = true; + bool enterWnd = LOWORD(lParam) == HTCLIENT; + if (enterWnd && winCursor) + { + winCursor = !winCursor; + ShowCursor(winCursor != 0); + plMouseDevice::ShowCursor(); + } + else if (!enterWnd && !winCursor) + { + winCursor = !winCursor; + ShowCursor(winCursor != 0); + plMouseDevice::HideCursor(); + } + return TRUE; + } + break; + case WM_ACTIVATE: { bool active = (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE); diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp index fe0f4d5a..05830adc 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp @@ -750,27 +750,3 @@ bool plMouseDevice::MsgReceive(plMessage* msg) } return false; } - - - -void plMouseDevice::HandleWindowActivate(bool bActive, HWND hWnd) -{ - if ( bActive ) - { - RECT rect; - ::GetClientRect(hWnd,&rect); - -// rect.right /= plInputManager::GetInstance()->GetMouseScale(); -// rect.bottom /= plInputManager::GetInstance()->GetMouseScale(); - - ::MapWindowPoints( hWnd, NULL, (POINT *)&rect, 2 ); - ::ShowCursor( FALSE ); - SetCapture(hWnd); - - } - else - { - ReleaseCapture(); - ::ShowCursor( TRUE ); - } -} diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h index 0a3b2df6..e03943a1 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.h @@ -160,7 +160,6 @@ public: ~plMouseDevice(); const char* GetInputName() { return "mouse"; } - void HandleWindowActivate(bool bActive, hsWindowHndl hWnd); bool HasControlFlag(int f) const { return fControlFlags.IsBitSet(f); } void SetControlFlag(int f) diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp index aa0a8d1c..d4593d62 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputManager.cpp @@ -584,8 +584,6 @@ void plDInputMgr::AddDevice(IDirectInputDevice8* device) void plDInputMgr::ConfigureDevice() { ::ShowCursor( TRUE ); - ReleaseCapture(); - DICOLORSET dics; ZeroMemory(&dics, sizeof(DICOLORSET)); @@ -607,8 +605,6 @@ void plDInputMgr::ConfigureDevice() fDI->fSticks[i]->fDevice->SetActionMap( fDI->fActionFormat, NULL, DIDSAM_FORCESAVE ); ::ShowCursor( FALSE ); - SetCapture(fhWnd); - } bool plDInputMgr::MsgReceive(plMessage* msg) diff --git a/Sources/Plasma/PubUtilLib/plPipeline/plDXPipeline.cpp b/Sources/Plasma/PubUtilLib/plPipeline/plDXPipeline.cpp index d0c14736..00a67839 100644 --- a/Sources/Plasma/PubUtilLib/plPipeline/plDXPipeline.cpp +++ b/Sources/Plasma/PubUtilLib/plPipeline/plDXPipeline.cpp @@ -2247,7 +2247,6 @@ bool plDXPipeline::IResetDevice() { IClearShadowSlaves(); - ReleaseCapture(); Sleep(100); HRESULT coopLev = fD3DDevice->TestCooperativeLevel(); if( coopLev == D3DERR_DEVICELOST ) @@ -2295,8 +2294,6 @@ bool plDXPipeline::IResetDevice() /// all device-specific stuff needs to be recreated plDeviceRecreateMsg* clean = new plDeviceRecreateMsg(); plgDispatch::MsgSend(clean); - - SetCapture(fSettings.fHWnd); } fDevWasLost = true; fDeviceLost = false; From c090b44d5aad095ef386c56fef740f46881f3f51 Mon Sep 17 00:00:00 2001 From: Skoader Date: Wed, 3 Oct 2012 20:28:51 -0400 Subject: [PATCH 2/5] Fix clicking on the title bar does not activate the window. --- Sources/Plasma/Apps/plClient/winmain.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index 4efe1809..cd10e5a9 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -490,25 +490,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (gClient && !minimized && !gClient->GetDone()) { - if (LOWORD(wParam) == WA_CLICKACTIVE) - { - // See if they've clicked on the frame, in which case they just want to - // move, not activate, us. - POINT pt; - GetCursorPos(&pt); - ScreenToClient(hWnd, &pt); - - RECT rect; - GetClientRect(hWnd, &rect); - - if( (pt.x < rect.left) - ||(pt.x >= rect.right) - ||(pt.y < rect.top) - ||(pt.y >= rect.bottom) ) - { - active = false; - } - } gClient->WindowActivate(active); } else From cb48aab373facdb699d54857c2d2e236c046f512 Mon Sep 17 00:00:00 2001 From: Skoader Date: Wed, 3 Oct 2012 20:30:07 -0400 Subject: [PATCH 3/5] Fix no cursor when not the top level window. WM_MOUSEMOVE messages were only processed when the window was active. --- Sources/Plasma/Apps/plClient/winmain.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index cd10e5a9..ba7849e5 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -413,7 +413,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_LBUTTONUP : case WM_RBUTTONUP : case WM_MBUTTONUP : // The middle mouse button was released. - case WM_MOUSEMOVE : case 0x020A: // fuc&ing windows b.s... { if (gClient && gClient->WindowActive() && gClient->GetInputManager()) @@ -423,6 +422,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; + case WM_MOUSEMOVE: + { + if (gClient && gClient->GetInputManager()) + gClient->GetInputManager()->HandleWin32ControlEvent(message, wParam, lParam, hWnd); + } + break; + #if 0 case WM_KILLFOCUS: SetForegroundWindow(hWnd); From b90776fafe1a8b4fb0623d1307a22332d0ffe9a5 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 23 Oct 2012 23:21:50 -0400 Subject: [PATCH 4/5] Capture the mouse on clicks This hack prevents the cursor from leaving the window when panning the camera or changing directions quickly. This is important for those with high mouse sensitivities. --- Sources/Plasma/Apps/plClient/winmain.cpp | 48 +++++++++++++----------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index ba7849e5..56f600c1 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -395,32 +395,38 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) nc->ResetServerTimeOffset(true); break; - case WM_KEYDOWN : - case WM_LBUTTONDOWN : - case WM_RBUTTONDOWN : - case WM_LBUTTONDBLCLK : // The left mouse button was double-clicked. - case WM_MBUTTONDBLCLK : // The middle mouse button was double-clicked. - case WM_MBUTTONDOWN : // The middle mouse button was pressed. - case WM_RBUTTONDBLCLK : // The right mouse button was double-clicked. - // If they did anything but move the mouse, quit any intro movie playing. - { - if( gClient ) - gClient->SetQuitIntro(true); - } - // Fall through to other events + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_RBUTTONDBLCLK: + // Ensure we don't leave the client area during this action + SetCapture(hWnd); + // fall through to old case + case WM_KEYDOWN: case WM_CHAR: - case WM_KEYUP : - case WM_LBUTTONUP : - case WM_RBUTTONUP : - case WM_MBUTTONUP : // The middle mouse button was released. - case 0x020A: // fuc&ing windows b.s... + // If they did anything but move the mouse, quit any intro movie playing. + if (gClient) { - if (gClient && gClient->WindowActive() && gClient->GetInputManager()) - { + gClient->SetQuitIntro(true); + + // normal input processing + if (gClient->WindowActive() && gClient->GetInputManager()) gClient->GetInputManager()->HandleWin32ControlEvent(message, wParam, lParam, hWnd); - } } break; + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + // Stop hogging the cursor + ReleaseCapture(); + // fall through to input processing + case WM_MOUSEWHEEL: + case WM_KEYUP: + if (gClient && gClient->WindowActive() && gClient->GetInputManager()) + gClient->GetInputManager()->HandleWin32ControlEvent(message, wParam, lParam, hWnd); + break; case WM_MOUSEMOVE: { From 336f1c40ad11d73bc92dafa65c8b63031deab726 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sat, 3 Nov 2012 01:22:56 -0400 Subject: [PATCH 5/5] Track mouse ups/downs for releasing purposes --- Sources/Plasma/Apps/plClient/winmain.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index 56f600c1..03920d34 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -371,7 +371,7 @@ void DebugMsgF(const char* format, ...); LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static bool gDragging = false; - static uint32_t keyState=0; + static uint8_t mouse_down = 0; // Messages we registered for manually (no const value) if (message == s_WmTaskbarList) @@ -401,8 +401,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_RBUTTONDBLCLK: - // Ensure we don't leave the client area during this action - SetCapture(hWnd); + // Ensure we don't leave the client area during clicks + if (!(mouse_down++)) + SetCapture(hWnd); // fall through to old case case WM_KEYDOWN: case WM_CHAR: @@ -420,7 +421,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_RBUTTONUP: case WM_MBUTTONUP: // Stop hogging the cursor - ReleaseCapture(); + if (!(--mouse_down)) + ReleaseCapture(); // fall through to input processing case WM_MOUSEWHEEL: case WM_KEYUP: