mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-01 23:35:55 +00:00
Add setting to only capture system keys in full-screen
This commit is contained in:
parent
58803ef40d
commit
87a7d2e45c
@ -264,6 +264,11 @@ StreamCommandLineParser::StreamCommandLineParser()
|
|||||||
{"software", StreamingPreferences::VDS_FORCE_SOFTWARE},
|
{"software", StreamingPreferences::VDS_FORCE_SOFTWARE},
|
||||||
{"hardware", StreamingPreferences::VDS_FORCE_HARDWARE},
|
{"hardware", StreamingPreferences::VDS_FORCE_HARDWARE},
|
||||||
};
|
};
|
||||||
|
m_CaptureSysKeysModeMap = {
|
||||||
|
{"never", StreamingPreferences::CSK_OFF},
|
||||||
|
{"fullscreen", StreamingPreferences::CSK_FULLSCREEN},
|
||||||
|
{"always", StreamingPreferences::CSK_ALWAYS},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamCommandLineParser::~StreamCommandLineParser()
|
StreamCommandLineParser::~StreamCommandLineParser()
|
||||||
@ -307,7 +312,7 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
|
|||||||
parser.addToggleOption("background-gamepad", "background gamepad input");
|
parser.addToggleOption("background-gamepad", "background gamepad input");
|
||||||
parser.addToggleOption("reverse-scroll-direction", "inverted scroll direction");
|
parser.addToggleOption("reverse-scroll-direction", "inverted scroll direction");
|
||||||
parser.addToggleOption("swap-gamepad-buttons", "swap A/B and X/Y gamepad buttons (Nintendo-style)");
|
parser.addToggleOption("swap-gamepad-buttons", "swap A/B and X/Y gamepad buttons (Nintendo-style)");
|
||||||
parser.addToggleOption("capture-system-keys", "capture system key combos in fullscreen mode");
|
parser.addChoiceOption("capture-system-keys", "capture system key combos", m_CaptureSysKeysModeMap.keys());
|
||||||
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
|
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
|
||||||
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
|
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
|
||||||
|
|
||||||
@ -422,8 +427,10 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
|
|||||||
// Resolve --swap-gamepad-buttons and --no-swap-gamepad-buttons options
|
// Resolve --swap-gamepad-buttons and --no-swap-gamepad-buttons options
|
||||||
preferences->swapFaceButtons = parser.getToggleOptionValue("swap-gamepad-buttons", preferences->swapFaceButtons);
|
preferences->swapFaceButtons = parser.getToggleOptionValue("swap-gamepad-buttons", preferences->swapFaceButtons);
|
||||||
|
|
||||||
// Resolve --capture-system-keys and --no-capture-system-keys options
|
// Resolve --capture-system-keys option
|
||||||
preferences->captureSysKeys = parser.getToggleOptionValue("capture-system-keys", preferences->captureSysKeys);
|
if (parser.isSet("capture-system-keys")) {
|
||||||
|
preferences->captureSysKeysMode = mapValue(m_CaptureSysKeysModeMap, parser.getChoiceOptionValue("capture-system-keys"));
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve --video-codec option
|
// Resolve --video-codec option
|
||||||
if (parser.isSet("video-codec")) {
|
if (parser.isSet("video-codec")) {
|
||||||
|
@ -53,4 +53,5 @@ private:
|
|||||||
QMap<QString, StreamingPreferences::AudioConfig> m_AudioConfigMap;
|
QMap<QString, StreamingPreferences::AudioConfig> m_AudioConfigMap;
|
||||||
QMap<QString, StreamingPreferences::VideoCodecConfig> m_VideoCodecMap;
|
QMap<QString, StreamingPreferences::VideoCodecConfig> m_VideoCodecMap;
|
||||||
QMap<QString, StreamingPreferences::VideoDecoderSelection> m_VideoDecoderMap;
|
QMap<QString, StreamingPreferences::VideoDecoderSelection> m_VideoDecoderMap;
|
||||||
|
QMap<QString, StreamingPreferences::CaptureSysKeysMode> m_CaptureSysKeysModeMap;
|
||||||
};
|
};
|
||||||
|
@ -907,23 +907,79 @@ Flickable {
|
|||||||
qsTr("NOTE: Due to a bug in GeForce Experience, this option may not work properly if your host PC has multiple monitors.")
|
qsTr("NOTE: Due to a bug in GeForce Experience, this option may not work properly if your host PC has multiple monitors.")
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
Row {
|
||||||
id: captureSysKeysCheck
|
spacing: 5
|
||||||
hoverEnabled: true
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: qsTr("Capture system keyboard shortcuts")
|
|
||||||
font.pointSize: 12
|
CheckBox {
|
||||||
enabled: SystemProperties.hasWindowManager
|
id: captureSysKeysCheck
|
||||||
checked: StreamingPreferences.captureSysKeys && SystemProperties.hasWindowManager
|
hoverEnabled: true
|
||||||
onCheckedChanged: {
|
text: qsTr("Capture system keyboard shortcuts")
|
||||||
StreamingPreferences.captureSysKeys = checked
|
font.pointSize: 12
|
||||||
|
enabled: SystemProperties.hasWindowManager
|
||||||
|
checked: StreamingPreferences.captureSysKeysMode !== StreamingPreferences.CSK_OFF || !SystemProperties.hasWindowManager
|
||||||
|
|
||||||
|
ToolTip.delay: 1000
|
||||||
|
ToolTip.timeout: 10000
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("This enables the capture of system-wide keyboard shortcuts like Alt+Tab that would normally be handled by the client OS while streaming.") + "\n\n" +
|
||||||
|
qsTr("NOTE: Certain keyboard shortcuts like Ctrl+Alt+Del on Windows cannot be intercepted by any application, including Moonlight.")
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip.delay: 1000
|
AutoResizingComboBox {
|
||||||
ToolTip.timeout: 10000
|
// ignore setting the index at first, and actually set it when the component is loaded
|
||||||
ToolTip.visible: hovered
|
Component.onCompleted: {
|
||||||
ToolTip.text: qsTr("This enables the capture of system-wide keyboard shortcuts like Alt+Tab that would normally be handled by the client OS while streaming.") + "\n\n" +
|
if (!visible) {
|
||||||
qsTr("NOTE: Certain keyboard shortcuts like Ctrl+Alt+Del on Windows cannot be intercepted by any application, including Moonlight.")
|
// Do nothing if the control won't even be visible
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var saved_syskeysmode = StreamingPreferences.captureSysKeysMode
|
||||||
|
currentIndex = 0
|
||||||
|
for (var i = 0; i < captureSysKeysModeListModel.count; i++) {
|
||||||
|
var el_syskeysmode = captureSysKeysModeListModel.get(i).val;
|
||||||
|
if (saved_syskeysmode === el_syskeysmode) {
|
||||||
|
currentIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
activated(currentIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled: captureSysKeysCheck.checked
|
||||||
|
textRole: "text"
|
||||||
|
model: ListModel {
|
||||||
|
id: captureSysKeysModeListModel
|
||||||
|
ListElement {
|
||||||
|
text: qsTr("in fullscreen")
|
||||||
|
val: StreamingPreferences.CSK_FULLSCREEN
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
text: qsTr("always")
|
||||||
|
val: StreamingPreferences.CSK_ALWAYS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePref() {
|
||||||
|
if (!enabled) {
|
||||||
|
StreamingPreferences.captureSysKeysMode = StreamingPreferences.CSK_OFF
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StreamingPreferences.captureSysKeysMode = captureSysKeysModeListModel.get(currentIndex).val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ::onActivated must be used, as it only listens for when the index is changed by a human
|
||||||
|
onActivated: {
|
||||||
|
updatePref()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This handles transition of the checkbox state
|
||||||
|
onEnabledChanged: {
|
||||||
|
updatePref()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
@ -95,7 +95,8 @@ void StreamingPreferences::reload()
|
|||||||
backgroundGamepad = settings.value(SER_BACKGROUNDGAMEPAD, false).toBool();
|
backgroundGamepad = settings.value(SER_BACKGROUNDGAMEPAD, false).toBool();
|
||||||
reverseScrollDirection = settings.value(SER_REVERSESCROLL, false).toBool();
|
reverseScrollDirection = settings.value(SER_REVERSESCROLL, false).toBool();
|
||||||
swapFaceButtons = settings.value(SER_SWAPFACEBUTTONS, false).toBool();
|
swapFaceButtons = settings.value(SER_SWAPFACEBUTTONS, false).toBool();
|
||||||
captureSysKeys = settings.value(SER_CAPTURESYSKEYS, false).toBool();
|
captureSysKeysMode = static_cast<CaptureSysKeysMode>(settings.value(SER_CAPTURESYSKEYS,
|
||||||
|
static_cast<int>(CaptureSysKeysMode::CSK_OFF)).toInt());
|
||||||
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
||||||
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
|
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
|
||||||
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
|
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
|
||||||
@ -227,7 +228,7 @@ void StreamingPreferences::save()
|
|||||||
settings.setValue(SER_BACKGROUNDGAMEPAD, backgroundGamepad);
|
settings.setValue(SER_BACKGROUNDGAMEPAD, backgroundGamepad);
|
||||||
settings.setValue(SER_REVERSESCROLL, reverseScrollDirection);
|
settings.setValue(SER_REVERSESCROLL, reverseScrollDirection);
|
||||||
settings.setValue(SER_SWAPFACEBUTTONS, swapFaceButtons);
|
settings.setValue(SER_SWAPFACEBUTTONS, swapFaceButtons);
|
||||||
settings.setValue(SER_CAPTURESYSKEYS, captureSysKeys);
|
settings.setValue(SER_CAPTURESYSKEYS, captureSysKeysMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int StreamingPreferences::getDefaultBitrate(int width, int height, int fps)
|
int StreamingPreferences::getDefaultBitrate(int width, int height, int fps)
|
||||||
|
@ -69,6 +69,14 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(Language);
|
Q_ENUM(Language);
|
||||||
|
|
||||||
|
enum CaptureSysKeysMode
|
||||||
|
{
|
||||||
|
CSK_OFF,
|
||||||
|
CSK_FULLSCREEN,
|
||||||
|
CSK_ALWAYS,
|
||||||
|
};
|
||||||
|
Q_ENUM(CaptureSysKeysMode);
|
||||||
|
|
||||||
Q_PROPERTY(int width MEMBER width NOTIFY displayModeChanged)
|
Q_PROPERTY(int width MEMBER width NOTIFY displayModeChanged)
|
||||||
Q_PROPERTY(int height MEMBER height NOTIFY displayModeChanged)
|
Q_PROPERTY(int height MEMBER height NOTIFY displayModeChanged)
|
||||||
Q_PROPERTY(int fps MEMBER fps NOTIFY displayModeChanged)
|
Q_PROPERTY(int fps MEMBER fps NOTIFY displayModeChanged)
|
||||||
@ -98,7 +106,7 @@ public:
|
|||||||
Q_PROPERTY(bool backgroundGamepad MEMBER backgroundGamepad NOTIFY backgroundGamepadChanged)
|
Q_PROPERTY(bool backgroundGamepad MEMBER backgroundGamepad NOTIFY backgroundGamepadChanged)
|
||||||
Q_PROPERTY(bool reverseScrollDirection MEMBER reverseScrollDirection NOTIFY reverseScrollDirectionChanged)
|
Q_PROPERTY(bool reverseScrollDirection MEMBER reverseScrollDirection NOTIFY reverseScrollDirectionChanged)
|
||||||
Q_PROPERTY(bool swapFaceButtons MEMBER swapFaceButtons NOTIFY swapFaceButtonsChanged)
|
Q_PROPERTY(bool swapFaceButtons MEMBER swapFaceButtons NOTIFY swapFaceButtonsChanged)
|
||||||
Q_PROPERTY(bool captureSysKeys MEMBER captureSysKeys NOTIFY captureSysKeysChanged)
|
Q_PROPERTY(CaptureSysKeysMode captureSysKeysMode MEMBER captureSysKeysMode NOTIFY captureSysKeysModeChanged)
|
||||||
Q_PROPERTY(Language language MEMBER language NOTIFY languageChanged);
|
Q_PROPERTY(Language language MEMBER language NOTIFY languageChanged);
|
||||||
|
|
||||||
Q_INVOKABLE bool retranslate();
|
Q_INVOKABLE bool retranslate();
|
||||||
@ -127,7 +135,6 @@ public:
|
|||||||
bool backgroundGamepad;
|
bool backgroundGamepad;
|
||||||
bool reverseScrollDirection;
|
bool reverseScrollDirection;
|
||||||
bool swapFaceButtons;
|
bool swapFaceButtons;
|
||||||
bool captureSysKeys;
|
|
||||||
int packetSize;
|
int packetSize;
|
||||||
AudioConfig audioConfig;
|
AudioConfig audioConfig;
|
||||||
VideoCodecConfig videoCodecConfig;
|
VideoCodecConfig videoCodecConfig;
|
||||||
@ -136,6 +143,7 @@ public:
|
|||||||
WindowMode recommendedFullScreenMode;
|
WindowMode recommendedFullScreenMode;
|
||||||
UIDisplayMode uiDisplayMode;
|
UIDisplayMode uiDisplayMode;
|
||||||
Language language;
|
Language language;
|
||||||
|
CaptureSysKeysMode captureSysKeysMode;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void displayModeChanged();
|
void displayModeChanged();
|
||||||
@ -164,7 +172,7 @@ signals:
|
|||||||
void backgroundGamepadChanged();
|
void backgroundGamepadChanged();
|
||||||
void reverseScrollDirectionChanged();
|
void reverseScrollDirectionChanged();
|
||||||
void swapFaceButtonsChanged();
|
void swapFaceButtonsChanged();
|
||||||
void captureSysKeysChanged();
|
void captureSysKeysModeChanged();
|
||||||
void languageChanged();
|
void languageChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -22,7 +22,7 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
|
|||||||
m_MouseWasInVideoRegion(false),
|
m_MouseWasInVideoRegion(false),
|
||||||
m_PendingMouseButtonsAllUpOnVideoRegionLeave(false),
|
m_PendingMouseButtonsAllUpOnVideoRegionLeave(false),
|
||||||
m_FakeCaptureActive(false),
|
m_FakeCaptureActive(false),
|
||||||
m_CaptureSystemKeysEnabled(prefs.captureSysKeys || !WMUtils::isRunningWindowManager()),
|
m_CaptureSystemKeysMode(prefs.captureSysKeysMode),
|
||||||
m_MouseCursorCapturedVisibilityState(SDL_DISABLE),
|
m_MouseCursorCapturedVisibilityState(SDL_DISABLE),
|
||||||
m_PendingKeyCombo(KeyComboMax),
|
m_PendingKeyCombo(KeyComboMax),
|
||||||
m_LongPressTimer(0),
|
m_LongPressTimer(0),
|
||||||
@ -37,6 +37,11 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
|
|||||||
m_NumFingersDown(0),
|
m_NumFingersDown(0),
|
||||||
m_ClipboardData()
|
m_ClipboardData()
|
||||||
{
|
{
|
||||||
|
// System keys are always captured when running without a WM
|
||||||
|
if (!WMUtils::isRunningWindowManager()) {
|
||||||
|
m_CaptureSystemKeysMode = StreamingPreferences::CSK_ALWAYS;
|
||||||
|
}
|
||||||
|
|
||||||
// Allow gamepad input when the app doesn't have focus if requested
|
// Allow gamepad input when the app doesn't have focus if requested
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, prefs.backgroundGamepad ? "1" : "0");
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, prefs.backgroundGamepad ? "1" : "0");
|
||||||
|
|
||||||
@ -51,16 +56,13 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s
|
|||||||
#if !SDL_VERSION_ATLEAST(2, 0, 15)
|
#if !SDL_VERSION_ATLEAST(2, 0, 15)
|
||||||
// For older versions of SDL (2.0.14 and earlier), use SDL_HINT_GRAB_KEYBOARD
|
// For older versions of SDL (2.0.14 and earlier), use SDL_HINT_GRAB_KEYBOARD
|
||||||
SDL_SetHintWithPriority(SDL_HINT_GRAB_KEYBOARD,
|
SDL_SetHintWithPriority(SDL_HINT_GRAB_KEYBOARD,
|
||||||
m_CaptureSystemKeysEnabled ? "1" : "0",
|
m_CaptureSystemKeysMode != StreamingPreferences::CSK_OFF ? "1" : "0",
|
||||||
SDL_HINT_OVERRIDE);
|
SDL_HINT_OVERRIDE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Opt-out of SDL's built-in Alt+Tab handling while keyboard grab is enabled
|
// Opt-out of SDL's built-in Alt+Tab handling while keyboard grab is enabled
|
||||||
SDL_SetHint("SDL_ALLOW_ALT_TAB_WHILE_GRABBED", "0");
|
SDL_SetHint("SDL_ALLOW_ALT_TAB_WHILE_GRABBED", "0");
|
||||||
|
|
||||||
// Don't close the window on Alt+F4 when keyboard grab is enabled
|
|
||||||
SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, m_CaptureSystemKeysEnabled ? "1" : "0");
|
|
||||||
|
|
||||||
// Allow clicks to pass through to us when focusing the window. If we're in
|
// Allow clicks to pass through to us when focusing the window. If we're in
|
||||||
// absolute mouse mode, this will avoid the user having to click twice to
|
// absolute mouse mode, this will avoid the user having to click twice to
|
||||||
// trigger a click on the host if the Moonlight window is not focused. In
|
// trigger a click on the host if the Moonlight window is not focused. In
|
||||||
@ -328,10 +330,8 @@ void SdlInputHandler::notifyFocusLost()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
if (m_CaptureSystemKeysEnabled) {
|
// Ungrab the keyboard
|
||||||
// Stop capturing system keys on focus loss
|
updateKeyboardGrabState();
|
||||||
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), m_OldHotKeyMode);
|
|
||||||
}
|
|
||||||
#endif
|
#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
|
||||||
@ -342,10 +342,11 @@ void SdlInputHandler::notifyFocusLost()
|
|||||||
void SdlInputHandler::notifyFocusGained()
|
void SdlInputHandler::notifyFocusGained()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
if (m_CaptureSystemKeysEnabled) {
|
// Re-grab the keyboard if it was grabbed before focus loss
|
||||||
// Start capturing system keys again on focus gain
|
// FIXME: We only do this on macOS because we get a spurious
|
||||||
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), CGSGlobalHotKeyDisable);
|
// focus gain when in SDL_WINDOW_FULLSCREEN_DESKTOP on Windows
|
||||||
}
|
// immediately after losing focus by clicking on another window.
|
||||||
|
updateKeyboardGrabState();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,9 +360,62 @@ bool SdlInputHandler::isCaptureActive()
|
|||||||
return m_FakeCaptureActive;
|
return m_FakeCaptureActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlInputHandler::updateKeyboardGrabState()
|
||||||
|
{
|
||||||
|
if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_OFF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldGrab = isCaptureActive();
|
||||||
|
Uint32 windowFlags = SDL_GetWindowFlags(m_Window);
|
||||||
|
if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN &&
|
||||||
|
!(windowFlags & SDL_WINDOW_FULLSCREEN)) {
|
||||||
|
// Ungrab if it's fullscreen only and we left fullscreen
|
||||||
|
shouldGrab = false;
|
||||||
|
}
|
||||||
|
else if (!(windowFlags & SDL_WINDOW_INPUT_FOCUS)) {
|
||||||
|
// Ungrab if we lose input focus (SDL will do this internally, but
|
||||||
|
// not for macOS where SDL is not handling the grab logic).
|
||||||
|
shouldGrab = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't close the window on Alt+F4 when keyboard grab is enabled
|
||||||
|
SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, shouldGrab ? "1" : "0");
|
||||||
|
|
||||||
|
if (shouldGrab) {
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
||||||
|
// On SDL 2.0.15, we can get keyboard-only grab on Win32, X11, and Wayland.
|
||||||
|
// This does nothing on macOS but it sets the SDL_WINDOW_KEYBOARD_GRABBED flag
|
||||||
|
// that we look for to see if keyboard capture is enabled. We'll handle macOS
|
||||||
|
// ourselves below using the private CGSSetGlobalHotKeyOperatingMode() API.
|
||||||
|
SDL_SetWindowKeyboardGrab(m_Window, SDL_TRUE);
|
||||||
|
#else
|
||||||
|
// If we're in full-screen desktop mode and SDL doesn't have keyboard grab yet,
|
||||||
|
// grab the cursor (will grab the keyboard too on X11).
|
||||||
|
if (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) {
|
||||||
|
SDL_SetWindowGrab(m_Window, SDL_TRUE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
// SDL doesn't support this private macOS API
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), CGSGlobalHotKeyDisable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
||||||
|
// Allow the keyboard to leave the window
|
||||||
|
SDL_SetWindowKeyboardGrab(m_Window, SDL_FALSE);
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
// SDL doesn't support this private macOS API
|
||||||
|
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), m_OldHotKeyMode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SdlInputHandler::isSystemKeyCaptureActive()
|
bool SdlInputHandler::isSystemKeyCaptureActive()
|
||||||
{
|
{
|
||||||
if (!m_CaptureSystemKeysEnabled) {
|
if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_OFF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,13 +424,23 @@ bool SdlInputHandler::isSystemKeyCaptureActive()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Uint32 windowFlags = SDL_GetWindowFlags(m_Window);
|
Uint32 windowFlags = SDL_GetWindowFlags(m_Window);
|
||||||
return (windowFlags & SDL_WINDOW_INPUT_FOCUS)
|
if (!(windowFlags & SDL_WINDOW_INPUT_FOCUS)
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
||||||
&& (windowFlags & SDL_WINDOW_KEYBOARD_GRABBED)
|
|| !(windowFlags & SDL_WINDOW_KEYBOARD_GRABBED)
|
||||||
#else
|
#else
|
||||||
&& (windowFlags & SDL_WINDOW_INPUT_GRABBED)
|
|| !(windowFlags & SDL_WINDOW_INPUT_GRABBED)
|
||||||
#endif
|
#endif
|
||||||
;
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN &&
|
||||||
|
!(windowFlags & SDL_WINDOW_FULLSCREEN)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlInputHandler::setCaptureActive(bool active)
|
void SdlInputHandler::setCaptureActive(bool active)
|
||||||
@ -391,26 +455,6 @@ void SdlInputHandler::setCaptureActive(bool active)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the keyboard too if system key capture is enabled
|
|
||||||
if (m_CaptureSystemKeysEnabled) {
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
|
||||||
// On SDL 2.0.15, we can get keyboard-only grab on Win32, X11, and Wayland.
|
|
||||||
// This does nothing on macOS but it sets the SDL_WINDOW_KEYBOARD_GRABBED flag
|
|
||||||
// that we look for to see if keyboard capture is enabled.
|
|
||||||
SDL_SetWindowKeyboardGrab(m_Window, SDL_TRUE);
|
|
||||||
#else
|
|
||||||
// If we're in full-screen desktop mode and SDL doesn't have keyboard grab yet,
|
|
||||||
// grab the cursor (will grab the keyboard too on X11).
|
|
||||||
if (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) {
|
|
||||||
SDL_SetWindowGrab(m_Window, SDL_TRUE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_DARWIN
|
|
||||||
// SDL doesn't support this private macOS API
|
|
||||||
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), CGSGlobalHotKeyDisable);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_AbsoluteMouseMode) {
|
if (!m_AbsoluteMouseMode) {
|
||||||
// If our window is occluded when mouse is captured, the mouse may
|
// If our window is occluded when mouse is captured, the mouse may
|
||||||
// get stuck on top of the occluding window and not be properly
|
// get stuck on top of the occluding window and not be properly
|
||||||
@ -458,19 +502,14 @@ void SdlInputHandler::setCaptureActive(bool active)
|
|||||||
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
||||||
// Allow the cursor to leave the bounds of our window again.
|
// Allow the cursor to leave the bounds of our window again.
|
||||||
SDL_SetWindowMouseGrab(m_Window, SDL_FALSE);
|
SDL_SetWindowMouseGrab(m_Window, SDL_FALSE);
|
||||||
|
|
||||||
// Allow the keyboard to leave the window
|
|
||||||
SDL_SetWindowKeyboardGrab(m_Window, SDL_FALSE);
|
|
||||||
#else
|
#else
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now update the keyboard grab
|
||||||
|
updateKeyboardGrabState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event)
|
void SdlInputHandler::handleTouchFingerEvent(SDL_TouchFingerEvent* event)
|
||||||
|
@ -112,6 +112,8 @@ public:
|
|||||||
|
|
||||||
void flushMousePositionUpdate();
|
void flushMousePositionUpdate();
|
||||||
|
|
||||||
|
void updateKeyboardGrabState();
|
||||||
|
|
||||||
static
|
static
|
||||||
QString getUnmappedGamepads();
|
QString getUnmappedGamepads();
|
||||||
|
|
||||||
@ -185,7 +187,7 @@ private:
|
|||||||
bool m_FakeCaptureActive;
|
bool m_FakeCaptureActive;
|
||||||
QString m_OldIgnoreDevices;
|
QString m_OldIgnoreDevices;
|
||||||
QString m_OldIgnoreDevicesExcept;
|
QString m_OldIgnoreDevicesExcept;
|
||||||
bool m_CaptureSystemKeysEnabled;
|
StreamingPreferences::CaptureSysKeysMode m_CaptureSystemKeysMode;
|
||||||
int m_MouseCursorCapturedVisibilityState;
|
int m_MouseCursorCapturedVisibilityState;
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
|
@ -926,10 +926,8 @@ void Session::toggleFullscreen()
|
|||||||
bool fullScreen = !(SDL_GetWindowFlags(m_Window) & m_FullScreenFlag);
|
bool fullScreen = !(SDL_GetWindowFlags(m_Window) & m_FullScreenFlag);
|
||||||
|
|
||||||
if (fullScreen) {
|
if (fullScreen) {
|
||||||
if ((m_FullScreenFlag == SDL_WINDOW_FULLSCREEN || m_Preferences->captureSysKeys) && m_InputHandler->isCaptureActive()) {
|
if (m_FullScreenFlag == SDL_WINDOW_FULLSCREEN && m_InputHandler->isCaptureActive()) {
|
||||||
// Confine the cursor to the window if we're capturing input while transitioning to full screen.
|
// Confine the cursor to the window if we're capturing input while transitioning to full screen.
|
||||||
// We also need to grab if we're capturing system keys, because SDL requires window grab to
|
|
||||||
// capture the keyboard on X11.
|
|
||||||
SDL_SetWindowGrab(m_Window, SDL_TRUE);
|
SDL_SetWindowGrab(m_Window, SDL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,6 +944,9 @@ void Session::toggleFullscreen()
|
|||||||
// Reposition the window when the resize is complete
|
// Reposition the window when the resize is complete
|
||||||
m_PendingWindowedTransition = true;
|
m_PendingWindowedTransition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Input handler might need to start/stop keyboard grab after changing modes
|
||||||
|
m_InputHandler->updateKeyboardGrabState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::notifyMouseEmulationMode(bool enabled)
|
void Session::notifyMouseEmulationMode(bool enabled)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user