mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-14 13:22:27 +00:00
Add support for pasting clipboard text
This commit is contained in:
parent
36dc0f3e3c
commit
b83c6f0c28
5 changed files with 134 additions and 0 deletions
|
@ -134,6 +134,7 @@ SOURCES += \
|
|||
settings/mappingfetcher.cpp \
|
||||
settings/streamingpreferences.cpp \
|
||||
streaming/input/abstouch.cpp \
|
||||
streaming/input/clipboard.cpp \
|
||||
streaming/input/gamepad.cpp \
|
||||
streaming/input/input.cpp \
|
||||
streaming/input/keyboard.cpp \
|
||||
|
|
101
app/streaming/input/clipboard.cpp
Normal file
101
app/streaming/input/clipboard.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "input.h"
|
||||
|
||||
#define MAP_KEY(c, sc) \
|
||||
case c: \
|
||||
event.key.keysym.scancode = sc; \
|
||||
break
|
||||
|
||||
#define MAP_KEY_SHIFT(c, sc) \
|
||||
case c: \
|
||||
event.key.keysym.scancode = sc; \
|
||||
event.key.keysym.mod = KMOD_SHIFT; \
|
||||
break
|
||||
|
||||
void SdlInputHandler::sendText(const char* text)
|
||||
{
|
||||
for (const char* c = text; *c != 0; c++) {
|
||||
SDL_Event event = {};
|
||||
|
||||
if (*c >= 'A' && *c <= 'Z') {
|
||||
event.key.keysym.scancode = (SDL_Scancode)((*c - 'A') + SDL_SCANCODE_A);
|
||||
event.key.keysym.mod = KMOD_SHIFT;
|
||||
}
|
||||
else if (*c >= 'a' && *c <= 'z') {
|
||||
event.key.keysym.scancode = (SDL_Scancode)((*c - 'a') + SDL_SCANCODE_A);
|
||||
}
|
||||
else if (*c >= '1' && *c <= '9') {
|
||||
event.key.keysym.scancode = (SDL_Scancode)((*c - '1') + SDL_SCANCODE_1);
|
||||
}
|
||||
else {
|
||||
// TODO: Smartquotes
|
||||
switch (*c) {
|
||||
|
||||
// Handle CRLF separately to avoid duplicate newlines
|
||||
case '\r':
|
||||
if (*(c + 1) == '\n') {
|
||||
c++;
|
||||
}
|
||||
event.key.keysym.scancode = SDL_SCANCODE_RETURN;
|
||||
break;
|
||||
|
||||
MAP_KEY('\b', SDL_SCANCODE_BACKSPACE);
|
||||
MAP_KEY('\n', SDL_SCANCODE_RETURN);
|
||||
MAP_KEY('\t', SDL_SCANCODE_TAB);
|
||||
|
||||
MAP_KEY(' ', SDL_SCANCODE_SPACE);
|
||||
MAP_KEY_SHIFT('!', SDL_SCANCODE_1);
|
||||
MAP_KEY_SHIFT('"', SDL_SCANCODE_APOSTROPHE);
|
||||
MAP_KEY_SHIFT('#', SDL_SCANCODE_3);
|
||||
MAP_KEY_SHIFT('$', SDL_SCANCODE_4);
|
||||
MAP_KEY_SHIFT('%', SDL_SCANCODE_5);
|
||||
MAP_KEY_SHIFT('&', SDL_SCANCODE_7);
|
||||
MAP_KEY('\'', SDL_SCANCODE_APOSTROPHE);
|
||||
MAP_KEY_SHIFT('(', SDL_SCANCODE_9);
|
||||
MAP_KEY_SHIFT(')', SDL_SCANCODE_0);
|
||||
MAP_KEY_SHIFT('*', SDL_SCANCODE_8);
|
||||
MAP_KEY_SHIFT('+', SDL_SCANCODE_EQUALS);
|
||||
MAP_KEY(',', SDL_SCANCODE_COMMA);
|
||||
MAP_KEY('-', SDL_SCANCODE_MINUS);
|
||||
MAP_KEY('.', SDL_SCANCODE_PERIOD);
|
||||
MAP_KEY('/', SDL_SCANCODE_SLASH);
|
||||
MAP_KEY('0', SDL_SCANCODE_0);
|
||||
|
||||
MAP_KEY_SHIFT(':', SDL_SCANCODE_SEMICOLON);
|
||||
MAP_KEY(';', SDL_SCANCODE_SEMICOLON);
|
||||
MAP_KEY_SHIFT('<', SDL_SCANCODE_COMMA);
|
||||
MAP_KEY('=', SDL_SCANCODE_EQUALS);
|
||||
MAP_KEY_SHIFT('>', SDL_SCANCODE_PERIOD);
|
||||
MAP_KEY_SHIFT('?', SDL_SCANCODE_SLASH);
|
||||
MAP_KEY_SHIFT('@', SDL_SCANCODE_2);
|
||||
|
||||
MAP_KEY('[', SDL_SCANCODE_LEFTBRACKET);
|
||||
MAP_KEY('\\', SDL_SCANCODE_BACKSLASH);
|
||||
MAP_KEY(']', SDL_SCANCODE_RIGHTBRACKET);
|
||||
MAP_KEY_SHIFT('^', SDL_SCANCODE_6);
|
||||
MAP_KEY_SHIFT('_', SDL_SCANCODE_MINUS);
|
||||
MAP_KEY('`', SDL_SCANCODE_GRAVE);
|
||||
|
||||
MAP_KEY_SHIFT('{', SDL_SCANCODE_LEFTBRACKET);
|
||||
MAP_KEY_SHIFT('|', SDL_SCANCODE_BACKSLASH);
|
||||
MAP_KEY_SHIFT('}', SDL_SCANCODE_RIGHTBRACKET);
|
||||
MAP_KEY_SHIFT('~', SDL_SCANCODE_GRAVE);
|
||||
|
||||
default:
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Pasting text - non-ASCII character '%c' ignored",
|
||||
*c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
event.type = SDL_KEYDOWN;
|
||||
event.key.state = SDL_PRESSED;
|
||||
handleKeyEvent(&event.key);
|
||||
|
||||
SDL_Delay(10);
|
||||
|
||||
event.type = SDL_KEYUP;
|
||||
event.key.state = SDL_RELEASED;
|
||||
handleKeyEvent(&event.key);
|
||||
}
|
||||
}
|
|
@ -109,6 +109,11 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
|
|||
m_SpecialKeyCombos[KeyComboToggleMinimize].scanCode = SDL_SCANCODE_D;
|
||||
m_SpecialKeyCombos[KeyComboToggleMinimize].enabled = QGuiApplication::platformName() != "eglfs";
|
||||
|
||||
m_SpecialKeyCombos[KeyComboPasteText].keyCombo = KeyComboPasteText;
|
||||
m_SpecialKeyCombos[KeyComboPasteText].keyCode = SDLK_v;
|
||||
m_SpecialKeyCombos[KeyComboPasteText].scanCode = SDL_SCANCODE_V;
|
||||
m_SpecialKeyCombos[KeyComboPasteText].enabled = true;
|
||||
|
||||
m_OldIgnoreDevices = SDL_GetHint(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES);
|
||||
m_OldIgnoreDevicesExcept = SDL_GetHint(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT);
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
|
||||
void handleJoystickArrivalEvent(SDL_JoyDeviceEvent* event);
|
||||
|
||||
void sendText(const char* text);
|
||||
|
||||
void rumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor);
|
||||
|
||||
void handleTouchFingerEvent(SDL_TouchFingerEvent* event);
|
||||
|
@ -101,6 +103,7 @@ private:
|
|||
KeyComboToggleMouseMode,
|
||||
KeyComboToggleCursorHide,
|
||||
KeyComboToggleMinimize,
|
||||
KeyComboPasteText,
|
||||
KeyComboMax
|
||||
};
|
||||
|
||||
|
|
|
@ -87,6 +87,30 @@ void SdlInputHandler::performPendingSpecialKeyCombo()
|
|||
|
||||
SDL_MinimizeWindow(m_Window);
|
||||
break;
|
||||
|
||||
case KeyComboPasteText:
|
||||
{
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Detected paste text combo");
|
||||
const char* text = SDL_GetClipboardText();
|
||||
if (text != nullptr) {
|
||||
// Reset pending key combo before pasting,
|
||||
// otherwise it will ignore our keypresses.
|
||||
m_PendingKeyCombo = KeyComboMax;
|
||||
|
||||
// Send the text and free it as required by SDL
|
||||
sendText(text);
|
||||
SDL_free((void*)text);
|
||||
}
|
||||
else {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"No text in clipboard to paste!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
// Reset pending key combo
|
||||
|
|
Loading…
Reference in a new issue