diff --git a/doc/newsfragments/mac-accessibility-permission.feature b/doc/newsfragments/mac-accessibility-permission.feature
new file mode 100644
index 00000000..e44e0c0d
--- /dev/null
+++ b/doc/newsfragments/mac-accessibility-permission.feature
@@ -0,0 +1 @@
++ Add support to detect when the accessibility permission has been removed on MacOS and terminate the application.
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 570e8424..0154be67 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -21,6 +21,7 @@ set(GUI_COMMON_HEADER_FILES
set(GUI_SOURCE_FILES
src/AboutDialog.cpp
+ src/AccessibilityPermissionObserver.cpp
src/ActionDialog.cpp
src/AddClientDialog.cpp
src/AppConfig.cpp
@@ -61,6 +62,7 @@ set(GUI_SOURCE_FILES
set(GUI_HEADER_FILES
src/AboutDialog.h
+ src/AccessibilityPermissionObserver.h
src/ActionDialog.h
src/AddClientDialog.h
src/AppConfig.h
diff --git a/src/gui/src/AccessibilityPermissionObserver.cpp b/src/gui/src/AccessibilityPermissionObserver.cpp
new file mode 100644
index 00000000..80574918
--- /dev/null
+++ b/src/gui/src/AccessibilityPermissionObserver.cpp
@@ -0,0 +1,52 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2022 Duncan Cunningham
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "AccessibilityPermissionObserver.h"
+
+#include
+#include
+
+#if defined(Q_OS_MAC)
+#include
+#endif
+
+AccessibilityPermissionObserver::AccessibilityPermissionObserver(QObject* parent)
+ : QObject(parent)
+{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 // mavericks
+ m_pTimer = new QTimer(this);
+
+ connect(m_pTimer, SIGNAL(timeout()), this, SLOT(checkAccessibilityPermissions()));
+#endif
+}
+
+void AccessibilityPermissionObserver::start()
+{
+ if (m_pTimer) {
+ m_pTimer->start(1000);
+ }
+}
+
+void AccessibilityPermissionObserver::checkAccessibilityPermissions()
+{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 // mavericks
+ // There's no API to be notified when this permission changes, so we have to poll it.
+ if (!AXIsProcessTrusted()) {
+ QApplication::quit();
+ }
+#endif
+}
\ No newline at end of file
diff --git a/src/gui/src/AccessibilityPermissionObserver.h b/src/gui/src/AccessibilityPermissionObserver.h
new file mode 100644
index 00000000..f0a54b23
--- /dev/null
+++ b/src/gui/src/AccessibilityPermissionObserver.h
@@ -0,0 +1,34 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2022 Duncan Cunningham
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+
+class QTimer;
+
+class AccessibilityPermissionObserver: public QObject
+{
+ Q_OBJECT
+public:
+ explicit AccessibilityPermissionObserver(QObject* parent = nullptr);
+ void start();
+public slots:
+ void checkAccessibilityPermissions();
+private:
+ QTimer* m_pTimer;
+};
\ No newline at end of file
diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp
index d17548a4..03d7a710 100644
--- a/src/gui/src/MainWindow.cpp
+++ b/src/gui/src/MainWindow.cpp
@@ -21,6 +21,7 @@
#include "MainWindow.h"
#include "AboutDialog.h"
+#include "AccessibilityPermissionObserver.h"
#include "ServerConfigDialog.h"
#include "SettingsDialog.h"
#include "ZeroconfService.h"
@@ -118,7 +119,8 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_SuppressEmptyServerWarning(false),
m_ExpectedRunningState(kStopped),
m_pSslCertificate(NULL),
- m_pLogWindow(new LogWindow(nullptr))
+ m_pLogWindow(new LogWindow(nullptr)),
+ m_pAccessibilityPermissionObserver(nullptr)
{
// explicitly unset DeleteOnClose so the window can be show and hidden
// repeatedly until Barrier is finished
@@ -503,6 +505,11 @@ void MainWindow::startBarrier()
bool desktopMode = appConfig().processMode() == Desktop;
bool serviceMode = appConfig().processMode() == Service;
+#if defined(Q_OS_MAC)
+ m_pAccessibilityPermissionObserver = new AccessibilityPermissionObserver(this);
+ m_pAccessibilityPermissionObserver->start();
+#endif
+
appendLogDebug("starting process");
m_ExpectedRunningState = kStarted;
setBarrierState(barrierConnecting);
@@ -767,6 +774,11 @@ void MainWindow::stopBarrier()
// reset so that new connects cause auto-hide.
m_AlreadyHidden = false;
+
+#if defined(Q_OS_MAC)
+ delete m_pAccessibilityPermissionObserver;
+ m_pAccessibilityPermissionObserver = nullptr;
+#endif
}
void MainWindow::stopService()
diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h
index 0c582c9f..b46b4bd4 100644
--- a/src/gui/src/MainWindow.h
+++ b/src/gui/src/MainWindow.h
@@ -53,6 +53,7 @@ class QTemporaryFile;
class QMessageBox;
class QAbstractButton;
+class AccessibilityPermissionObserver;
class LogDialog;
class QBarrierApplication;
class SetupWizard;
@@ -198,6 +199,7 @@ public slots:
SslCertificate* m_pSslCertificate;
QStringList m_PendingClientNames;
LogWindow *m_pLogWindow;
+ AccessibilityPermissionObserver* m_pAccessibilityPermissionObserver;
bool m_fingerprint_expanded = false;