Move alert
function from DisplayServer
to OS
.
This commit is contained in:
parent
5de991d57c
commit
618eb27e8b
36 changed files with 377 additions and 350 deletions
|
@ -196,6 +196,10 @@ int _OS::get_low_processor_usage_mode_sleep_usec() const {
|
|||
return OS::get_singleton()->get_low_processor_usage_mode_sleep_usec();
|
||||
}
|
||||
|
||||
void _OS::alert(const String &p_alert, const String &p_title) {
|
||||
OS::get_singleton()->alert(p_alert, p_title);
|
||||
}
|
||||
|
||||
String _OS::get_executable_path() const {
|
||||
return OS::get_singleton()->get_executable_path();
|
||||
}
|
||||
|
@ -487,6 +491,8 @@ void _OS::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs);
|
||||
ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("alert", "text", "title"), &_OS::alert, DEFVAL("Alert!"));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &_OS::set_low_processor_usage_mode);
|
||||
ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &_OS::is_in_low_processor_usage_mode);
|
||||
|
||||
|
|
|
@ -162,6 +162,8 @@ public:
|
|||
void set_low_processor_usage_mode_sleep_usec(int p_usec);
|
||||
int get_low_processor_usage_mode_sleep_usec() const;
|
||||
|
||||
void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
|
||||
String get_executable_path() const;
|
||||
int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false);
|
||||
int create_process(const String &p_path, const Vector<String> &p_arguments);
|
||||
|
|
|
@ -110,6 +110,10 @@ void OS::printerr(const char *p_format, ...) {
|
|||
va_end(argp);
|
||||
}
|
||||
|
||||
void OS::alert(const String &p_alert, const String &p_title) {
|
||||
fprintf(stderr, "%s: %s\n", p_title.utf8().get_data(), p_alert.utf8().get_data());
|
||||
}
|
||||
|
||||
void OS::set_low_processor_usage_mode(bool p_enabled) {
|
||||
low_processor_usage_mode = p_enabled;
|
||||
}
|
||||
|
|
|
@ -120,6 +120,8 @@ public:
|
|||
virtual void open_midi_inputs();
|
||||
virtual void close_midi_inputs();
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
|
||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; }
|
||||
virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; }
|
||||
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; }
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="alert">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="text" type="String">
|
||||
</argument>
|
||||
<argument index="1" name="title" type="String" default=""Alert!"">
|
||||
</argument>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="clipboard_get" qualifiers="const">
|
||||
<return type="String">
|
||||
</return>
|
||||
|
|
|
@ -10,6 +10,17 @@
|
|||
<link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="alert">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="text" type="String">
|
||||
</argument>
|
||||
<argument index="1" name="title" type="String" default=""Alert!"">
|
||||
</argument>
|
||||
<description>
|
||||
Displays a modal dialog box using the host OS' facilities. Execution is blocked until the dialog is closed.
|
||||
</description>
|
||||
</method>
|
||||
<method name="can_use_threads" qualifiers="const">
|
||||
<return type="bool">
|
||||
</return>
|
||||
|
|
|
@ -139,10 +139,6 @@ void OS_Unix::finalize_core() {
|
|||
NetSocketPosix::cleanup();
|
||||
}
|
||||
|
||||
void OS_Unix::alert(const String &p_alert, const String &p_title) {
|
||||
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
|
||||
}
|
||||
|
||||
String OS_Unix::get_stdin_string(bool p_block) {
|
||||
if (p_block) {
|
||||
char buff[1024];
|
||||
|
|
|
@ -52,7 +52,6 @@ protected:
|
|||
public:
|
||||
OS_Unix();
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
virtual String get_stdin_string(bool p_block) override;
|
||||
|
||||
//virtual void set_mouse_show(bool p_show);
|
||||
|
|
|
@ -1080,7 +1080,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||
#else
|
||||
const String error_msg = "Error: Couldn't load project data at path \"" + project_path + "\". Is the .pck file missing?\nIf you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n";
|
||||
OS::get_singleton()->print("%s", error_msg.ascii().get_data());
|
||||
DisplayServer::get_singleton()->alert(error_msg);
|
||||
OS::get_singleton()->alert(error_msg);
|
||||
|
||||
goto error;
|
||||
#endif
|
||||
|
@ -2015,6 +2015,7 @@ bool Main::start() {
|
|||
// Let's throw an error gently. The code leading to this is pretty brittle so
|
||||
// this might end up triggered by valid usage, in which case we'll have to
|
||||
// fine-tune further.
|
||||
OS::get_singleton()->alert("Couldn't detect whether to run the editor, the project manager or a specific project. Aborting.");
|
||||
ERR_FAIL_V_MSG(false, "Couldn't detect whether to run the editor, the project manager or a specific project. Aborting.");
|
||||
}
|
||||
#endif
|
||||
|
@ -2044,9 +2045,8 @@ bool Main::start() {
|
|||
if (obj) {
|
||||
memdelete(obj);
|
||||
}
|
||||
ERR_FAIL_V_MSG(false,
|
||||
vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.",
|
||||
script));
|
||||
OS::get_singleton()->alert(vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script));
|
||||
ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script));
|
||||
}
|
||||
|
||||
script_loop->set_initialize_script(script_res);
|
||||
|
@ -2065,7 +2065,7 @@ bool Main::start() {
|
|||
if (obj) {
|
||||
memdelete(obj);
|
||||
}
|
||||
DisplayServer::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base);
|
||||
OS::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base);
|
||||
ERR_FAIL_V_MSG(false, vformat("The global class %s does not inherit from SceneTree or MainLoop.", main_loop_type));
|
||||
}
|
||||
script_loop->set_initialize_script(script_res);
|
||||
|
@ -2079,7 +2079,7 @@ bool Main::start() {
|
|||
|
||||
if (!main_loop) {
|
||||
if (!ClassDB::class_exists(main_loop_type)) {
|
||||
DisplayServer::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type);
|
||||
OS::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type);
|
||||
return false;
|
||||
} else {
|
||||
Object *ml = ClassDB::instantiate(main_loop_type);
|
||||
|
|
|
@ -334,13 +334,6 @@ bool DisplayServerAndroid::can_any_window_draw() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::alert(const String &p_alert, const String &p_title) {
|
||||
GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
|
||||
ERR_FAIL_COND(!godot_java);
|
||||
|
||||
godot_java->alert(p_alert, p_title);
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::process_events() {
|
||||
Input::get_singleton()->flush_accumulated_events();
|
||||
}
|
||||
|
@ -361,7 +354,7 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
|
|||
DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
|
||||
DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
|
||||
if (r_error != OK) {
|
||||
ds->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
|
||||
}
|
||||
return ds;
|
||||
}
|
||||
|
|
|
@ -204,8 +204,6 @@ public:
|
|||
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title) override;
|
||||
|
||||
virtual void process_events() override;
|
||||
|
||||
void process_accelerometer(const Vector3 &p_accelerometer);
|
||||
|
|
|
@ -71,6 +71,13 @@ public:
|
|||
virtual ~AndroidLogger() {}
|
||||
};
|
||||
|
||||
void OS_Android::alert(const String &p_alert, const String &p_title) {
|
||||
GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
|
||||
ERR_FAIL_COND(!godot_java);
|
||||
|
||||
godot_java->alert(p_alert, p_title);
|
||||
}
|
||||
|
||||
void OS_Android::initialize_core() {
|
||||
OS_Unix::initialize_core();
|
||||
|
||||
|
|
|
@ -86,6 +86,8 @@ public:
|
|||
virtual bool request_permissions() override;
|
||||
virtual Vector<String> get_granted_permissions() const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title) override;
|
||||
|
||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
|
||||
|
||||
virtual String get_name() const override;
|
||||
|
|
|
@ -119,8 +119,6 @@ public:
|
|||
virtual bool has_feature(Feature p_feature) const override;
|
||||
virtual String get_name() const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual int get_screen_count() const override;
|
||||
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
|
|
|
@ -320,12 +320,6 @@ String DisplayServerIPhone::get_name() const {
|
|||
return "iPhone";
|
||||
}
|
||||
|
||||
void DisplayServerIPhone::alert(const String &p_alert, const String &p_title) {
|
||||
const CharString utf8_alert = p_alert.utf8();
|
||||
const CharString utf8_title = p_title.utf8();
|
||||
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
|
||||
}
|
||||
|
||||
int DisplayServerIPhone::get_screen_count() const {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -92,13 +92,12 @@ public:
|
|||
|
||||
void start();
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
|
||||
virtual Error close_dynamic_library(void *p_library_handle) override;
|
||||
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
|
||||
|
||||
virtual void alert(const String &p_alert,
|
||||
const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual String get_name() const override;
|
||||
virtual String get_model_name() const override;
|
||||
|
||||
|
|
|
@ -114,6 +114,12 @@ OSIPhone::OSIPhone(String p_data_dir) {
|
|||
|
||||
OSIPhone::~OSIPhone() {}
|
||||
|
||||
void OSIPhone::alert(const String &p_alert, const String &p_title) {
|
||||
const CharString utf8_alert = p_alert.utf8();
|
||||
const CharString utf8_title = p_title.utf8();
|
||||
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
|
||||
}
|
||||
|
||||
void OSIPhone::initialize_core() {
|
||||
OS_Unix::initialize_core();
|
||||
|
||||
|
@ -221,12 +227,6 @@ Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const
|
|||
return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional);
|
||||
}
|
||||
|
||||
void OSIPhone::alert(const String &p_alert, const String &p_title) {
|
||||
const CharString utf8_alert = p_alert.utf8();
|
||||
const CharString utf8_title = p_title.utf8();
|
||||
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
|
||||
}
|
||||
|
||||
String OSIPhone::get_name() const {
|
||||
return "iOS";
|
||||
};
|
||||
|
|
|
@ -659,10 +659,6 @@ void DisplayServerJavaScript::send_window_event_callback(int p_notification) {
|
|||
}
|
||||
}
|
||||
|
||||
void DisplayServerJavaScript::alert(const String &p_alert, const String &p_title) {
|
||||
godot_js_display_alert(p_alert.utf8().get_data());
|
||||
}
|
||||
|
||||
void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) {
|
||||
ERR_FAIL_COND(p_icon.is_null());
|
||||
Ref<Image> icon = p_icon;
|
||||
|
|
|
@ -109,7 +109,6 @@ public:
|
|||
bool check_size_force_redraw();
|
||||
|
||||
// from DisplayServer
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
virtual bool has_feature(Feature p_feature) const override;
|
||||
virtual String get_name() const override;
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
|
||||
#include "godot_js.h"
|
||||
|
||||
void OS_JavaScript::alert(const String &p_alert, const String &p_title) {
|
||||
godot_js_display_alert(p_alert.utf8().get_data());
|
||||
}
|
||||
|
||||
// Lifecycle
|
||||
void OS_JavaScript::initialize() {
|
||||
OS_Unix::initialize_core();
|
||||
|
|
|
@ -89,6 +89,9 @@ public:
|
|||
String get_user_data_dir() const override;
|
||||
|
||||
bool is_userfs_persistent() const override;
|
||||
|
||||
void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) override;
|
||||
|
||||
void resume_audio();
|
||||
|
|
|
@ -136,70 +136,6 @@ String DisplayServerX11::get_name() const {
|
|||
return "X11";
|
||||
}
|
||||
|
||||
void DisplayServerX11::alert(const String &p_alert, const String &p_title) {
|
||||
const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" };
|
||||
|
||||
String path = OS::get_singleton()->get_environment("PATH");
|
||||
Vector<String> path_elems = path.split(":", false);
|
||||
String program;
|
||||
|
||||
for (int i = 0; i < path_elems.size(); i++) {
|
||||
for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
|
||||
String tested_path = path_elems[i].plus_file(message_programs[k]);
|
||||
|
||||
if (FileAccess::exists(tested_path)) {
|
||||
program = tested_path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (program.length()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> args;
|
||||
|
||||
if (program.ends_with("zenity")) {
|
||||
args.push_back("--error");
|
||||
args.push_back("--width");
|
||||
args.push_back("500");
|
||||
args.push_back("--title");
|
||||
args.push_back(p_title);
|
||||
args.push_back("--text");
|
||||
args.push_back(p_alert);
|
||||
}
|
||||
|
||||
if (program.ends_with("kdialog")) {
|
||||
args.push_back("--error");
|
||||
args.push_back(p_alert);
|
||||
args.push_back("--title");
|
||||
args.push_back(p_title);
|
||||
}
|
||||
|
||||
if (program.ends_with("Xdialog")) {
|
||||
args.push_back("--title");
|
||||
args.push_back(p_title);
|
||||
args.push_back("--msgbox");
|
||||
args.push_back(p_alert);
|
||||
args.push_back("0");
|
||||
args.push_back("0");
|
||||
}
|
||||
|
||||
if (program.ends_with("xmessage")) {
|
||||
args.push_back("-center");
|
||||
args.push_back("-title");
|
||||
args.push_back(p_title);
|
||||
args.push_back(p_alert);
|
||||
}
|
||||
|
||||
if (program.length()) {
|
||||
OS::get_singleton()->execute(program, args);
|
||||
} else {
|
||||
print_line(p_alert);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) {
|
||||
Window root_return, child_return;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
|
@ -3677,8 +3613,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
|
|||
DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
|
||||
DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
|
||||
if (r_error != OK) {
|
||||
ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
"Unable to initialize Video driver");
|
||||
}
|
||||
return ds;
|
||||
|
@ -3976,8 +3912,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
}
|
||||
|
||||
if (!_refresh_device_info()) {
|
||||
alert("Your system does not support XInput 2.\n"
|
||||
"Please upgrade your distribution.",
|
||||
OS::get_singleton()->alert("Your system does not support XInput 2.\n"
|
||||
"Please upgrade your distribution.",
|
||||
"Unable to initialize XInput");
|
||||
r_error = ERR_UNAVAILABLE;
|
||||
return;
|
||||
|
|
|
@ -280,8 +280,6 @@ public:
|
|||
virtual bool has_feature(Feature p_feature) const override;
|
||||
virtual String get_name() const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual void mouse_set_mode(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode() const override;
|
||||
|
||||
|
|
|
@ -51,6 +51,70 @@
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) {
|
||||
const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" };
|
||||
|
||||
String path = get_environment("PATH");
|
||||
Vector<String> path_elems = path.split(":", false);
|
||||
String program;
|
||||
|
||||
for (int i = 0; i < path_elems.size(); i++) {
|
||||
for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
|
||||
String tested_path = path_elems[i].plus_file(message_programs[k]);
|
||||
|
||||
if (FileAccess::exists(tested_path)) {
|
||||
program = tested_path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (program.length()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> args;
|
||||
|
||||
if (program.ends_with("zenity")) {
|
||||
args.push_back("--error");
|
||||
args.push_back("--width");
|
||||
args.push_back("500");
|
||||
args.push_back("--title");
|
||||
args.push_back(p_title);
|
||||
args.push_back("--text");
|
||||
args.push_back(p_alert);
|
||||
}
|
||||
|
||||
if (program.ends_with("kdialog")) {
|
||||
args.push_back("--error");
|
||||
args.push_back(p_alert);
|
||||
args.push_back("--title");
|
||||
args.push_back(p_title);
|
||||
}
|
||||
|
||||
if (program.ends_with("Xdialog")) {
|
||||
args.push_back("--title");
|
||||
args.push_back(p_title);
|
||||
args.push_back("--msgbox");
|
||||
args.push_back(p_alert);
|
||||
args.push_back("0");
|
||||
args.push_back("0");
|
||||
}
|
||||
|
||||
if (program.ends_with("xmessage")) {
|
||||
args.push_back("-center");
|
||||
args.push_back("-title");
|
||||
args.push_back(p_title);
|
||||
args.push_back(p_alert);
|
||||
}
|
||||
|
||||
if (program.length()) {
|
||||
execute(program, args);
|
||||
} else {
|
||||
print_line(p_alert);
|
||||
}
|
||||
}
|
||||
|
||||
void OS_LinuxBSD::initialize() {
|
||||
crash_handler.initialize();
|
||||
|
||||
|
|
|
@ -90,6 +90,8 @@ public:
|
|||
|
||||
virtual String get_unique_id() const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual bool _check_internal_feature_support(const String &p_feature) override;
|
||||
|
||||
void run();
|
||||
|
|
|
@ -60,6 +60,10 @@ class DisplayServerOSX : public DisplayServer {
|
|||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
void _send_event(NSEvent *p_event);
|
||||
NSMenu *_get_dock_menu() const;
|
||||
void _menu_callback(id p_sender);
|
||||
|
||||
#if defined(OPENGL_ENABLED)
|
||||
ContextGL_OSX *context_gles2;
|
||||
#endif
|
||||
|
@ -163,7 +167,6 @@ public:
|
|||
|
||||
String rendering_driver;
|
||||
|
||||
id delegate;
|
||||
id autoreleasePool;
|
||||
CGEventSourceRef eventSource;
|
||||
|
||||
|
@ -207,7 +210,6 @@ public:
|
|||
virtual void global_menu_remove_item(const String &p_menu_root, int p_idx) override;
|
||||
virtual void global_menu_clear(const String &p_menu_root) override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) override;
|
||||
virtual Error dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) override;
|
||||
|
||||
|
|
|
@ -104,46 +104,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
|
|||
return [NSCursor arrowCursor];
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* GodotApplication */
|
||||
/*************************************************************************/
|
||||
|
||||
@interface GodotApplication : NSApplication
|
||||
@end
|
||||
|
||||
@implementation GodotApplication
|
||||
|
||||
- (void)sendEvent:(NSEvent *)event {
|
||||
// special case handling of command-period, which is traditionally a special
|
||||
// shortcut in macOS and doesn't arrive at our regular keyDown handler.
|
||||
if ([event type] == NSEventTypeKeyDown) {
|
||||
if (([event modifierFlags] & NSEventModifierFlagCommand) && [event keyCode] == 0x2f) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instantiate();
|
||||
|
||||
_get_key_modifier_state([event modifierFlags], k);
|
||||
k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID);
|
||||
k->set_pressed(true);
|
||||
k->set_keycode(KEY_PERIOD);
|
||||
k->set_physical_keycode(KEY_PERIOD);
|
||||
k->set_echo([event isARepeat]);
|
||||
|
||||
Input::get_singleton()->accumulate_input_event(k);
|
||||
}
|
||||
}
|
||||
|
||||
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
|
||||
// This works around an AppKit bug, where key up events while holding
|
||||
// down the command key don't get sent to the key window.
|
||||
if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) {
|
||||
[[self keyWindow] sendEvent:event];
|
||||
} else {
|
||||
[super sendEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************************************/
|
||||
/* GlobalMenuItem */
|
||||
/*************************************************************************/
|
||||
|
@ -160,121 +120,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
|
|||
@implementation GlobalMenuItem
|
||||
@end
|
||||
|
||||
/*************************************************************************/
|
||||
/* GodotApplicationDelegate */
|
||||
/*************************************************************************/
|
||||
|
||||
@interface GodotApplicationDelegate : NSObject
|
||||
- (void)forceUnbundledWindowActivationHackStep1;
|
||||
- (void)forceUnbundledWindowActivationHackStep2;
|
||||
- (void)forceUnbundledWindowActivationHackStep3;
|
||||
@end
|
||||
|
||||
@implementation GodotApplicationDelegate
|
||||
|
||||
- (void)forceUnbundledWindowActivationHackStep1 {
|
||||
// Step1: Switch focus to macOS Dock.
|
||||
// Required to perform step 2, TransformProcessType will fail if app is already the in focus.
|
||||
for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) {
|
||||
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
break;
|
||||
}
|
||||
[self performSelector:@selector(forceUnbundledWindowActivationHackStep2) withObject:nil afterDelay:0.02];
|
||||
}
|
||||
|
||||
- (void)forceUnbundledWindowActivationHackStep2 {
|
||||
// Step 2: Register app as foreground process.
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
(void)TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
[self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02];
|
||||
}
|
||||
|
||||
- (void)forceUnbundledWindowActivationHackStep3 {
|
||||
// Step 3: Switch focus back to app window.
|
||||
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notice {
|
||||
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||
if (nsappname == nil) {
|
||||
// If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored).
|
||||
[self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidResignActive:(NSNotification *)notification {
|
||||
if (OS_OSX::get_singleton()->get_main_loop()) {
|
||||
OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)notification {
|
||||
if (OS_OSX::get_singleton()->get_main_loop()) {
|
||||
OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)globalMenuCallback:(id)sender {
|
||||
if (![sender representedObject]) {
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalMenuItem *value = [sender representedObject];
|
||||
|
||||
if (value) {
|
||||
if (value->checkable) {
|
||||
if ([sender state] == NSControlStateValueOff) {
|
||||
[sender setState:NSControlStateValueOn];
|
||||
} else {
|
||||
[sender setState:NSControlStateValueOff];
|
||||
}
|
||||
}
|
||||
|
||||
if (value->callback != Callable()) {
|
||||
Variant tag = value->meta;
|
||||
Variant *tagp = &tag;
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
value->callback.call((const Variant **)&tagp, 1, ret, ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
|
||||
return DS_OSX->dock_menu;
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
|
||||
// Note: may be called called before main loop init!
|
||||
char *utfs = strdup([filename UTF8String]);
|
||||
((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename.parse_utf8(utfs);
|
||||
free(utfs);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// Open new instance
|
||||
if (OS_OSX::get_singleton()->get_main_loop()) {
|
||||
List<String> args;
|
||||
args.push_back(((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename);
|
||||
String exec = OS::get_singleton()->get_executable_path();
|
||||
OS::get_singleton()->create_process(exec, args);
|
||||
}
|
||||
#endif
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||
DS_OSX->_send_window_event(DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (void)showAbout:(id)sender {
|
||||
if (OS_OSX::get_singleton()->get_main_loop()) {
|
||||
OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************************************/
|
||||
/* GodotWindowDelegate */
|
||||
/*************************************************************************/
|
||||
|
@ -1983,26 +1828,6 @@ void DisplayServerOSX::global_menu_clear(const String &p_menu_root) {
|
|||
}
|
||||
}
|
||||
|
||||
void DisplayServerOSX::alert(const String &p_alert, const String &p_title) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
NSAlert *window = [[NSAlert alloc] init];
|
||||
NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()];
|
||||
NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()];
|
||||
|
||||
[window addButtonWithTitle:@"OK"];
|
||||
[window setMessageText:ns_title];
|
||||
[window setInformativeText:ns_alert];
|
||||
[window setAlertStyle:NSAlertStyleWarning];
|
||||
|
||||
id key_window = [[NSApplication sharedApplication] keyWindow];
|
||||
[window runModal];
|
||||
[window release];
|
||||
if (key_window) {
|
||||
[key_window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
}
|
||||
|
||||
Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
@ -3375,6 +3200,56 @@ void DisplayServerOSX::_release_pressed_events() {
|
|||
}
|
||||
}
|
||||
|
||||
NSMenu *DisplayServerOSX::_get_dock_menu() const {
|
||||
return dock_menu;
|
||||
}
|
||||
|
||||
void DisplayServerOSX::_menu_callback(id p_sender) {
|
||||
if (![p_sender representedObject]) {
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalMenuItem *value = [p_sender representedObject];
|
||||
|
||||
if (value) {
|
||||
if (value->checkable) {
|
||||
if ([p_sender state] == NSControlStateValueOff) {
|
||||
[p_sender setState:NSControlStateValueOn];
|
||||
} else {
|
||||
[p_sender setState:NSControlStateValueOff];
|
||||
}
|
||||
}
|
||||
|
||||
if (value->callback != Callable()) {
|
||||
Variant tag = value->meta;
|
||||
Variant *tagp = &tag;
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
value->callback.call((const Variant **)&tagp, 1, ret, ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerOSX::_send_event(NSEvent *p_event) {
|
||||
// special case handling of command-period, which is traditionally a special
|
||||
// shortcut in macOS and doesn't arrive at our regular keyDown handler.
|
||||
if ([p_event type] == NSEventTypeKeyDown) {
|
||||
if (([p_event modifierFlags] & NSEventModifierFlagCommand) && [p_event keyCode] == 0x2f) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instantiate();
|
||||
|
||||
_get_key_modifier_state([p_event modifierFlags], k);
|
||||
k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID);
|
||||
k->set_pressed(true);
|
||||
k->set_keycode(KEY_PERIOD);
|
||||
k->set_physical_keycode(KEY_PERIOD);
|
||||
k->set_echo([p_event isARepeat]);
|
||||
|
||||
Input::get_singleton()->accumulate_input_event(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerOSX::_process_key_events() {
|
||||
Ref<InputEventKey> k;
|
||||
for (int i = 0; i < key_event_pos; i++) {
|
||||
|
@ -3615,7 +3490,7 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co
|
|||
DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
|
||||
DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
|
||||
if (r_error != OK) {
|
||||
ds->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver");
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver");
|
||||
}
|
||||
return ds;
|
||||
}
|
||||
|
@ -3785,12 +3660,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
|
|||
|
||||
CGEventSourceSetLocalEventsSuppressionInterval(eventSource, 0.0);
|
||||
|
||||
// Implicitly create shared NSApplication instance
|
||||
[GodotApplication sharedApplication];
|
||||
|
||||
// In case we are unbundled, make us a proper UI application
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
||||
keyboard_layout_dirty = true;
|
||||
displays_arrangement_dirty = true;
|
||||
displays_scale_dirty = true;
|
||||
|
@ -3804,9 +3673,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
|
|||
// Register to be notified on displays arrangement changes
|
||||
CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, nullptr);
|
||||
|
||||
// Menu bar setup must go between sharedApplication above and
|
||||
// finishLaunching below, in order to properly emulate the behavior
|
||||
// of NSApplicationMain
|
||||
NSMenuItem *menu_item;
|
||||
NSString *title;
|
||||
|
||||
|
@ -3846,32 +3712,10 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
|
|||
title = [NSString stringWithFormat:NSLocalizedString(@"Quit %@", nil), nsappname];
|
||||
[apple_menu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
|
||||
|
||||
// Setup menu bar
|
||||
NSMenu *main_menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
// Add items to the menu bar
|
||||
NSMenu *main_menu = [NSApp mainMenu];
|
||||
menu_item = [main_menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
|
||||
[main_menu setSubmenu:apple_menu forItem:menu_item];
|
||||
[NSApp setMainMenu:main_menu];
|
||||
|
||||
[NSApp finishLaunching];
|
||||
|
||||
delegate = [[GodotApplicationDelegate alloc] init];
|
||||
ERR_FAIL_COND(!delegate);
|
||||
[NSApp setDelegate:delegate];
|
||||
|
||||
//process application:openFile: event
|
||||
while (true) {
|
||||
NSEvent *event = [NSApp
|
||||
nextEventMatchingMask:NSEventMaskAny
|
||||
untilDate:[NSDate distantPast]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
|
||||
if (event == nil) {
|
||||
break;
|
||||
}
|
||||
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
//TODO - do Vulkan and GLES2 support checks, driver selection and fallback
|
||||
|
@ -3924,8 +3768,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
|
|||
RendererCompositorRD::make_current();
|
||||
}
|
||||
#endif
|
||||
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
DisplayServerOSX::~DisplayServerOSX() {
|
||||
|
|
|
@ -72,6 +72,8 @@ protected:
|
|||
public:
|
||||
virtual String get_name() const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
|
||||
|
||||
virtual MainLoop *get_main_loop() const override;
|
||||
|
|
|
@ -41,6 +41,137 @@
|
|||
#include <mach-o/dyld.h>
|
||||
#include <os/log.h>
|
||||
|
||||
#define DS_OSX ((DisplayServerOSX *)(DisplayServerOSX::get_singleton()))
|
||||
|
||||
/*************************************************************************/
|
||||
/* GodotApplication */
|
||||
/*************************************************************************/
|
||||
|
||||
@interface GodotApplication : NSApplication
|
||||
@end
|
||||
|
||||
@implementation GodotApplication
|
||||
|
||||
- (void)sendEvent:(NSEvent *)event {
|
||||
if (DS_OSX) {
|
||||
DS_OSX->_send_event(event);
|
||||
}
|
||||
|
||||
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
|
||||
// This works around an AppKit bug, where key up events while holding
|
||||
// down the command key don't get sent to the key window.
|
||||
if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) {
|
||||
[[self keyWindow] sendEvent:event];
|
||||
} else {
|
||||
[super sendEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************************************/
|
||||
/* GodotApplicationDelegate */
|
||||
/*************************************************************************/
|
||||
|
||||
@interface GodotApplicationDelegate : NSObject
|
||||
- (void)forceUnbundledWindowActivationHackStep1;
|
||||
- (void)forceUnbundledWindowActivationHackStep2;
|
||||
- (void)forceUnbundledWindowActivationHackStep3;
|
||||
@end
|
||||
|
||||
@implementation GodotApplicationDelegate
|
||||
|
||||
- (void)forceUnbundledWindowActivationHackStep1 {
|
||||
// Step1: Switch focus to macOS Dock.
|
||||
// Required to perform step 2, TransformProcessType will fail if app is already the in focus.
|
||||
for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) {
|
||||
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
break;
|
||||
}
|
||||
[self performSelector:@selector(forceUnbundledWindowActivationHackStep2)
|
||||
withObject:nil
|
||||
afterDelay:0.02];
|
||||
}
|
||||
|
||||
- (void)forceUnbundledWindowActivationHackStep2 {
|
||||
// Step 2: Register app as foreground process.
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
(void)TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
[self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02];
|
||||
}
|
||||
|
||||
- (void)forceUnbundledWindowActivationHackStep3 {
|
||||
// Step 3: Switch focus back to app window.
|
||||
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notice {
|
||||
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||
if (nsappname == nil) {
|
||||
// If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored).
|
||||
[self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidResignActive:(NSNotification *)notification {
|
||||
if (OS::get_singleton()->get_main_loop()) {
|
||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)notification {
|
||||
if (OS::get_singleton()->get_main_loop()) {
|
||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)globalMenuCallback:(id)sender {
|
||||
if (DS_OSX) {
|
||||
return DS_OSX->_menu_callback(sender);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
|
||||
if (DS_OSX) {
|
||||
return DS_OSX->_get_dock_menu();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
|
||||
// Note: may be called called before main loop init!
|
||||
char *utfs = strdup([filename UTF8String]);
|
||||
((OS_OSX *)OS_OSX::get_singleton())->open_with_filename.parse_utf8(utfs);
|
||||
free(utfs);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// Open new instance
|
||||
if (OS_OSX::get_singleton()->get_main_loop()) {
|
||||
List<String> args;
|
||||
args.push_back(((OS_OSX *)OS_OSX::get_singleton())->open_with_filename);
|
||||
String exec = OS_OSX::get_singleton()->get_executable_path();
|
||||
OS_OSX::get_singleton()->create_process(exec, args);
|
||||
}
|
||||
#endif
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||
if (DS_OSX) {
|
||||
DS_OSX->_send_window_event(DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
|
||||
}
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (void)showAbout:(id)sender {
|
||||
if (OS_OSX::get_singleton()->get_main_loop()) {
|
||||
OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*************************************************************************/
|
||||
/* OSXTerminalLogger */
|
||||
/*************************************************************************/
|
||||
|
@ -119,6 +250,24 @@ String OS_OSX::get_unique_id() const {
|
|||
return serial_number;
|
||||
}
|
||||
|
||||
void OS_OSX::alert(const String &p_alert, const String &p_title) {
|
||||
NSAlert *window = [[NSAlert alloc] init];
|
||||
NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()];
|
||||
NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()];
|
||||
|
||||
[window addButtonWithTitle:@"OK"];
|
||||
[window setMessageText:ns_title];
|
||||
[window setInformativeText:ns_alert];
|
||||
[window setAlertStyle:NSAlertStyleWarning];
|
||||
|
||||
id key_window = [[NSApplication sharedApplication] keyWindow];
|
||||
[window runModal];
|
||||
[window release];
|
||||
if (key_window) {
|
||||
[key_window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void OS_OSX::initialize_core() {
|
||||
OS_Unix::initialize_core();
|
||||
|
||||
|
@ -372,6 +521,41 @@ OS_OSX::OS_OSX() {
|
|||
#endif
|
||||
|
||||
DisplayServerOSX::register_osx_driver();
|
||||
|
||||
// Implicitly create shared NSApplication instance
|
||||
[GodotApplication sharedApplication];
|
||||
|
||||
// In case we are unbundled, make us a proper UI application
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
||||
// Menu bar setup must go between sharedApplication above and
|
||||
// finishLaunching below, in order to properly emulate the behavior
|
||||
// of NSApplicationMain
|
||||
|
||||
NSMenu *main_menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
[NSApp setMainMenu:main_menu];
|
||||
[NSApp finishLaunching];
|
||||
|
||||
id delegate = [[GodotApplicationDelegate alloc] init];
|
||||
ERR_FAIL_COND(!delegate);
|
||||
[NSApp setDelegate:delegate];
|
||||
|
||||
//process application:openFile: event
|
||||
while (true) {
|
||||
NSEvent *event = [NSApp
|
||||
nextEventMatchingMask:NSEventMaskAny
|
||||
untilDate:[NSDate distantPast]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
|
||||
if (event == nil) {
|
||||
break;
|
||||
}
|
||||
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
|
||||
|
|
|
@ -79,10 +79,6 @@ String DisplayServerWindows::get_name() const {
|
|||
return "Windows";
|
||||
}
|
||||
|
||||
void DisplayServerWindows::alert(const String &p_alert, const String &p_title) {
|
||||
MessageBoxW(nullptr, (LPCWSTR)(p_alert.utf16().get_data()), (LPCWSTR)(p_title.utf16().get_data()), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
|
||||
if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) {
|
||||
// Mouse is grabbed (captured or confined).
|
||||
|
@ -3358,8 +3354,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
|
|||
DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
|
||||
DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
|
||||
if (r_error != OK) {
|
||||
ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
"Unable to initialize Video driver");
|
||||
}
|
||||
return ds;
|
||||
|
|
|
@ -442,8 +442,6 @@ public:
|
|||
virtual bool has_feature(Feature p_feature) const override;
|
||||
virtual String get_name() const override;
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual void mouse_set_mode(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode() const override;
|
||||
|
||||
|
|
|
@ -165,6 +165,10 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
|
|||
}
|
||||
}
|
||||
|
||||
void OS_Windows::alert(const String &p_alert, const String &p_title) {
|
||||
MessageBoxW(nullptr, (LPCWSTR)(p_alert.utf16().get_data()), (LPCWSTR)(p_title.utf16().get_data()), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
void OS_Windows::initialize_debugging() {
|
||||
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ protected:
|
|||
Map<ProcessID, ProcessInfo> *process_map;
|
||||
|
||||
public:
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||
|
||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
|
||||
virtual Error close_dynamic_library(void *p_library_handle) override;
|
||||
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
|
||||
|
|
|
@ -346,8 +346,6 @@ void DisplayServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("global_menu_remove_item", "menu_root", "idx"), &DisplayServer::global_menu_remove_item);
|
||||
ClassDB::bind_method(D_METHOD("global_menu_clear", "menu_root"), &DisplayServer::global_menu_clear);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("alert", "text", "title"), &DisplayServer::alert, DEFVAL("Alert!"));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("mouse_set_mode", "mouse_mode"), &DisplayServer::mouse_set_mode);
|
||||
ClassDB::bind_method(D_METHOD("mouse_get_mode"), &DisplayServer::mouse_get_mode);
|
||||
|
||||
|
|
|
@ -143,8 +143,6 @@ public:
|
|||
virtual void global_menu_remove_item(const String &p_menu_root, int p_idx);
|
||||
virtual void global_menu_clear(const String &p_menu_root);
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0;
|
||||
|
||||
enum MouseMode {
|
||||
MOUSE_MODE_VISIBLE,
|
||||
MOUSE_MODE_HIDDEN,
|
||||
|
|
|
@ -55,8 +55,6 @@ public:
|
|||
bool has_feature(Feature p_feature) const override { return false; }
|
||||
String get_name() const override { return "headless"; }
|
||||
|
||||
void alert(const String &p_alert, const String &p_title = "ALERT!") override {}
|
||||
|
||||
int get_screen_count() const override { return 0; }
|
||||
Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Point2i(); }
|
||||
Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Size2i(); }
|
||||
|
|
Loading…
Reference in a new issue