diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 05715749aaf..69dc6d698b5 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -294,7 +294,7 @@
On Android devices: Returns the list of dangerous permissions that have been granted.
- On macOS: Returns the list of user selected folders accessible to the application (sandboxed applications only). Use the native file dialog to request folder access permission.
+ On macOS: Returns the list of granted permissions and user selected folders accessible to the application (sandboxed applications only). Use the native file dialog to request folder access permission.
@@ -755,8 +755,9 @@
The [param name] must be the full permission name. For example:
- [code]OS.request_permission("android.permission.READ_EXTERNAL_STORAGE")[/code]
- [code]OS.request_permission("android.permission.POST_NOTIFICATIONS")[/code]
- [b]Note:[/b] Permission must be checked during export.
- [b]Note:[/b] This method is only implemented on Android.
+ - [code]OS.request_permission("macos.permission.RECORD_SCREEN")[/code]
+ [b]Note:[/b] On Android, permission must be checked during export.
+ [b]Note:[/b] This method is implemented on Android and macOS.
diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h
index 0256147edca..2bb4f9cba7a 100644
--- a/platform/macos/os_macos.h
+++ b/platform/macos/os_macos.h
@@ -128,6 +128,7 @@ public:
virtual String get_model_name() const override;
virtual bool is_sandboxed() const override;
+ virtual bool request_permission(const String &p_name) override;
virtual Vector get_granted_permissions() const override;
virtual void revoke_granted_permissions() override;
diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm
index 7aa68a72418..f205c29c3c3 100644
--- a/platform/macos/os_macos.mm
+++ b/platform/macos/os_macos.mm
@@ -100,9 +100,35 @@ bool OS_MacOS::is_sandboxed() const {
return has_environment("APP_SANDBOX_CONTAINER_ID");
}
+bool OS_MacOS::request_permission(const String &p_name) {
+ if (@available(macOS 10.15, *)) {
+ if (p_name == "macos.permission.RECORD_SCREEN") {
+ if (CGPreflightScreenCaptureAccess()) {
+ return true;
+ } else {
+ CGRequestScreenCaptureAccess();
+ return false;
+ }
+ }
+ } else {
+ if (p_name == "macos.permission.RECORD_SCREEN") {
+ return true;
+ }
+ }
+ return false;
+}
+
Vector OS_MacOS::get_granted_permissions() const {
Vector ret;
+ if (@available(macOS 10.15, *)) {
+ if (CGPreflightScreenCaptureAccess()) {
+ ret.push_back("macos.permission.RECORD_SCREEN");
+ }
+ } else {
+ ret.push_back("macos.permission.RECORD_SCREEN");
+ }
+
if (is_sandboxed()) {
NSArray *bookmarks = [[NSUserDefaults standardUserDefaults] arrayForKey:@"sec_bookmarks"];
for (id bookmark in bookmarks) {
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index af891ba4830..cd6eb2641d0 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -38,6 +38,7 @@
#include "scene/gui/grid_container.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
+#include "scene/gui/link_button.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
@@ -68,6 +69,14 @@ void ColorPicker::_notification(int p_what) {
_update_color();
} break;
+#ifdef MACOS_ENABLED
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (is_visible_in_tree()) {
+ perm_hb->set_visible(!OS::get_singleton()->get_granted_permissions().has("macos.permission.RECORD_SCREEN"));
+ }
+ } break;
+#endif
+
case NOTIFICATION_READY: {
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_COLOR_PICKER)) {
btn_pick->set_accessibility_name(ETR("Pick Color From Screen"));
@@ -2215,6 +2224,23 @@ ColorPicker::ColorPicker() {
btn_add_preset->set_accessibility_name(ETR("Add Preset"));
btn_add_preset->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_add_preset_pressed));
preset_container->add_child(btn_add_preset);
+
+ perm_hb = memnew(HBoxContainer);
+ perm_hb->set_alignment(BoxContainer::ALIGNMENT_CENTER);
+
+ LinkButton *perm_link = memnew(LinkButton);
+ perm_link->set_text(ETR("Screen Recording permission missing!"));
+ perm_link->set_tooltip_text(ETR("Screen Recording permission is required to pick colors from the other application windows.\nClick here to request access..."));
+ perm_link->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_req_permission));
+ perm_hb->add_child(perm_link);
+ real_vbox->add_child(perm_hb);
+ perm_hb->set_visible(false);
+}
+
+void ColorPicker::_req_permission() {
+#ifdef MACOS_ENABLED
+ OS::get_singleton()->request_permission("macos.permission.RECORD_SCREEN");
+#endif
}
ColorPicker::~ColorPicker() {
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 78fd5a61cb2..2257e8bf044 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -186,6 +186,9 @@ private:
Ref preset_group;
Ref recent_preset_group;
+ HBoxContainer *perm_hb = nullptr;
+ void _req_permission();
+
#ifdef TOOLS_ENABLED
Callable quick_open_callback;
Callable palette_saved_callback;