diff --git a/frontend/data/locale/en-US.ini b/frontend/data/locale/en-US.ini
index 572b15f15..d7e72b698 100644
--- a/frontend/data/locale/en-US.ini
+++ b/frontend/data/locale/en-US.ini
@@ -510,8 +510,10 @@ MacPermissions.Item.Camera="Camera"
MacPermissions.Item.Camera.Details="This permission is needed in order to capture content from a webcam or capture card."
MacPermissions.Item.Microphone="Microphone"
MacPermissions.Item.Microphone.Details="OBS requires this permission if you want to capture your microphone or an external audio device."
+MacPermissions.Item.InputMonitoring="Input Monitoring"
+MacPermissions.Item.InputMonitoring.Details="This permission is required for hotkeys to work while OBS is in the background."
MacPermissions.Item.Accessibility="Accessibility"
-MacPermissions.Item.Accessibility.Details="For keyboard shortcuts (hotkeys) to work while other apps are focused, please enable this permission."
+MacPermissions.Item.Accessibility.Details="On older installations, OBS may be listed in \"Accessibility\" instead of \"Input Monitoring\"."
MacPermissions.Continue="Continue"
# Source leak error message
diff --git a/frontend/dialogs/OBSPermissions.cpp b/frontend/dialogs/OBSPermissions.cpp
index 9c62970d7..9381b8549 100644
--- a/frontend/dialogs/OBSPermissions.cpp
+++ b/frontend/dialogs/OBSPermissions.cpp
@@ -22,7 +22,7 @@
#include "moc_OBSPermissions.cpp"
OBSPermissions::OBSPermissions(QWidget *parent, MacPermissionStatus capture, MacPermissionStatus video,
- MacPermissionStatus audio, MacPermissionStatus accessibility)
+ MacPermissionStatus audio, MacPermissionStatus inputMonitoring)
: QDialog(parent),
ui(new Ui::OBSPermissions)
{
@@ -30,7 +30,12 @@ OBSPermissions::OBSPermissions(QWidget *parent, MacPermissionStatus capture, Mac
SetStatus(ui->capturePermissionButton, capture, QTStr("MacPermissions.Item.ScreenRecording"));
SetStatus(ui->videoPermissionButton, video, QTStr("MacPermissions.Item.Camera"));
SetStatus(ui->audioPermissionButton, audio, QTStr("MacPermissions.Item.Microphone"));
- SetStatus(ui->accessibilityPermissionButton, accessibility, QTStr("MacPermissions.Item.Accessibility"));
+ SetStatus(ui->inputMonitoringPermissionButton, inputMonitoring, QTStr("MacPermissions.Item.InputMonitoring"));
+
+ ui->accessibilityPermissionButton->setText(
+ QTStr("MacPermissions.OpenPreferences").arg(QTStr("MacPermissions.Item.Accessibility")));
+ ui->accessibilityPermissionButton->setVisible(inputMonitoring != kPermissionAuthorized);
+ ui->accessibilityPermissionLabel->setVisible(inputMonitoring != kPermissionAuthorized);
}
void OBSPermissions::SetStatus(QPushButton *btn, MacPermissionStatus status, const QString &preference)
@@ -74,10 +79,15 @@ void OBSPermissions::on_audioPermissionButton_clicked()
}
}
+void OBSPermissions::on_inputMonitoringPermissionButton_clicked()
+{
+ OpenMacOSPrivacyPreferences("ListenEvent");
+ RequestPermission(kInputMonitoring);
+}
+
void OBSPermissions::on_accessibilityPermissionButton_clicked()
{
OpenMacOSPrivacyPreferences("Accessibility");
- RequestPermission(kAccessibility);
}
void OBSPermissions::on_continueButton_clicked()
diff --git a/frontend/dialogs/OBSPermissions.hpp b/frontend/dialogs/OBSPermissions.hpp
index 5fab46b55..b6e7c2b08 100644
--- a/frontend/dialogs/OBSPermissions.hpp
+++ b/frontend/dialogs/OBSPermissions.hpp
@@ -40,6 +40,7 @@ private slots:
void on_capturePermissionButton_clicked();
void on_videoPermissionButton_clicked();
void on_audioPermissionButton_clicked();
+ void on_inputMonitoringPermissionButton_clicked();
void on_accessibilityPermissionButton_clicked();
void on_continueButton_clicked();
};
diff --git a/frontend/forms/OBSPermissions.ui b/frontend/forms/OBSPermissions.ui
index 8d65da91d..9b0182ce8 100644
--- a/frontend/forms/OBSPermissions.ui
+++ b/frontend/forms/OBSPermissions.ui
@@ -344,7 +344,7 @@
- MacPermissions.Item.Accessibility
+ MacPermissions.Item.InputMonitoring
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -354,11 +354,62 @@
-
- MacPermissions.Item.Accessibility.Details
+ MacPermissions.Item.InputMonitoring.Details
+
+
+ true
-
+
+
+ QLayout::SetDefaultConstraint
+
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 300
+ 0
+
+
+
+
+ 300
+ 16777215
+
+
+
+
+ 300
+ 0
+
+
+
+
+
+
+ -
+
+
+ MacPermissions.Item.Accessibility.Details
+
+
+ true
+
+
+
+ -
QLayout::SetDefaultConstraint
diff --git a/frontend/obs-main.cpp b/frontend/obs-main.cpp
index 987dca5bc..7f41f8741 100644
--- a/frontend/obs-main.cpp
+++ b/frontend/obs-main.cpp
@@ -673,14 +673,14 @@ static int run_program(fstream &logFile, int argc, char *argv[])
#ifdef __APPLE__
MacPermissionStatus audio_permission = CheckPermission(kAudioDeviceAccess);
MacPermissionStatus video_permission = CheckPermission(kVideoDeviceAccess);
- MacPermissionStatus accessibility_permission = CheckPermission(kAccessibility);
+ MacPermissionStatus input_monitoring_permission = CheckPermission(kInputMonitoring);
MacPermissionStatus screen_permission = CheckPermission(kScreenCapture);
int permissionsDialogLastShown =
config_get_int(App()->GetAppConfig(), "General", "MacOSPermissionsDialogLastShown");
if (permissionsDialogLastShown < MACOS_PERMISSIONS_DIALOG_VERSION) {
OBSPermissions check(nullptr, screen_permission, video_permission, audio_permission,
- accessibility_permission);
+ input_monitoring_permission);
check.exec();
}
#endif
diff --git a/frontend/utility/platform-osx.mm b/frontend/utility/platform-osx.mm
index c9648b00f..5421a23e7 100644
--- a/frontend/utility/platform-osx.mm
+++ b/frontend/utility/platform-osx.mm
@@ -267,16 +267,14 @@ MacPermissionStatus CheckPermissionWithPrompt(MacPermissionType type, bool promp
break;
}
- case kAccessibility: {
- permissionResponse = (AXIsProcessTrusted() ? kPermissionAuthorized : kPermissionDenied);
+ case kInputMonitoring: {
+ permissionResponse = (CGPreflightListenEventAccess() ? kPermissionAuthorized : kPermissionDenied);
if (permissionResponse != kPermissionAuthorized && prompt_for_permission) {
- NSDictionary *options = @{(__bridge id) kAXTrustedCheckOptionPrompt: @YES};
- permissionResponse = (AXIsProcessTrustedWithOptions((CFDictionaryRef) options) ? kPermissionAuthorized
- : kPermissionDenied);
+ permissionResponse = (CGRequestListenEventAccess() ? kPermissionAuthorized : kPermissionDenied);
}
- blog(LOG_INFO, "[macOS] Permission for accessibility %s.",
+ blog(LOG_INFO, "[macOS] Permission for input monitoring %s.",
permissionResponse == kPermissionAuthorized ? "granted" : "denied");
break;
}
diff --git a/frontend/utility/platform.hpp b/frontend/utility/platform.hpp
index e05bc66eb..24f397bdd 100644
--- a/frontend/utility/platform.hpp
+++ b/frontend/utility/platform.hpp
@@ -84,7 +84,7 @@ typedef enum {
kAudioDeviceAccess = 0,
kVideoDeviceAccess = 1,
kScreenCapture = 2,
- kAccessibility = 3
+ kInputMonitoring = 3
} MacPermissionType;
typedef enum {
diff --git a/frontend/widgets/OBSBasic_MainControls.cpp b/frontend/widgets/OBSBasic_MainControls.cpp
index 6b3c7958c..bbebcbf97 100644
--- a/frontend/widgets/OBSBasic_MainControls.cpp
+++ b/frontend/widgets/OBSBasic_MainControls.cpp
@@ -219,7 +219,7 @@ void OBSBasic::on_actionShowMacPermissions_triggered()
{
#ifdef __APPLE__
OBSPermissions check(this, CheckPermission(kScreenCapture), CheckPermission(kVideoDeviceAccess),
- CheckPermission(kAudioDeviceAccess), CheckPermission(kAccessibility));
+ CheckPermission(kAudioDeviceAccess), CheckPermission(kInputMonitoring));
check.exec();
#endif
}