From 3ec62c82a3a281a5add54c9f4ce4874b95efb7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Wed, 23 Sep 2020 13:43:51 +0200 Subject: [PATCH] Implement no-window mode for X11 and MacOS Bonus: Homogeinize and improve OS::alert() for no-window mode --- drivers/unix/os_unix.cpp | 2 +- main/main.cpp | 4 +- platform/osx/os_osx.mm | 81 ++++++++++++++++++++++++++++++--- platform/windows/os_windows.cpp | 10 ++-- platform/x11/context_gl_x11.cpp | 5 +- platform/x11/os_x11.cpp | 10 +++- 6 files changed, 96 insertions(+), 16 deletions(-) diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 7ec5a2e2aa5e..ba6b699aa5e4 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -156,7 +156,7 @@ void OS_Unix::finalize_core() { void OS_Unix::alert(const String &p_alert, const String &p_title) { - fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data()); + fprintf(stderr, "ALERT: %s: %s\n", p_title.utf8().get_data(), p_alert.utf8().get_data()); } String OS_Unix::get_stdin_string(bool p_block) { diff --git a/main/main.cpp b/main/main.cpp index a20da26a0709..a685dfca5c60 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -259,7 +259,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --resolution x Request window resolution.\n"); OS::get_singleton()->print(" --position , Request window position.\n"); OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n"); - OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n"); + OS::get_singleton()->print(" --no-window Run with invisible window. Useful together with --script.\n"); OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n"); OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n"); OS::get_singleton()->print(" --tablet-driver Tablet input driver ("); @@ -609,7 +609,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "--low-dpi") { // force low DPI (macOS only) force_lowdpi = true; - } else if (I->get() == "--no-window") { // disable window creation (Windows only) + } else if (I->get() == "--no-window") { // run with an invisible window OS::get_singleton()->set_no_window_mode(true); } else if (I->get() == "--tablet-driver") { diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 7efa7d93847f..ec587062d342 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1606,8 +1606,10 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay //[window_object setTitle:[NSString stringWithUTF8String:"GodotEnginies"]]; [window_object setContentView:window_view]; [window_object setDelegate:window_delegate]; - [window_object setAcceptsMouseMovedEvents:YES]; - [(NSWindow *)window_object center]; + if (!is_no_window_mode_enabled()) { + [window_object setAcceptsMouseMovedEvents:YES]; + [((NSWindow *)window_object) center]; + } [window_object setRestorable:NO]; @@ -1689,11 +1691,16 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay set_use_vsync(p_desired.use_vsync); - [NSApp activateIgnoringOtherApps:YES]; + if (!is_no_window_mode_enabled()) { + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp activateIgnoringOtherApps:YES]; + } _update_window(); - [window_object makeKeyAndOrderFront:nil]; + if (!is_no_window_mode_enabled()) { + [window_object makeKeyAndOrderFront:nil]; + } on_top = p_desired.always_on_top; if (p_desired.always_on_top) { @@ -1773,6 +1780,10 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay update_real_mouse_position(); + if (is_no_window_mode_enabled()) { + [NSApp hide:nil]; + } + return OK; } @@ -1880,6 +1891,11 @@ virtual void log_error(const char *p_function, const char *p_file, int p_line, c #endif void OS_OSX::alert(const String &p_alert, const String &p_title) { + if (is_no_window_mode_enabled()) { + print_line("ALERT: " + p_title + ": " + p_alert); + return; + } + // Set OS X-compliant variables NSAlert *window = [[NSAlert alloc] init]; NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; @@ -2447,6 +2463,10 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::set_current_screen(int p_screen) { + if (is_no_window_mode_enabled()) { + return; + } + Vector2 wpos = get_window_position() - get_screen_position(get_current_screen()); set_window_position(wpos + get_screen_position(p_screen)); }; @@ -2593,6 +2613,9 @@ static int get_screen_index(NSScreen *screen) { } void OS_OSX::set_native_window_position(const Point2 &p_position) { + if (is_no_window_mode_enabled()) { + return; + } NSPoint pos; float displayScale = get_screen_max_scale(); @@ -2606,6 +2629,10 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::set_window_position(const Point2 &p_position) { + if (is_no_window_mode_enabled()) { + return; + } + Point2 position = p_position; // OS X native y-coordinate relative to get_screens_origin() is negative, // Godot passes a positive value @@ -2636,6 +2663,10 @@ static int get_screen_index(NSScreen *screen) { void OS_OSX::set_min_window_size(const Size2 p_size) { + if (is_no_window_mode_enabled()) { + return; + } + if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) { ERR_PRINT("Minimum window size can't be larger than maximum window size!"); return; @@ -2652,6 +2683,10 @@ static int get_screen_index(NSScreen *screen) { void OS_OSX::set_max_window_size(const Size2 p_size) { + if (is_no_window_mode_enabled()) { + return; + } + if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) { ERR_PRINT("Maximum window size can't be smaller than minimum window size!"); return; @@ -2668,6 +2703,10 @@ static int get_screen_index(NSScreen *screen) { void OS_OSX::set_window_size(const Size2 p_size) { + if (is_no_window_mode_enabled()) { + return; + } + Size2 size = p_size / get_screen_max_scale(); NSPoint top_left; @@ -2687,6 +2726,9 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::set_window_fullscreen(bool p_enabled) { + if (is_no_window_mode_enabled()) { + return; + } if (zoomed != p_enabled) { if (layered_window) @@ -2717,6 +2759,9 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::set_window_resizable(bool p_enabled) { + if (is_no_window_mode_enabled()) { + return; + } if (p_enabled) [window_object setStyleMask:[window_object styleMask] | NSWindowStyleMaskResizable]; @@ -2732,6 +2777,9 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::set_window_minimized(bool p_enabled) { + if (is_no_window_mode_enabled()) { + return; + } if (p_enabled) [window_object performMiniaturize:nil]; @@ -2748,6 +2796,9 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::set_window_maximized(bool p_enabled) { + if (is_no_window_mode_enabled()) { + return; + } if (p_enabled) { restore_rect = Rect2(get_window_position(), get_window_size()); @@ -2766,12 +2817,19 @@ static int get_screen_index(NSScreen *screen) { }; void OS_OSX::move_window_to_foreground() { + if (is_no_window_mode_enabled()) { + return; + } [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; [window_object makeKeyAndOrderFront:nil]; } void OS_OSX::set_window_always_on_top(bool p_enabled) { + if (is_no_window_mode_enabled()) { + return; + } + on_top = p_enabled; if (is_window_always_on_top() == p_enabled) @@ -2792,6 +2850,9 @@ static int get_screen_index(NSScreen *screen) { } void OS_OSX::request_attention() { + if (is_no_window_mode_enabled()) { + return; + } [NSApp requestUserAttention:NSCriticalRequest]; } @@ -2823,12 +2884,18 @@ static int get_screen_index(NSScreen *screen) { } [context update]; NSRect frame = [window_object frame]; - [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; - [window_object setFrame:frame display:YES]; + + if (!is_no_window_mode_enabled()) { + [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; + [window_object setFrame:frame display:YES]; + } } } void OS_OSX::set_borderless_window(bool p_borderless) { + if (is_no_window_mode_enabled()) { + return; + } // OrderOut prevents a lose focus bug with the window [window_object orderOut:nil]; @@ -3318,7 +3385,7 @@ void _update_keyboard_layouts() { [GodotApplication sharedApplication]; // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp setActivationPolicy:(NSApplicationActivationPolicyAccessory)]; // Menu bar setup must go between sharedApplication above and // finishLaunching below, in order to properly emulate the behavior diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 02ac70146510..d048f24c3f3d 100755 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1855,10 +1855,12 @@ void OS_Windows::finalize_core() { void OS_Windows::alert(const String &p_alert, const String &p_title) { - if (!is_no_window_mode_enabled()) - MessageBoxW(NULL, p_alert.c_str(), p_title.c_str(), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); - else - print_line("ALERT: " + p_alert); + if (is_no_window_mode_enabled()) { + print_line("ALERT: " + p_title + ": " + p_alert); + return; + } + + MessageBoxW(NULL, p_alert.c_str(), p_title.c_str(), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); } void OS_Windows::set_mouse_mode(MouseMode p_mode) { diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 1b3e2547fb0e..7581a42bc64d 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -197,7 +197,10 @@ Error ContextGL_X11::initialize() { ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED); set_class_hint(x11_display, x11_window); - XMapWindow(x11_display, x11_window); + + if (!OS::get_singleton()->is_no_window_mode_enabled()) { + XMapWindow(x11_display, x11_window); + } XSync(x11_display, False); XSetErrorHandler(oldHandler); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index b434f17cd3ff..fa80f93c674d 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -847,7 +847,9 @@ void OS_X11::finalize() { if (xrandr_handle) dlclose(xrandr_handle); - XUnmapWindow(x11_display, x11_window); + if (!OS::get_singleton()->is_no_window_mode_enabled()) { + XUnmapWindow(x11_display, x11_window); + } XDestroyWindow(x11_display, x11_window); #if defined(OPENGL_ENABLED) @@ -3226,6 +3228,12 @@ void OS_X11::swap_buffers() { } void OS_X11::alert(const String &p_alert, const String &p_title) { + + if (is_no_window_mode_enabled()) { + print_line("ALERT: " + p_title + ": " + p_alert); + return; + } + const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" }; String path = get_environment("PATH");