Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2015-09-24 01:31:21 +0300
committerKacper Michajłow <kasper93@gmail.com>2015-09-24 22:34:54 +0300
commit19e47dff6c349eb030e1456241272e15c4d71245 (patch)
treeda5e3073a5302fca9c5de4037f2cee9a055a8409
parente5f6b2c79ce1a211b71fa713f686e7acf6422f37 (diff)
Mouse: Adjust mouse behavior for Windows 10.
Mouse messages are dispatched to the focused window first, but if it isn't interested message will be dispatched to the root window instead. Closes #5248
-rw-r--r--docs/Changelog.txt1
-rw-r--r--src/mpc-hc/MouseTouch.cpp14
-rw-r--r--src/mpc-hc/MouseTouch.h75
3 files changed, 47 insertions, 43 deletions
diff --git a/docs/Changelog.txt b/docs/Changelog.txt
index a86f5f5a3..4b0f02777 100644
--- a/docs/Changelog.txt
+++ b/docs/Changelog.txt
@@ -39,6 +39,7 @@ next version - not released yet
! QuickTime: Fix a crash when using system default renderer
! Fix "snap to desktop edge" and "autofit zoom" on Windows 10
! Ticket #4086, Logitech LCD: Correctly initialize the volume at start-up
+! Ticket #5248, Adjust mouse behavior for Windows 10
! Ticket #5454, Deleting an item from the playlist sometimes did not work when shuffle mode was enabled
! Ticket #5464, If the main window was minimized while the D3D Fullscreen window was displayed on another screen,
it was impossible to use the mouse buttons to play, pause, exit fullscreen, etc.
diff --git a/src/mpc-hc/MouseTouch.cpp b/src/mpc-hc/MouseTouch.cpp
index 39f1d8b8f..9812dda23 100644
--- a/src/mpc-hc/MouseTouch.cpp
+++ b/src/mpc-hc/MouseTouch.cpp
@@ -1,5 +1,5 @@
/*
- * (C) 2013-2014 see Authors.txt
+ * (C) 2013-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -635,15 +635,15 @@ void CMouseWnd::OnDestroy()
CWnd::OnDestroy();
}
-std::vector<CWnd*> CMainFrameMouseHook::GetRoots()
+std::unordered_set<const CWnd*> CMainFrameMouseHook::GetRoots()
{
- std::vector<CWnd*> ret;
- ret.reserve(2);
- CMainFrame* pMainFrame = AfxGetMainFrame();
+ std::unordered_set<const CWnd*> ret;
+ const CMainFrame* pMainFrame = AfxGetMainFrame();
+ ASSERT(pMainFrame);
if (pMainFrame) {
- ret.emplace_back(pMainFrame);
+ ret.emplace(pMainFrame);
if (pMainFrame->IsD3DFullScreenMode()) {
- ret.emplace_back(pMainFrame->m_pFullscreenWnd);
+ ret.emplace(pMainFrame->m_pFullscreenWnd);
}
}
return ret;
diff --git a/src/mpc-hc/MouseTouch.h b/src/mpc-hc/MouseTouch.h
index 8e094fc2a..806bc2b82 100644
--- a/src/mpc-hc/MouseTouch.h
+++ b/src/mpc-hc/MouseTouch.h
@@ -21,9 +21,10 @@
#pragma once
#include <map>
-#include <vector>
+#include <unordered_set>
#include "EventDispatcher.h"
+#include "SysVersion.h"
// TODO: handle touch gestures
@@ -169,45 +170,45 @@ private:
template <class T>
class CMouseWheelHook
{
- HHOOK m_hHook;
+ HHOOK m_hHook = NULL;
static LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION && wParam == WM_MOUSEWHEEL) {
const auto& msex = *reinterpret_cast<MOUSEHOOKSTRUCTEX*>(lParam);
- if (CWnd* pFocus = CWnd::FromHandlePermanent(msex.hwnd)) {
- if (CWnd* pFocusRoot = pFocus->GetAncestor(GA_ROOT)) {
- for (CWnd* pRoot : T::GetRoots()) {
- ASSERT(pRoot);
- // only intercept messages to focused windows that have white-listed root windows
- if (pRoot && *pRoot == *pFocusRoot) {
- if (CWnd* pUnder = CWnd::WindowFromPoint(msex.pt)) {
- if (CWnd* pUnderRoot = pUnder->GetAncestor(GA_ROOT)) {
- if (*pUnderRoot == *pFocusRoot &&
- GetCurrentThreadId() == GetWindowThreadProcessId(pUnder->m_hWnd, nullptr)) {
- // prepare MSG struct
- MSG msg = {
- pUnder->m_hWnd,
- wParam,
- CMouse::GetMouseFlags() | msex.mouseData,
- MAKELPARAM(msex.pt.x, msex.pt.y),
- GetMessageTime(),
- msex.pt
- };
-
- // walk through pre-translate
- if (CWnd::WalkPreTranslateTree(pUnderRoot->m_hWnd, &msg)) {
- // the message shouldn't be dispatched
- return TRUE;
- }
-
- // dispatch the message
- if (msg.hwnd) {
- DispatchMessage(&msg);
- }
+ if (const CWnd* pFocus = CWnd::FromHandlePermanent(msex.hwnd)) {
+ if (const CWnd* pFocusRoot = pFocus->GetAncestor(GA_ROOT)) {
+ // only intercept messages to focused windows that have white-listed root windows
+ if (T::GetRoots().count(pFocusRoot)) {
+ if (const CWnd* pUnder = CWnd::WindowFromPoint(msex.pt)) {
+ if (pFocusRoot == pUnder->GetAncestor(GA_ROOT) &&
+ GetCurrentThreadId() == GetWindowThreadProcessId(pUnder->m_hWnd, nullptr)) {
+ MSG msg = {
+ NULL,
+ static_cast<UINT>(wParam),
+ CMouse::GetMouseFlags() | msex.mouseData,
+ MAKELPARAM(msex.pt.x, msex.pt.y),
+ GetMessageTime(),
+ msex.pt
+ };
+
+ for (const CWnd* pTarget : { pUnder, pFocusRoot }) {
+ msg.hwnd = pTarget->m_hWnd;
+ if (!msg.hwnd) {
+ ASSERT(FALSE);
+ continue;
+ }
+
+ // walk through pre-translate
+ if (CWnd::WalkPreTranslateTree(pFocusRoot->m_hWnd, &msg)) {
+ // the message shouldn't be dispatched
+ continue;
+ }
+
+ if (DispatchMessage(&msg)) {
+ return TRUE;
}
}
}
- return TRUE;
}
}
}
@@ -218,8 +219,10 @@ class CMouseWheelHook
public:
CMouseWheelHook() {
- m_hHook = SetWindowsHookEx(WH_MOUSE, MouseProc, nullptr, GetCurrentThreadId());
- ASSERT(m_hHook);
+ if (SysVersion::Is10OrLater()) {
+ m_hHook = SetWindowsHookEx(WH_MOUSE, MouseProc, nullptr, GetCurrentThreadId());
+ ASSERT(m_hHook);
+ }
}
virtual ~CMouseWheelHook() {
@@ -230,5 +233,5 @@ public:
};
struct CMainFrameMouseHook : CMouseWheelHook<CMainFrameMouseHook> {
- static std::vector<CWnd*> GetRoots();
+ static std::unordered_set<const CWnd*> GetRoots();
};