1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-07-19 02:54:47 +02:00

Add key input support to qml wallpaper

This commit is contained in:
Elias Steurer 2023-11-03 12:44:54 +01:00
parent cdc44f0548
commit 067b953526
6 changed files with 263 additions and 15 deletions

View File

@ -3,6 +3,7 @@ import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material
import ScreenPlayWallpaper
Rectangle {
id: root
@ -23,5 +24,16 @@ Rectangle {
Layout.fillWidth: true
onClicked: root.counter++
}
TextField {
placeholderText: "Edit me"
}
Button {
text: "Exit"
onClicked: {
Qt.callLater(function () {
Wallpaper.terminate();
});
}
}
}
}

View File

@ -164,6 +164,7 @@ Rectangle {
}
Row {
id: rowCounter
spacing: 20
anchors {
@ -205,18 +206,30 @@ Rectangle {
}
}
// WebView {
// width: 1000
// height: 400
// url: "https://screen-play.app"
Column {
anchors {
horizontalCenter: parent.horizontalCenter
top: rowCounter.bottom
topMargin: 20
}
spacing: 20
TextField {
placeholderText: "Edit me"
}
Button {
text: "Exit"
onClicked: {
Qt.callLater(function () {
Wallpaper.terminate();
});
}
}
}
// anchors {
// horizontalCenter: parent.horizontalCenter
// bottom: parent.bottom
// bottomMargin: 50
// }
// }
MultimediaView {
width: 1000
height: 400

View File

@ -442,3 +442,46 @@ void WindowsIntegration::setupWindowMouseHook()
return;
}
}
void WindowsIntegration::setupWindowKeyboardHook()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
if (!(m_keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookCallback, hInstance, 0))) {
OutputDebugStringW(L"Failed to install keyboard hook!");
return;
}
}
void WindowsIntegration::setKeyboardEventHandler(KeyboardEventHandler handler)
{
m_keyboardEventHandler = std::move(handler);
}
LRESULT __stdcall WindowsIntegration::KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0) {
KBDLLHOOKSTRUCT* kbStruct = (KBDLLHOOKSTRUCT*)lParam;
bool keyDown = wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN;
// Check if the callback function is set and call it
if (m_keyboardEventHandler) {
m_keyboardEventHandler(kbStruct->vkCode, keyDown);
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
void WindowsIntegration::unhookMouse()
{
if (m_mouseHook != NULL) {
UnhookWindowsHookEx(m_mouseHook);
m_mouseHook = NULL;
}
}
void WindowsIntegration::unhookKeyboard()
{
if (m_keyboardHook != NULL) {
UnhookWindowsHookEx(m_keyboardHook);
m_keyboardHook = NULL;
}
}

View File

@ -87,6 +87,10 @@ struct sEnumInfo {
using MouseEventHandler = std::function<void(DWORD mouseButton, UINT type, POINT p)>;
static MouseEventHandler m_mouseEventHandler;
static HHOOK m_mouseHook;
// Define a callback type for keyboard events
typedef std::function<void(UINT vkCode, bool keyDown)> KeyboardEventHandler;
static HHOOK m_keyboardHook;
static KeyboardEventHandler m_keyboardEventHandler;
class WindowsIntegration {
public:
@ -111,9 +115,14 @@ public:
void setWindowHandleWorker(HWND windowHandleWorker);
void setupWindowMouseHook();
static LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
// Set the mouse event handler function
void unhookMouse();
void setMouseEventHandler(MouseEventHandler handler);
static LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
void setupWindowKeyboardHook();
void unhookKeyboard();
void setKeyboardEventHandler(KeyboardEventHandler handler);
static LRESULT __stdcall KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
private:
HWND m_windowHandle {};

View File

@ -112,6 +112,26 @@ ScreenPlay::WallpaperExitCode WinWindow::start()
// Post the event to the target widget
QCoreApplication::postEvent(&m_window, qEvent);
});
// Inside your main application or somewhere appropriate
m_windowsIntegration.setupWindowKeyboardHook();
// Set up the keyboard event handler
m_windowsIntegration.setKeyboardEventHandler([this](UINT vkCode, bool keyDown) {
QEvent::Type eventType = keyDown ? QEvent::KeyPress : QEvent::KeyRelease;
// Map the vkCode to Qt key code if necessary
auto [qtKey, text] = mapVirtualKeyToQtKey(vkCode); // Implement this function based on your needs
// Create the QKeyEvent
QKeyEvent* qEvent = new QKeyEvent(eventType, qtKey, Qt::NoModifier, text);
// Handle the keyboard event
// For example, logging the key press
qDebug() << "Keyboard event: Key=" << vkCode << ", Type=" << (keyDown ? "KeyDown" : "KeyUp") << qEvent;
// Post the event to the target widget
QCoreApplication::postEvent(&m_window, qEvent);
});
});
return ScreenPlay::WallpaperExitCode::Ok;
}
@ -209,6 +229,155 @@ void WinWindow::configureWindowGeometry()
m_window.show();
}
std::tuple<int, QString> WinWindow::mapVirtualKeyToQtKey(UINT vkCode)
{
switch (vkCode) {
case VK_BACK:
return { Qt::Key_Backspace, QString() };
case VK_TAB:
return { Qt::Key_Tab, QString("\t") };
case VK_CLEAR:
return { Qt::Key_Clear, QString() };
case VK_RETURN:
return { Qt::Key_Return, QString("\r") };
// ... rest of the cases ...
case VK_SPACE:
return { Qt::Key_Space, QString(" ") };
// Extra keys
case 0x21: // '!'
return { Qt::Key_Exclam, QString("!") };
case 0x40: // '@'
return { Qt::Key_At, QString("@") };
case 0x23: // '#'
return { Qt::Key_NumberSign, QString("#") };
case 0x24: // '$'
return { Qt::Key_Dollar, QString("$") };
case 0x25: // '%'
return { Qt::Key_Percent, QString("%") };
case 0x5E: // '^'
return { Qt::Key_AsciiCircum, QString("^") };
case 0x26: // '&'
return { Qt::Key_Ampersand, QString("&") };
case 0x2A: // '*'
return { Qt::Key_Asterisk, QString("*") };
case 0x28: // '('
return { Qt::Key_ParenLeft, QString("(") };
case 0x29: // ')'
return { Qt::Key_ParenRight, QString(")") };
case 0x5F: // '_'
return { Qt::Key_Underscore, QString("_") };
case 0x2B: // '+'
return { Qt::Key_Plus, QString("+") };
case 0x2D: // '-'
return { Qt::Key_Minus, QString("-") };
case 0x3D: // '='
return { Qt::Key_Equal, QString("=") };
case 0x5B: // '['
return { Qt::Key_BracketLeft, QString("[") };
case 0x5D: // ']'
return { Qt::Key_BracketRight, QString("]") };
case 0x7B: // '{'
return { Qt::Key_BraceLeft, QString("{") };
case 0x7D: // '}'
return { Qt::Key_BraceRight, QString("}") };
case 0x3B: // ';'
return { Qt::Key_Semicolon, QString(";") };
case 0x27: // '''
return { Qt::Key_Apostrophe, QString("'") };
case 0x3A: // ':'
return { Qt::Key_Colon, QString(":") };
case 0x22: // '"'
return { Qt::Key_QuoteDbl, QString("\"") };
case 0x2F: // '/'
return { Qt::Key_Slash, QString("/") };
case 0x2E: // '.'
return { Qt::Key_Period, QString(".") };
case 0x3E: // '>'
return { Qt::Key_Greater, QString(">") };
case 0x2C: // ','
return { Qt::Key_Comma, QString(",") };
case 0x3F: // '?'
return { Qt::Key_Question, QString("?") };
// Numeric keys
case 0x30:
return { Qt::Key_0, QString("0") };
case 0x31:
return { Qt::Key_1, QString("1") };
case 0x32:
return { Qt::Key_2, QString("2") };
case 0x33:
return { Qt::Key_3, QString("3") };
case 0x34:
return { Qt::Key_4, QString("4") };
case 0x35:
return { Qt::Key_5, QString("5") };
case 0x36:
return { Qt::Key_6, QString("6") };
case 0x37:
return { Qt::Key_7, QString("7") };
case 0x38:
return { Qt::Key_8, QString("8") };
case 0x39:
return { Qt::Key_9, QString("9") };
// Alphabet keys
case 0x41:
return { Qt::Key_A, QString("a") };
case 0x42:
return { Qt::Key_B, QString("b") };
case 0x43:
return { Qt::Key_C, QString("c") };
case 0x44:
return { Qt::Key_D, QString("d") };
case 0x45:
return { Qt::Key_E, QString("e") };
case 0x46:
return { Qt::Key_F, QString("f") };
case 0x47:
return { Qt::Key_G, QString("g") };
case 0x48:
return { Qt::Key_H, QString("h") };
case 0x49:
return { Qt::Key_I, QString("i") };
case 0x4A:
return { Qt::Key_J, QString("j") };
case 0x4B:
return { Qt::Key_K, QString("k") };
case 0x4C:
return { Qt::Key_L, QString("l") };
case 0x4D:
return { Qt::Key_M, QString("m") };
case 0x4E:
return { Qt::Key_N, QString("n") };
case 0x4F:
return { Qt::Key_O, QString("o") };
case 0x50:
return { Qt::Key_P, QString("p") };
case 0x51:
return { Qt::Key_Q, QString("q") };
case 0x52:
return { Qt::Key_R, QString("r") };
case 0x53:
return { Qt::Key_S, QString("s") };
case 0x54:
return { Qt::Key_T, QString("t") };
case 0x55:
return { Qt::Key_U, QString("u") };
case 0x56:
return { Qt::Key_V, QString("v") };
case 0x57:
return { Qt::Key_W, QString("w") };
case 0x58:
return { Qt::Key_X, QString("x") };
case 0x59:
return { Qt::Key_Y, QString("y") };
case 0x5A:
return { Qt::Key_Z, QString("z") };
default:
return { Qt::Key_unknown, QString() };
}
}
/*!
\brief Custom exit method to force a redraw of the window so that
the default desktop wallpaper can be seen agian.
@ -216,9 +385,7 @@ void WinWindow::configureWindowGeometry()
void WinWindow::terminate()
{
using ScreenPlay::InstalledType::InstalledType;
if (type() != InstalledType::VideoWallpaper && type() != InstalledType::GifWallpaper) {
// UnhookWindowsHookEx(g_mouseHook);
}
ShowWindow(m_windowsIntegration.windowHandle(), SW_HIDE);
// Force refresh so that we display the regular
@ -226,6 +393,9 @@ void WinWindow::terminate()
ShowWindow(m_windowsIntegration.windowHandleWorker(), SW_HIDE);
ShowWindow(m_windowsIntegration.windowHandleWorker(), SW_SHOW);
m_windowsIntegration.unhookKeyboard();
m_windowsIntegration.unhookMouse();
QGuiApplication::quit();
}

View File

@ -54,6 +54,7 @@ private:
void setupWallpaperForAllScreens();
void setupWallpaperForMultipleScreens(const QVector<int>& activeScreensList);
void configureWindowGeometry();
std::tuple<int, QString> mapVirtualKeyToQtKey(UINT vkCode);
private slots:
void checkForFullScreenWindow();