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;