mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-03 08:15:37 +00:00
Add support for system key capture in windowed mode on macOS
This commit is contained in:
parent
28ecc6bcbf
commit
b27ca993aa
@ -68,12 +68,6 @@ SystemProperties::SystemProperties()
|
|||||||
hasDiscordIntegration = false;
|
hasDiscordIntegration = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
|
||||||
supportsWindowedSystemKeyCapture = false;
|
|
||||||
#else
|
|
||||||
supportsWindowedSystemKeyCapture = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unmappedGamepads = SdlInputHandler::getUnmappedGamepads();
|
unmappedGamepads = SdlInputHandler::getUnmappedGamepads();
|
||||||
|
|
||||||
// Populate data that requires talking to SDL. We do it all in one shot
|
// Populate data that requires talking to SDL. We do it all in one shot
|
||||||
|
@ -19,7 +19,6 @@ public:
|
|||||||
Q_PROPERTY(bool hasWindowManager MEMBER hasWindowManager CONSTANT)
|
Q_PROPERTY(bool hasWindowManager MEMBER hasWindowManager CONSTANT)
|
||||||
Q_PROPERTY(bool hasBrowser MEMBER hasBrowser CONSTANT)
|
Q_PROPERTY(bool hasBrowser MEMBER hasBrowser CONSTANT)
|
||||||
Q_PROPERTY(bool hasDiscordIntegration MEMBER hasDiscordIntegration CONSTANT)
|
Q_PROPERTY(bool hasDiscordIntegration MEMBER hasDiscordIntegration CONSTANT)
|
||||||
Q_PROPERTY(bool supportsWindowedSystemKeyCapture MEMBER supportsWindowedSystemKeyCapture CONSTANT)
|
|
||||||
Q_PROPERTY(QString unmappedGamepads MEMBER unmappedGamepads NOTIFY unmappedGamepadsChanged)
|
Q_PROPERTY(QString unmappedGamepads MEMBER unmappedGamepads NOTIFY unmappedGamepadsChanged)
|
||||||
Q_PROPERTY(int maximumStreamingFrameRate MEMBER maximumStreamingFrameRate CONSTANT)
|
Q_PROPERTY(int maximumStreamingFrameRate MEMBER maximumStreamingFrameRate CONSTANT)
|
||||||
Q_PROPERTY(QSize maximumResolution MEMBER maximumResolution CONSTANT)
|
Q_PROPERTY(QSize maximumResolution MEMBER maximumResolution CONSTANT)
|
||||||
@ -44,7 +43,6 @@ private:
|
|||||||
bool hasWindowManager;
|
bool hasWindowManager;
|
||||||
bool hasBrowser;
|
bool hasBrowser;
|
||||||
bool hasDiscordIntegration;
|
bool hasDiscordIntegration;
|
||||||
bool supportsWindowedSystemKeyCapture;
|
|
||||||
QString unmappedGamepads;
|
QString unmappedGamepads;
|
||||||
int maximumStreamingFrameRate;
|
int maximumStreamingFrameRate;
|
||||||
QSize maximumResolution;
|
QSize maximumResolution;
|
||||||
|
@ -911,8 +911,7 @@ Flickable {
|
|||||||
id: captureSysKeysCheck
|
id: captureSysKeysCheck
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: qsTr("Capture system keyboard shortcuts") + (SystemProperties.supportsWindowedSystemKeyCapture ?
|
text: qsTr("Capture system keyboard shortcuts")
|
||||||
"" : qsTr(" while streaming in fullscreen mode"))
|
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
enabled: SystemProperties.hasWindowManager
|
enabled: SystemProperties.hasWindowManager
|
||||||
checked: StreamingPreferences.captureSysKeys && SystemProperties.hasWindowManager
|
checked: StreamingPreferences.captureSysKeys && SystemProperties.hasWindowManager
|
||||||
|
@ -171,6 +171,10 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
CGSGetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), &m_OldHotKeyMode);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize the gamepad mask with currently attached gamepads to avoid
|
// Initialize the gamepad mask with currently attached gamepads to avoid
|
||||||
// causing gamepads to unexpectedly disappear and reappear on the host
|
// causing gamepads to unexpectedly disappear and reappear on the host
|
||||||
// during stream startup as we detect currently attached gamepads one at a time.
|
// during stream startup as we detect currently attached gamepads one at a time.
|
||||||
@ -240,6 +244,10 @@ SdlInputHandler::~SdlInputHandler()
|
|||||||
SDL_DestroyCond(m_ClipboardHasData);
|
SDL_DestroyCond(m_ClipboardHasData);
|
||||||
SDL_DestroyMutex(m_ClipboardLock);
|
SDL_DestroyMutex(m_ClipboardLock);
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), m_OldHotKeyMode);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||||
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
|
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
|
||||||
SDL_assert(!SDL_WasInit(SDL_INIT_HAPTIC));
|
SDL_assert(!SDL_WasInit(SDL_INIT_HAPTIC));
|
||||||
@ -319,11 +327,28 @@ void SdlInputHandler::notifyFocusLost()
|
|||||||
setCaptureActive(false);
|
setCaptureActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
if (m_CaptureSystemKeysEnabled) {
|
||||||
|
// Stop capturing system keys on focus loss
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), m_OldHotKeyMode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Raise all keys that are currently pressed. If we don't do this, certain keys
|
// Raise all keys that are currently pressed. If we don't do this, certain keys
|
||||||
// used in shortcuts that cause focus loss (such as Alt+Tab) may get stuck down.
|
// used in shortcuts that cause focus loss (such as Alt+Tab) may get stuck down.
|
||||||
raiseAllKeys();
|
raiseAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlInputHandler::notifyFocusGained()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
if (m_CaptureSystemKeysEnabled) {
|
||||||
|
// Start capturing system keys again on focus gain
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), CGSGlobalHotKeyDisable);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool SdlInputHandler::isCaptureActive()
|
bool SdlInputHandler::isCaptureActive()
|
||||||
{
|
{
|
||||||
if (SDL_GetRelativeMouseMode()) {
|
if (SDL_GetRelativeMouseMode()) {
|
||||||
@ -350,10 +375,6 @@ bool SdlInputHandler::isSystemKeyCaptureActive()
|
|||||||
&& (windowFlags & SDL_WINDOW_KEYBOARD_GRABBED)
|
&& (windowFlags & SDL_WINDOW_KEYBOARD_GRABBED)
|
||||||
#else
|
#else
|
||||||
&& (windowFlags & SDL_WINDOW_INPUT_GRABBED)
|
&& (windowFlags & SDL_WINDOW_INPUT_GRABBED)
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_DARWIN
|
|
||||||
// Darwin only supports full-screen system key capture
|
|
||||||
&& (windowFlags & SDL_WINDOW_FULLSCREEN)
|
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -383,6 +404,10 @@ void SdlInputHandler::setCaptureActive(bool active)
|
|||||||
if (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) {
|
if (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) {
|
||||||
SDL_SetWindowGrab(m_Window, SDL_TRUE);
|
SDL_SetWindowGrab(m_Window, SDL_TRUE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
// SDL doesn't support this private macOS API
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), CGSGlobalHotKeyDisable);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,6 +465,11 @@ void SdlInputHandler::setCaptureActive(bool active)
|
|||||||
// Allow the cursor to leave the bounds of our window again.
|
// Allow the cursor to leave the bounds of our window again.
|
||||||
SDL_SetWindowGrab(m_Window, SDL_FALSE);
|
SDL_SetWindowGrab(m_Window, SDL_FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
// SDL doesn't support this private macOS API
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), m_OldHotKeyMode);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,25 @@ struct GamepadState {
|
|||||||
unsigned char lt, rt;
|
unsigned char lt, rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
#include <CoreGraphics/CGError.h>
|
||||||
|
extern "C" {
|
||||||
|
typedef int CGSConnection;
|
||||||
|
typedef enum {
|
||||||
|
CGSGlobalHotKeyEnable = 0,
|
||||||
|
CGSGlobalHotKeyDisable = 1,
|
||||||
|
} CGSGlobalHotKeyOperatingMode;
|
||||||
|
|
||||||
|
extern CGSConnection _CGSDefaultConnection(void);
|
||||||
|
|
||||||
|
extern CGError CGSGetGlobalHotKeyOperatingMode(CGSConnection connection,
|
||||||
|
CGSGlobalHotKeyOperatingMode* mode);
|
||||||
|
|
||||||
|
extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection connection,
|
||||||
|
CGSGlobalHotKeyOperatingMode mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_GAMEPADS 4
|
#define MAX_GAMEPADS 4
|
||||||
#define MAX_FINGERS 2
|
#define MAX_FINGERS 2
|
||||||
|
|
||||||
@ -79,6 +98,8 @@ public:
|
|||||||
|
|
||||||
void notifyFocusLost();
|
void notifyFocusLost();
|
||||||
|
|
||||||
|
void notifyFocusGained();
|
||||||
|
|
||||||
bool isCaptureActive();
|
bool isCaptureActive();
|
||||||
|
|
||||||
bool isSystemKeyCaptureActive();
|
bool isSystemKeyCaptureActive();
|
||||||
@ -167,6 +188,10 @@ private:
|
|||||||
bool m_CaptureSystemKeysEnabled;
|
bool m_CaptureSystemKeysEnabled;
|
||||||
int m_MouseCursorCapturedVisibilityState;
|
int m_MouseCursorCapturedVisibilityState;
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
CGSGlobalHotKeyOperatingMode m_OldHotKeyMode;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
KeyCombo keyCombo;
|
KeyCombo keyCombo;
|
||||||
SDL_Keycode keyCode;
|
SDL_Keycode keyCode;
|
||||||
|
@ -522,15 +522,6 @@ bool Session::initialize()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
|
||||||
// macOS behaves as if we're capturing system keys when
|
|
||||||
// we enter "real" full-screen mode, so use standard
|
|
||||||
// full-screen as our full-screen flag when capturing keys.
|
|
||||||
if (m_Preferences->captureSysKeys) {
|
|
||||||
m_FullScreenFlag = SDL_WINDOW_FULLSCREEN;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 11)
|
#if !SDL_VERSION_ATLEAST(2, 0, 11)
|
||||||
// HACK: Using a full-screen window breaks mouse capture on the Pi's LXDE
|
// HACK: Using a full-screen window breaks mouse capture on the Pi's LXDE
|
||||||
// GUI environment. Force the session to use windowed mode (which won't
|
// GUI environment. Force the session to use windowed mode (which won't
|
||||||
@ -1345,6 +1336,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
if (m_Preferences->muteOnFocusLoss) {
|
if (m_Preferences->muteOnFocusLoss) {
|
||||||
m_AudioMuted = false;
|
m_AudioMuted = false;
|
||||||
}
|
}
|
||||||
|
m_InputHandler->notifyFocusGained();
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_LEAVE:
|
case SDL_WINDOWEVENT_LEAVE:
|
||||||
m_InputHandler->notifyMouseLeave();
|
m_InputHandler->notifyMouseLeave();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user