diff --git a/main/main.cpp b/main/main.cpp index 52284788d5d5..d04d201d917a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1415,6 +1415,72 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } #endif +#ifdef TOOLS_ENABLED + String game_path; + String script; + String test; + String export_preset; + String positional_arg; + + List args = OS::get_singleton()->get_cmdline_args(); + for (int i = 0; i < args.size(); i++) { + if (args[i].length() && args[i][0] != '-' && positional_arg == "") { + positional_arg = args[i]; + + if (args[i].ends_with(".scn") || + args[i].ends_with(".tscn") || + args[i].ends_with(".escn") || + args[i].ends_with(".res") || + args[i].ends_with(".tres")) { + // Only consider the positional argument to be a scene path if it ends with + // a file extension associated with Godot scenes. This makes it possible + // for projects to parse command-line arguments for custom CLI arguments + // or other file extensions without trouble. This can be used to implement + // "drag-and-drop onto executable" logic, which can prove helpful + // for non-game applications. + game_path = args[i]; + } + } else if (i < (args.size() - 1)) { + bool parsed_pair = true; + if (args[i] == "-s" || args[i] == "--script") { + script = args[i + 1]; + } else if (args[i] == "--test") { + test = args[i + 1]; + } else if (args[i] == "--export") { + export_preset = args[i + 1]; + } else if (args[i] == "--export-debug") { + export_preset = args[i + 1]; + } else if (args[i] == "--export-pack") { + export_preset = args[i + 1]; + } else { + // The parameter does not match anything known, don't skip the next argument + parsed_pair = false; + } + if (parsed_pair) { + i++; + } + } + } +#endif + + if (editor) { + OS::get_singleton()->set_context(OS::CONTEXT_EDITOR); + } + +#ifdef TOOLS_ENABLED + if (script == "" && game_path == "" && String(GLOBAL_DEF("application/run/main_scene", "")) != "") { + game_path = GLOBAL_DEF("application/run/main_scene", ""); + } + if (editor) { + if (export_preset != "") { + game_path = ""; // Do not load anything. + } + } + if (project_manager || (script == "" && test == "" && game_path == "" && !editor)) { + OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN); + } +#endif + Error err = OS::get_singleton()->initialize(video_mode, video_driver_idx, audio_driver_idx); if (err != OK) { return err; diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index f147298b351a..e293b248e954 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -30,6 +30,8 @@ #include "context_gl_x11.h" +#include "core/project_settings.h" + #ifdef X11_ENABLED #if defined(OPENGL_ENABLED) #include @@ -80,20 +82,44 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { return 0; } -static void set_class_hint(Display *p_display, Window p_window) { - XClassHint *classHint; +static void set_class_hint(Display *p_display, Window p_window, int p_context) { + XClassHint *classHint = XAllocClassHint(); - /* set the name and class hints for the window manager to use */ - classHint = XAllocClassHint(); if (classHint) { - classHint->res_name = (char *)"Godot_Engine"; - classHint->res_class = (char *)"Godot"; + CharString name_str; + switch (p_context) { + case OS::CONTEXT_EDITOR: + name_str = "Godot_Editor"; + break; + case OS::CONTEXT_PROJECTMAN: + name_str = "Godot_ProjectList"; + break; + case OS::CONTEXT_ENGINE: + name_str = "Godot_Engine"; + break; + } + + CharString class_str; + if (p_context == OS::CONTEXT_ENGINE) { + String config_name = GLOBAL_GET("application/config/name"); + if (config_name.length() == 0) { + class_str = "Godot_Engine"; + } else { + class_str = config_name.utf8(); + } + } else { + class_str = "Godot"; + } + + classHint->res_class = class_str.ptrw(); + classHint->res_name = name_str.ptrw(); + + XSetClassHint(p_display, p_window, classHint); + XFree(classHint); } - XSetClassHint(p_display, p_window, classHint); - XFree(classHint); } -Error ContextGL_X11::initialize() { +Error ContextGL_X11::initialize(int p_context) { //const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB"); @@ -203,7 +229,7 @@ Error ContextGL_X11::initialize() { XStoreName(x11_display, x11_window, "Godot Engine"); ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED); - set_class_hint(x11_display, x11_window); + set_class_hint(x11_display, x11_window, p_context); if (!OS::get_singleton()->is_no_window_mode_enabled()) { XMapWindow(x11_display, x11_window); diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index 9dc603806542..c613d8725f13 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -73,7 +73,7 @@ class ContextGL_X11 { void make_offscreen_current(); void release_offscreen_current(); - Error initialize(); + Error initialize(int p_context); void set_use_vsync(bool p_use); bool is_using_vsync() const; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index e52d23881514..9029bcb42d2d 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -361,7 +361,7 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a while (!context_gl) { context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type)); - if (context_gl->initialize() != OK) { + if (context_gl->initialize(context) != OK) { memdelete(context_gl); context_gl = nullptr; @@ -4077,39 +4077,43 @@ bool OS_X11::is_vsync_enabled() const { } */ void OS_X11::set_context(int p_context) { - XClassHint *classHint = XAllocClassHint(); + context = p_context; - if (classHint) { - CharString name_str; - switch (p_context) { - case CONTEXT_EDITOR: - name_str = "Godot_Editor"; - break; - case CONTEXT_PROJECTMAN: - name_str = "Godot_ProjectList"; - break; - case CONTEXT_ENGINE: - name_str = "Godot_Engine"; - break; - } + if (x11_window) { + XClassHint *classHint = XAllocClassHint(); - CharString class_str; - if (p_context == CONTEXT_ENGINE) { - String config_name = GLOBAL_GET("application/config/name"); - if (config_name.length() == 0) { - class_str = "Godot_Engine"; + if (classHint) { + CharString name_str; + switch (context) { + case CONTEXT_EDITOR: + name_str = "Godot_Editor"; + break; + case CONTEXT_PROJECTMAN: + name_str = "Godot_ProjectList"; + break; + case CONTEXT_ENGINE: + name_str = "Godot_Engine"; + break; + } + + CharString class_str; + if (context == CONTEXT_ENGINE) { + String config_name = GLOBAL_GET("application/config/name"); + if (config_name.length() == 0) { + class_str = "Godot_Engine"; + } else { + class_str = config_name.utf8(); + } } else { - class_str = config_name.utf8(); + class_str = "Godot"; } - } else { - class_str = "Godot"; - } - classHint->res_class = class_str.ptrw(); - classHint->res_name = name_str.ptrw(); + classHint->res_class = class_str.ptrw(); + classHint->res_name = name_str.ptrw(); - XSetClassHint(x11_display, x11_window, classHint); - XFree(classHint); + XSetClassHint(x11_display, x11_window, classHint); + XFree(classHint); + } } } @@ -4482,6 +4486,8 @@ OS_X11::OS_X11() { AudioDriverManager::add_driver(&driver_alsa); #endif + x11_window = 0; + context = CONTEXT_ENGINE; xi.opcode = 0; xi.last_relative_time = 0; layered_window = false; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 2b5a8e7ea96e..71691c1e520a 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -105,6 +105,7 @@ class OS_X11 : public OS_Unix { Window xdnd_source_window; MainLoop *main_loop; ::Display *x11_display; + int context; char *xmbstring; int xmblen; unsigned long last_timestamp;