mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-25 12:13:00 +01:00
Move mouse support into windowsintegration
This commit is contained in:
parent
e3918079d7
commit
cdc44f0548
@ -389,3 +389,56 @@ BOOL MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPAR
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowsIntegration::setMouseEventHandler(MouseEventHandler handler)
|
||||
{
|
||||
m_mouseEventHandler = handler;
|
||||
}
|
||||
|
||||
LRESULT __stdcall WindowsIntegration::MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Initialize mouse event variables
|
||||
DWORD mouseButton = 0;
|
||||
UINT type = WM_MOUSEMOVE;
|
||||
POINT p {};
|
||||
|
||||
if (nCode >= 0) {
|
||||
switch (wParam) {
|
||||
case WM_LBUTTONDOWN:
|
||||
mouseButton = MK_LBUTTON;
|
||||
type = WM_LBUTTONDOWN;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
mouseButton = MK_LBUTTON;
|
||||
type = WM_LBUTTONUP;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
mouseButton = MK_RBUTTON;
|
||||
type = WM_RBUTTONDOWN;
|
||||
break;
|
||||
default:
|
||||
type = WM_MOUSEMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCursorPos(&p)) {
|
||||
// Check if the callback function is set and call it
|
||||
if (m_mouseEventHandler) {
|
||||
m_mouseEventHandler(mouseButton, type, p);
|
||||
}
|
||||
|
||||
} else {
|
||||
return CallNextHookEx(m_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
return CallNextHookEx(m_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
void WindowsIntegration::setupWindowMouseHook()
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
if (!(m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, hInstance, 0))) {
|
||||
OutputDebugStringW(L"Failed to install mouse hook!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,11 @@ struct sEnumInfo {
|
||||
HMONITOR hMonitor;
|
||||
};
|
||||
|
||||
// Define the type for the mouse event handler function
|
||||
using MouseEventHandler = std::function<void(DWORD mouseButton, UINT type, POINT p)>;
|
||||
static MouseEventHandler m_mouseEventHandler;
|
||||
static HHOOK m_mouseHook;
|
||||
|
||||
class WindowsIntegration {
|
||||
public:
|
||||
struct SpanResult {
|
||||
@ -105,6 +110,11 @@ public:
|
||||
void setWindowHandle(HWND windowHandle);
|
||||
void setWindowHandleWorker(HWND windowHandleWorker);
|
||||
|
||||
void setupWindowMouseHook();
|
||||
static LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
// Set the mouse event handler function
|
||||
void setMouseEventHandler(MouseEventHandler handler);
|
||||
|
||||
private:
|
||||
HWND m_windowHandle {};
|
||||
HWND m_windowHandleWorker {};
|
||||
|
@ -15,89 +15,6 @@
|
||||
\brief ScreenPlayWindow used for the Windows implementation.
|
||||
*/
|
||||
|
||||
HHOOK g_mouseHook;
|
||||
QPoint g_LastMousePosition { 0, 0 };
|
||||
QPoint g_globalOffset { 0, 0 };
|
||||
QQuickView* g_winGlobalHook = nullptr;
|
||||
|
||||
/*!
|
||||
\brief Windows mouse callback. This hook then forwards the event to the Qt window.
|
||||
We must manually call a release event otherwise QML gets stuck.
|
||||
*/
|
||||
LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
Qt::MouseButton mouseButton {};
|
||||
Qt::MouseButtons mouseButtons {};
|
||||
Qt::KeyboardModifier keyboardModifier {};
|
||||
QMouseEvent::Type type { QMouseEvent::Type::MouseMove };
|
||||
|
||||
if (nCode >= 0) {
|
||||
switch (wParam) {
|
||||
case WM_LBUTTONDOWN:
|
||||
mouseButton = Qt::MouseButton::LeftButton;
|
||||
mouseButtons.setFlag(Qt::LeftButton);
|
||||
type = QMouseEvent::Type::MouseButtonPress;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
mouseButton = Qt::MouseButton::LeftButton;
|
||||
mouseButtons.setFlag(Qt::LeftButton);
|
||||
type = QMouseEvent::Type::MouseButtonRelease;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
mouseButton = Qt::MouseButton::RightButton;
|
||||
mouseButtons.setFlag(Qt::RightButton);
|
||||
type = QMouseEvent::Type::MouseButtonPress;
|
||||
break;
|
||||
default:
|
||||
type = QMouseEvent::Type::MouseMove;
|
||||
}
|
||||
}
|
||||
|
||||
POINT p {};
|
||||
if (GetCursorPos(&p)) {
|
||||
g_LastMousePosition.setX(p.x);
|
||||
g_LastMousePosition.setY(p.y);
|
||||
} else {
|
||||
return CallNextHookEx(g_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
auto event = QMouseEvent(type, g_LastMousePosition, mouseButton, mouseButtons, keyboardModifier);
|
||||
|
||||
QGuiApplication::sendEvent(g_winGlobalHook, &event);
|
||||
|
||||
if (type == QMouseEvent::Type::MouseButtonPress) {
|
||||
}
|
||||
QTimer::singleShot(100, [&]() {
|
||||
// auto eventPress = QMouseEvent(QMouseEvent::Type::MouseButtonPress, g_LastMousePosition, mouseButton, mouseButtons, {});
|
||||
// qInfo() << mouseButton << QGuiApplication::sendEvent(g_winGlobalHook, &eventPress) << g_globalOffset.x() << g_globalOffset.y();
|
||||
auto eventRelease = QMouseEvent(QMouseEvent::Type::MouseButtonRelease, g_LastMousePosition, mouseButton, mouseButtons, {});
|
||||
QGuiApplication::sendEvent(g_winGlobalHook, &eventRelease);
|
||||
});
|
||||
|
||||
return CallNextHookEx(g_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Setup the SetWindowsHookEx hook to be used to receive mouse events.
|
||||
*/
|
||||
void WinWindow::setupWindowMouseHook()
|
||||
{
|
||||
using ScreenPlay::InstalledType::InstalledType;
|
||||
|
||||
// MUST be called before setting hook for events!
|
||||
if (type() != InstalledType::VideoWallpaper && type() != InstalledType::GifWallpaper) {
|
||||
qInfo() << "Enable mousehook";
|
||||
g_winGlobalHook = &m_window;
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
if (!(g_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, hInstance, 0))) {
|
||||
qInfo() << "Faild to install mouse hook!";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScreenPlay::WallpaperExitCode WinWindow::start()
|
||||
{
|
||||
connect(
|
||||
@ -143,13 +60,59 @@ ScreenPlay::WallpaperExitCode WinWindow::start()
|
||||
}
|
||||
}
|
||||
|
||||
QTimer::singleShot(1000, this, [&]() {
|
||||
setupWindowMouseHook();
|
||||
});
|
||||
|
||||
qInfo() << "Setup " << width() << height();
|
||||
m_window.setSource(QUrl("qrc:/qml/ScreenPlayWallpaper/qml/Wallpaper.qml"));
|
||||
m_window.show();
|
||||
|
||||
QTimer::singleShot(1000, this, [&]() {
|
||||
m_windowsIntegration.setupWindowMouseHook();
|
||||
// Set up the mouse event handler
|
||||
m_windowsIntegration.setMouseEventHandler([this](DWORD mouseButton, UINT type, POINT p) {
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
QEvent::Type eventType = QEvent::None;
|
||||
|
||||
// Determine the Qt mouse event type and button
|
||||
switch (type) {
|
||||
case WM_LBUTTONDOWN:
|
||||
eventType = QEvent::MouseButtonPress;
|
||||
button = Qt::LeftButton;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
eventType = QEvent::MouseButtonRelease;
|
||||
button = Qt::LeftButton;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
eventType = QEvent::MouseButtonPress;
|
||||
button = Qt::RightButton;
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
eventType = QEvent::MouseButtonRelease;
|
||||
button = Qt::RightButton;
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
eventType = QEvent::MouseMove;
|
||||
button = Qt::NoButton;
|
||||
break;
|
||||
// Add more cases as needed
|
||||
}
|
||||
|
||||
// Convert POINT to global position
|
||||
QPoint globalPos(p.x, p.y);
|
||||
|
||||
// Convert global position to local position within the target widget
|
||||
QPoint localPos = m_window.mapFromGlobal(globalPos);
|
||||
|
||||
// Create the QMouseEvent
|
||||
QMouseEvent* qEvent = new QMouseEvent(eventType, localPos, globalPos, button, button, QGuiApplication::keyboardModifiers());
|
||||
|
||||
// Handle the mouse event
|
||||
// For example, logging the mouse button and position
|
||||
qDebug() << "Mouse event: Button=" << mouseButton << ", Type=" << type
|
||||
<< ", Position=(" << p.x << ", " << p.y << ")" << globalPos << localPos << button;
|
||||
// Post the event to the target widget
|
||||
QCoreApplication::postEvent(&m_window, qEvent);
|
||||
});
|
||||
});
|
||||
return ScreenPlay::WallpaperExitCode::Ok;
|
||||
}
|
||||
|
||||
@ -254,7 +217,7 @@ void WinWindow::terminate()
|
||||
{
|
||||
using ScreenPlay::InstalledType::InstalledType;
|
||||
if (type() != InstalledType::VideoWallpaper && type() != InstalledType::GifWallpaper) {
|
||||
UnhookWindowsHookEx(g_mouseHook);
|
||||
// UnhookWindowsHookEx(g_mouseHook);
|
||||
}
|
||||
ShowWindow(m_windowsIntegration.windowHandle(), SW_HIDE);
|
||||
|
||||
|
@ -53,7 +53,6 @@ private:
|
||||
void setupWallpaperForOneScreen(int activeScreen);
|
||||
void setupWallpaperForAllScreens();
|
||||
void setupWallpaperForMultipleScreens(const QVector<int>& activeScreensList);
|
||||
void setupWindowMouseHook();
|
||||
void configureWindowGeometry();
|
||||
|
||||
private slots:
|
||||
|
Loading…
Reference in New Issue
Block a user