summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/detect.py7
-rw-r--r--platform/android/export/export_plugin.cpp9
-rw-r--r--platform/android/export/gradle_export_util.cpp4
-rw-r--r--platform/android/file_access_android.cpp2
-rw-r--r--platform/android/file_access_android.h2
-rw-r--r--platform/android/file_access_filesystem_jandroid.cpp2
-rw-r--r--platform/android/file_access_filesystem_jandroid.h2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java8
-rw-r--r--platform/ios/detect.py9
-rw-r--r--platform/ios/display_layer.mm10
-rw-r--r--platform/ios/display_server_ios.mm4
-rw-r--r--platform/ios/export/export_plugin.cpp1
-rw-r--r--platform/ios/godot_view.mm2
-rw-r--r--platform/linuxbsd/detect.py4
-rw-r--r--platform/macos/SCsub1
-rw-r--r--platform/macos/detect.py9
-rw-r--r--platform/macos/display_server_macos.h4
-rw-r--r--platform/macos/display_server_macos.mm82
-rw-r--r--platform/macos/godot_button_view.h52
-rw-r--r--platform/macos/godot_button_view.mm123
-rw-r--r--platform/macos/godot_window.h2
-rw-r--r--platform/macos/godot_window.mm13
-rw-r--r--platform/macos/godot_window_delegate.h2
-rw-r--r--platform/macos/godot_window_delegate.mm66
-rw-r--r--platform/web/detect.py4
-rw-r--r--platform/web/export/export_plugin.cpp8
-rw-r--r--platform/windows/detect.py8
-rw-r--r--platform/windows/display_server_windows.cpp28
28 files changed, 402 insertions, 66 deletions
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 1d9bcdd932..a31bba745f 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -47,9 +47,6 @@ def get_flags():
return [
("arch", "arm64"), # Default for convenience.
("tools", False),
- # Benefits of LTO for Android (size, performance) haven't been clearly established yet.
- # So for now we override the default value which may be set when using `production=yes`.
- ("lto", "none"),
]
@@ -136,6 +133,10 @@ def configure(env):
env.Append(CPPFLAGS=["-UNDEBUG"])
# LTO
+
+ if env["lto"] == "auto": # LTO benefits for Android (size, performance) haven't been clearly established yet.
+ env["lto"] = "none"
+
if env["lto"] != "none":
if env["lto"] == "thin":
env.Append(CCFLAGS=["-flto=thin"])
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index e5656bd00b..366bd1c48c 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -1669,14 +1669,7 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp
}
void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
- String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- if (driver == "opengl3") {
- r_features->push_back("etc");
- }
- // FIXME: Review what texture formats are used for Vulkan.
- if (driver == "vulkan") {
- r_features->push_back("etc2");
- }
+ r_features->push_back("etc2");
Vector<String> abis = get_enabled_abis(p_preset);
for (int i = 0; i < abis.size(); ++i) {
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 8d370a31a4..2f53942f76 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -189,9 +189,7 @@ String bool_to_string(bool v) {
}
String _get_gles_tag() {
- bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES3" &&
- !ProjectSettings::get_singleton()->get("rendering/driver/fallback_to_gles2");
- return min_gles3 ? " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n" : "";
+ return " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n";
}
String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) {
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index ace7636e6c..d6cd62e9f5 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -42,7 +42,7 @@ String FileAccessAndroid::get_path_absolute() const {
return absolute_path;
}
-Error FileAccessAndroid::_open(const String &p_path, int p_mode_flags) {
+Error FileAccessAndroid::open_internal(const String &p_path, int p_mode_flags) {
_close();
path_src = p_path;
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index 8d7ade8ead..55f8fbe0f4 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -49,7 +49,7 @@ class FileAccessAndroid : public FileAccess {
public:
static AAssetManager *asset_manager;
- virtual Error _open(const String &p_path, int p_mode_flags) override; // open a file
+ virtual Error open_internal(const String &p_path, int p_mode_flags) override; // open a file
virtual bool is_open() const override; // true when file is open
/// returns the path for the current open file
diff --git a/platform/android/file_access_filesystem_jandroid.cpp b/platform/android/file_access_filesystem_jandroid.cpp
index 56561cb616..c2ee3389ae 100644
--- a/platform/android/file_access_filesystem_jandroid.cpp
+++ b/platform/android/file_access_filesystem_jandroid.cpp
@@ -61,7 +61,7 @@ String FileAccessFilesystemJAndroid::get_path_absolute() const {
return absolute_path;
}
-Error FileAccessFilesystemJAndroid::_open(const String &p_path, int p_mode_flags) {
+Error FileAccessFilesystemJAndroid::open_internal(const String &p_path, int p_mode_flags) {
if (is_open()) {
_close();
}
diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h
index 76d7db6e3a..815ab36516 100644
--- a/platform/android/file_access_filesystem_jandroid.h
+++ b/platform/android/file_access_filesystem_jandroid.h
@@ -60,7 +60,7 @@ class FileAccessFilesystemJAndroid : public FileAccess {
void _set_eof(bool eof);
public:
- virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
+ virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file
virtual bool is_open() const override; ///< true when file is open
/// returns the path for the current open file
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index a75c69484c..92e5e59496 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -274,11 +274,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
return false;
}
- final String videoDriver = GodotLib.getGlobal("rendering/driver/driver_name");
- if (videoDriver.equals("vulkan")) {
- mRenderView = new GodotVulkanRenderView(activity, this);
- } else {
+ final String renderer = GodotLib.getGlobal("rendering/renderer/rendering_method");
+ if (renderer.equals("gl_compatibility")) {
mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl);
+ } else {
+ mRenderView = new GodotVulkanRenderView(activity, this);
}
View view = mRenderView.getView();
diff --git a/platform/ios/detect.py b/platform/ios/detect.py
index ed7e714c4e..d5e6ee4b46 100644
--- a/platform/ios/detect.py
+++ b/platform/ios/detect.py
@@ -39,9 +39,6 @@ def get_flags():
("arch", "arm64"), # Default for convenience.
("tools", False),
("use_volk", False),
- # Disable by default even if production is set, as it makes linking in Xcode
- # on exports very slow and that's not what most users expect.
- ("lto", "none"),
]
@@ -73,7 +70,11 @@ def configure(env):
env.Append(CCFLAGS=["-gdwarf-2", "-O0"])
env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1)])
- # LTO
+ ## LTO
+
+ if env["lto"] == "auto": # Disable by default as it makes linking in Xcode very slow.
+ env["lto"] = "none"
+
if env["lto"] != "none":
if env["lto"] == "thin":
env.Append(CCFLAGS=["-flto=thin"])
diff --git a/platform/ios/display_layer.mm b/platform/ios/display_layer.mm
index 7c83494768..74c760ae9a 100644
--- a/platform/ios/display_layer.mm
+++ b/platform/ios/display_layer.mm
@@ -89,12 +89,12 @@
// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
- // Create GL ES 2 context
- if (GLOBAL_GET("rendering/driver/driver_name") == "opengl3") {
- context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
- NSLog(@"Setting up an OpenGL ES 2.0 context.");
+ // Create GL ES 3 context
+ if (GLOBAL_GET("rendering/renderer/rendering_method") == "gl_compatibility") {
+ context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
+ NSLog(@"Setting up an OpenGL ES 3.0 context.");
if (!context) {
- NSLog(@"Failed to create OpenGL ES 2.0 context!");
+ NSLog(@"Failed to create OpenGL ES 3.0 context!");
return;
}
}
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index 74d6bc2e97..d3a0f38463 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -62,7 +62,7 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
// Note that we should be checking "opengl3" as the driver, might never enable this seeing OpenGL is deprecated on iOS
// We are hardcoding the rendering_driver to "vulkan" down below
- if (rendering_driver == "opengl_es") {
+ if (rendering_driver == "opengl3") {
bool gl_initialization_error = false;
// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
@@ -163,7 +163,7 @@ Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
drivers.push_back("vulkan");
#endif
#if defined(GLES3_ENABLED)
- drivers.push_back("opengl_es");
+ drivers.push_back("opengl3");
#endif
return drivers;
diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index 7aacb2de85..74a57dc614 100644
--- a/platform/ios/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -34,7 +34,6 @@
#include "editor/editor_node.h"
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
- String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
// Vulkan and OpenGL ES 3.0 both mandate ETC2 support.
r_features->push_back("etc2");
diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm
index 9ed219508c..ff90c05b1d 100644
--- a/platform/ios/godot_view.mm
+++ b/platform/ios/godot_view.mm
@@ -74,7 +74,7 @@ static const float earth_gravity = 9.80665;
if ([driverName isEqualToString:@"vulkan"]) {
layer = [GodotMetalLayer layer];
- } else if ([driverName isEqualToString:@"opengl_es"]) {
+ } else if ([driverName isEqualToString:@"opengl3"]) {
if (@available(iOS 13, *)) {
NSLog(@"OpenGL ES is deprecated on iOS 13");
}
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 36644d5f29..12d2432eea 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -171,6 +171,10 @@ def configure(env):
env.Append(LINKFLAGS=["-fsanitize=memory"])
# LTO
+
+ if env["lto"] == "auto": # Full LTO for production.
+ env["lto"] = "full"
+
if env["lto"] != "none":
if env["lto"] == "thin":
if not env["use_llvm"]:
diff --git a/platform/macos/SCsub b/platform/macos/SCsub
index bbd461fba9..7ffb80f70b 100644
--- a/platform/macos/SCsub
+++ b/platform/macos/SCsub
@@ -12,6 +12,7 @@ files = [
"crash_handler_macos.mm",
"macos_terminal_logger.mm",
"display_server_macos.mm",
+ "godot_button_view.mm",
"godot_content_view.mm",
"godot_window_delegate.mm",
"godot_window.mm",
diff --git a/platform/macos/detect.py b/platform/macos/detect.py
index bcf4776609..834ac935d8 100644
--- a/platform/macos/detect.py
+++ b/platform/macos/detect.py
@@ -40,9 +40,6 @@ def get_flags():
return [
("arch", detect_arch()),
("use_volk", False),
- # Benefits of LTO for macOS (size, performance) haven't been clearly established yet.
- # So for now we override the default value which may be set when using `production=yes`.
- ("lto", "none"),
]
@@ -170,6 +167,10 @@ def configure(env):
env["AS"] = basecmd + "as"
# LTO
+
+ if env["lto"] == "auto": # LTO benefits for macOS (size, performance) haven't been clearly established yet.
+ env["lto"] = "none"
+
if env["lto"] != "none":
if env["lto"] == "thin":
env.Append(CCFLAGS=["-flto=thin"])
@@ -178,6 +179,8 @@ def configure(env):
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
+ # Sanitizers
+
if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]:
env.extra_suffix += ".san"
env.Append(CCFLAGS=["-DSANITIZERS_ENABLED"])
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index da377c9171..a27e0d5efa 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -76,6 +76,7 @@ public:
id window_delegate;
id window_object;
id window_view;
+ id window_button_view;
Vector<Vector2> mpath;
@@ -84,6 +85,7 @@ public:
Size2i min_size;
Size2i max_size;
Size2i size;
+ Vector2i wb_offset = Vector2i(14, 14);
NSRect last_frame_rect;
@@ -228,6 +230,7 @@ public:
void window_update(WindowID p_window);
void window_destroy(WindowID p_window);
void window_resize(WindowID p_window, int p_width, int p_height);
+ void window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled);
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
@@ -391,6 +394,7 @@ public:
virtual bool window_maximize_on_title_dbl_click() const override;
virtual bool window_minimize_on_title_dbl_click() const override;
+ virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) override;
virtual Vector2i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual Point2i ime_get_selection() const override;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 05f89c70aa..34723c7d4b 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -30,6 +30,7 @@
#include "display_server_macos.h"
+#include "godot_button_view.h"
#include "godot_content_view.h"
#include "godot_menu_delegate.h"
#include "godot_menu_item.h"
@@ -2212,7 +2213,9 @@ void DisplayServerMacOS::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];
popup_open(p_id);
- if (wd.no_focus || wd.is_popup) {
+ if ([wd.window_object isMiniaturized]) {
+ return;
+ } else if (wd.no_focus || wd.is_popup) {
[wd.window_object orderFront:nil];
} else {
[wd.window_object makeKeyAndOrderFront:nil];
@@ -2369,6 +2372,10 @@ void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
+ if ([wd.window_object isZoomed]) {
+ return;
+ }
+
Point2i position = p_position;
// OS X native y-coordinate relative to _get_screens_origin() is negative,
// Godot passes a positive value.
@@ -2493,6 +2500,10 @@ void DisplayServerMacOS::window_set_size(const Size2i p_size, WindowID p_window)
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
+ if ([wd.window_object isZoomed]) {
+ return;
+ }
+
Size2i size = p_size / screen_get_max_scale();
NSPoint top_left;
@@ -2639,27 +2650,59 @@ bool DisplayServerMacOS::window_minimize_on_title_dbl_click() const {
return false;
}
+void DisplayServerMacOS::window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ WindowData &wd = windows[p_window];
+ wd.wb_offset = p_offset;
+}
+
Vector2i DisplayServerMacOS::window_get_safe_title_margins(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Vector2i());
const WindowData &wd = windows[p_window];
- float max_x = 0.f;
- NSButton *cb = [wd.window_object standardWindowButton:NSWindowCloseButton];
- if (cb) {
- max_x = MAX(max_x, [cb frame].origin.x + [cb frame].size.width);
+ if (!wd.window_button_view) {
+ return Vector2i();
}
- NSButton *mb = [wd.window_object standardWindowButton:NSWindowMiniaturizeButton];
- if (mb) {
- max_x = MAX(max_x, [mb frame].origin.x + [mb frame].size.width);
+
+ float max_x = wd.wb_offset.x + [wd.window_button_view frame].size.width;
+
+ if ([wd.window_object windowTitlebarLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft) {
+ return Vector2i(0, max_x * screen_get_max_scale());
+ } else {
+ return Vector2i(max_x * screen_get_max_scale(), 0);
}
- NSButton *zb = [wd.window_object standardWindowButton:NSWindowZoomButton];
- if (zb) {
- max_x = MAX(max_x, [zb frame].origin.x + [zb frame].size.width);
+}
+
+void DisplayServerMacOS::window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled) {
+ if (p_wd.window_button_view) {
+ [p_wd.window_button_view removeFromSuperview];
+ p_wd.window_button_view = nil;
}
+ if (p_enabled) {
+ float cb_frame = NSMinX([[p_wd.window_object standardWindowButton:NSWindowCloseButton] frame]);
+ float mb_frame = NSMinX([[p_wd.window_object standardWindowButton:NSWindowMiniaturizeButton] frame]);
+ bool is_rtl = ([p_wd.window_object windowTitlebarLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft);
+
+ float window_buttons_spacing = (is_rtl) ? (cb_frame - mb_frame) : (mb_frame - cb_frame);
+
+ [p_wd.window_object setTitleVisibility:NSWindowTitleHidden];
+ [[p_wd.window_object standardWindowButton:NSWindowZoomButton] setHidden:YES];
+ [[p_wd.window_object standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
+ [[p_wd.window_object standardWindowButton:NSWindowCloseButton] setHidden:YES];
- return Vector2i(max_x * screen_get_max_scale(), 0);
+ p_wd.window_button_view = [[GodotButtonView alloc] initWithFrame:NSZeroRect];
+ [p_wd.window_button_view initButtons:window_buttons_spacing offset:NSMakePoint(p_wd.wb_offset.x, p_wd.wb_offset.y) rtl:is_rtl];
+ [p_wd.window_view addSubview:p_wd.window_button_view];
+ } else {
+ [p_wd.window_object setTitleVisibility:NSWindowTitleVisible];
+ [[p_wd.window_object standardWindowButton:NSWindowZoomButton] setHidden:NO];
+ [[p_wd.window_object standardWindowButton:NSWindowMiniaturizeButton] setHidden:NO];
+ [[p_wd.window_object standardWindowButton:NSWindowCloseButton] setHidden:NO];
+ }
}
void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
@@ -2684,14 +2727,21 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win
NSRect rect = [wd.window_object frame];
if (p_enabled) {
[wd.window_object setTitlebarAppearsTransparent:YES];
- [wd.window_object setTitleVisibility:NSWindowTitleHidden];
[wd.window_object setStyleMask:[wd.window_object styleMask] | NSWindowStyleMaskFullSizeContentView];
+
+ if (!wd.fullscreen) {
+ window_set_custom_window_buttons(wd, true);
+ }
} else {
[wd.window_object setTitlebarAppearsTransparent:NO];
- [wd.window_object setTitleVisibility:NSWindowTitleVisible];
[wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskFullSizeContentView];
+
+ if (!wd.fullscreen) {
+ window_set_custom_window_buttons(wd, false);
+ }
}
[wd.window_object setFrame:rect display:YES];
+ send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE);
} break;
case WINDOW_FLAG_BORDERLESS: {
// OrderOut prevents a lose focus bug with the window.
@@ -2711,7 +2761,9 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win
}
_update_window_style(wd);
if ([wd.window_object isVisible]) {
- if (wd.no_focus || wd.is_popup) {
+ if ([wd.window_object isMiniaturized]) {
+ return;
+ } else if (wd.no_focus || wd.is_popup) {
[wd.window_object orderFront:nil];
} else {
[wd.window_object makeKeyAndOrderFront:nil];
diff --git a/platform/macos/godot_button_view.h b/platform/macos/godot_button_view.h
new file mode 100644
index 0000000000..e7627a9e9b
--- /dev/null
+++ b/platform/macos/godot_button_view.h
@@ -0,0 +1,52 @@
+/*************************************************************************/
+/* godot_button_view.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_BUTTON_VIEW_H
+#define GODOT_BUTTON_VIEW_H
+
+#include "servers/display_server.h"
+
+#import <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
+
+@interface GodotButtonView : NSView {
+ NSTrackingArea *tracking_area;
+ NSPoint offset;
+ CGFloat spacing;
+ bool mouse_in_group;
+ bool rtl;
+}
+
+- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset rtl:(bool)is_rtl;
+- (void)displayButtons;
+
+@end
+
+#endif // GODOT_BUTTON_VIEW_H
diff --git a/platform/macos/godot_button_view.mm b/platform/macos/godot_button_view.mm
new file mode 100644
index 0000000000..9106f0b0db
--- /dev/null
+++ b/platform/macos/godot_button_view.mm
@@ -0,0 +1,123 @@
+/*************************************************************************/
+/* godot_button_view.mm */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "godot_button_view.h"
+
+@implementation GodotButtonView
+
+- (id)initWithFrame:(NSRect)frame {
+ self = [super initWithFrame:frame];
+
+ tracking_area = nil;
+ offset = NSMakePoint(8, 8);
+ spacing = 20;
+ mouse_in_group = false;
+ rtl = false;
+
+ return self;
+}
+
+- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset rtl:(bool)is_rtl {
+ spacing = button_spacing;
+ rtl = is_rtl;
+
+ NSButton *close_button = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:NSWindowStyleMaskTitled];
+ [close_button setFrameOrigin:NSMakePoint(rtl ? spacing * 2 : 0, 0)];
+ [self addSubview:close_button];
+
+ NSButton *miniaturize_button = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:NSWindowStyleMaskTitled];
+ [miniaturize_button setFrameOrigin:NSMakePoint(spacing, 0)];
+ [self addSubview:miniaturize_button];
+
+ NSButton *zoom_button = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:NSWindowStyleMaskTitled];
+ [zoom_button setFrameOrigin:NSMakePoint(rtl ? 0 : spacing * 2, 0)];
+ [self addSubview:zoom_button];
+
+ offset.y = button_offset.y - zoom_button.frame.size.height / 2;
+ offset.x = button_offset.x - zoom_button.frame.size.width / 2;
+
+ if (rtl) {
+ [self setFrameSize:NSMakeSize(close_button.frame.origin.x + close_button.frame.size.width, close_button.frame.size.height)];
+ } else {
+ [self setFrameSize:NSMakeSize(zoom_button.frame.origin.x + zoom_button.frame.size.width, zoom_button.frame.size.height)];
+ }
+ [self displayButtons];
+}
+
+- (void)viewDidMoveToWindow {
+ if (!self.window) {
+ return;
+ }
+
+ if (rtl) {
+ [self setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
+ [self setFrameOrigin:NSMakePoint(self.window.frame.size.width - self.frame.size.width - offset.x, self.window.frame.size.height - self.frame.size.height - offset.y)];
+ } else {
+ [self setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
+ [self setFrameOrigin:NSMakePoint(offset.x, self.window.frame.size.height - self.frame.size.height - offset.y)];
+ }
+}
+
+- (BOOL)_mouseInGroup:(NSButton *)button {
+ return mouse_in_group;
+}
+
+- (void)updateTrackingAreas {
+ if (tracking_area != nil) {
+ [self removeTrackingArea:tracking_area];
+ }
+
+ NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect;
+ tracking_area = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:options owner:self userInfo:nil];
+
+ [self addTrackingArea:tracking_area];
+}
+
+- (void)mouseEntered:(NSEvent *)event {
+ [super mouseEntered:event];
+
+ mouse_in_group = true;
+ [self displayButtons];
+}
+
+- (void)mouseExited:(NSEvent *)event {
+ [super mouseExited:event];
+
+ mouse_in_group = false;
+ [self displayButtons];
+}
+
+- (void)displayButtons {
+ for (NSView *subview in self.subviews) {
+ [subview setNeedsDisplay:YES];
+ }
+}
+
+@end
diff --git a/platform/macos/godot_window.h b/platform/macos/godot_window.h
index 9fc5599e86..d3653fda82 100644
--- a/platform/macos/godot_window.h
+++ b/platform/macos/godot_window.h
@@ -38,9 +38,11 @@
@interface GodotWindow : NSWindow {
DisplayServer::WindowID window_id;
+ NSTimeInterval anim_duration;
}
- (void)setWindowID:(DisplayServer::WindowID)wid;
+- (void)setAnimDuration:(NSTimeInterval)duration;
@end
diff --git a/platform/macos/godot_window.mm b/platform/macos/godot_window.mm
index e205e7546d..bc51da4f72 100644
--- a/platform/macos/godot_window.mm
+++ b/platform/macos/godot_window.mm
@@ -37,9 +37,22 @@
- (id)init {
self = [super init];
window_id = DisplayServer::INVALID_WINDOW_ID;
+ anim_duration = -1.0f;
return self;
}
+- (void)setAnimDuration:(NSTimeInterval)duration {
+ anim_duration = duration;
+}
+
+- (NSTimeInterval)animationResizeTime:(NSRect)newFrame {
+ if (anim_duration > 0) {
+ return anim_duration;
+ } else {
+ return [super animationResizeTime:newFrame];
+ }
+}
+
- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
}
diff --git a/platform/macos/godot_window_delegate.h b/platform/macos/godot_window_delegate.h
index 98c226aa2f..01cc13a016 100644
--- a/platform/macos/godot_window_delegate.h
+++ b/platform/macos/godot_window_delegate.h
@@ -38,6 +38,8 @@
@interface GodotWindowDelegate : NSObject <NSWindowDelegate> {
DisplayServer::WindowID window_id;
+ NSRect old_frame;
+ NSWindowStyleMask old_style_mask;
}
- (void)setWindowID:(DisplayServer::WindowID)wid;
diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm
index e1034c9993..279fd2a359 100644
--- a/platform/macos/godot_window_delegate.mm
+++ b/platform/macos/godot_window_delegate.mm
@@ -31,6 +31,8 @@
#include "godot_window_delegate.h"
#include "display_server_macos.h"
+#include "godot_button_view.h"
+#include "godot_window.h"
@implementation GodotWindowDelegate
@@ -68,6 +70,26 @@
ds->window_destroy(window_id);
}
+- (NSArray<NSWindow *> *)customWindowsToEnterFullScreenForWindow:(NSWindow *)window {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
+ if (!ds || !ds->has_window(window_id)) {
+ return nullptr;
+ }
+
+ old_frame = [window frame];
+ old_style_mask = [window styleMask];
+
+ NSMutableArray<NSWindow *> *windows = [[NSMutableArray alloc] init];
+ [windows addObject:window];
+
+ return windows;
+}
+
+- (void)window:(NSWindow *)window startCustomAnimationToEnterFullScreenWithDuration:(NSTimeInterval)duration {
+ [(GodotWindow *)window setAnimDuration:duration];
+ [window setFrame:[[window screen] frame] display:YES animate:YES];
+}
+
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
@@ -76,12 +98,46 @@
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
wd.fullscreen = true;
+
// Reset window size limits.
[wd.window_object setContentMinSize:NSMakeSize(0, 0)];
[wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
+ [(GodotWindow *)wd.window_object setAnimDuration:-1.0f];
+
+ // Reset custom window buttons.
+ if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) {
+ ds->window_set_custom_window_buttons(wd, false);
+ }
// Force window resize event.
[self windowDidResize:notification];
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE);
+}
+
+- (NSArray<NSWindow *> *)customWindowsToExitFullScreenForWindow:(NSWindow *)window {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
+ if (!ds || !ds->has_window(window_id)) {
+ return nullptr;
+ }
+
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
+
+ // Restore custom window buttons.
+ if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) {
+ ds->window_set_custom_window_buttons(wd, true);
+ }
+
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE);
+
+ NSMutableArray<NSWindow *> *windows = [[NSMutableArray alloc] init];
+ [windows addObject:wd.window_object];
+ return windows;
+}
+
+- (void)window:(NSWindow *)window startCustomAnimationToExitFullScreenWithDuration:(NSTimeInterval)duration {
+ [(GodotWindow *)window setAnimDuration:duration];
+ [window setStyleMask:old_style_mask];
+ [window setFrame:old_frame display:YES animate:YES];
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
@@ -93,6 +149,8 @@
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
wd.fullscreen = false;
+ [(GodotWindow *)wd.window_object setAnimDuration:-1.0f];
+
// Set window size limits.
const float scale = ds->screen_get_max_scale();
if (wd.min_size != Size2i()) {
@@ -219,6 +277,10 @@
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
+ if (wd.window_button_view) {
+ [(GodotButtonView *)wd.window_button_view displayButtons];
+ }
+
if (ds->mouse_get_mode() == DisplayServer::MOUSE_MODE_CAPTURED) {
const NSRect content_rect = [wd.window_view frame];
NSRect point_in_window_rect = NSMakeRect(content_rect.size.width / 2, content_rect.size.height / 2, 0, 0);
@@ -241,6 +303,10 @@
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
+ if (wd.window_button_view) {
+ [(GodotButtonView *)wd.window_button_view displayButtons];
+ }
+
ds->release_pressed_events();
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
diff --git a/platform/web/detect.py b/platform/web/detect.py
index 08f964db92..9cce73efc4 100644
--- a/platform/web/detect.py
+++ b/platform/web/detect.py
@@ -109,6 +109,10 @@ def configure(env):
env["ENV"] = os.environ
# LTO
+
+ if env["lto"] == "auto": # Full LTO for production.
+ env["lto"] = "full"
+
if env["lto"] != "none":
if env["lto"] == "thin":
env.Append(CCFLAGS=["-flto=thin"])
diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp
index 306453c1eb..1c327fe4b2 100644
--- a/platform/web/export/export_plugin.cpp
+++ b/platform/web/export/export_plugin.cpp
@@ -307,13 +307,7 @@ void EditorExportPlatformWeb::get_preset_features(const Ref<EditorExportPreset>
}
if (p_preset->get("vram_texture_compression/for_mobile")) {
- String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
- if (driver == "opengl3") {
- r_features->push_back("etc");
- } else if (driver == "vulkan") {
- // FIXME: Review if this is correct.
- r_features->push_back("etc2");
- }
+ r_features->push_back("etc2");
}
r_features->push_back("wasm32");
}
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index e6e1874fc0..52a959b34a 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -448,6 +448,9 @@ def configure_msvc(env, vcvars_msvc_config):
## LTO
+ if env["lto"] == "auto": # No LTO by default for MSVC, doesn't help.
+ env["lto"] = "none"
+
if env["lto"] != "none":
if env["lto"] == "thin":
print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.")
@@ -564,6 +567,11 @@ def configure_mingw(env):
if try_cmd("gcc-ranlib --version", env["mingw_prefix"], env["arch"]):
env["RANLIB"] = mingw_bin_prefix + "gcc-ranlib"
+ ## LTO
+
+ if env["lto"] == "auto": # Full LTO for production with MinGW.
+ env["lto"] = "full"
+
if env["lto"] != "none":
if env["lto"] == "thin":
if not env["use_llvm"]:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 4553f31480..46cb5473da 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -685,7 +685,13 @@ void DisplayServerWindows::show_window(WindowID p_id) {
_update_window_style(p_id);
}
- if (wd.no_focus || wd.is_popup) {
+ if (wd.maximized) {
+ ShowWindow(wd.hWnd, SW_SHOWMAXIMIZED);
+ SetForegroundWindow(wd.hWnd); // Slightly higher priority.
+ SetFocus(wd.hWnd); // Set keyboard focus.
+ } else if (wd.minimized) {
+ ShowWindow(wd.hWnd, SW_SHOWMINIMIZED);
+ } else if (wd.no_focus || wd.is_popup) {
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
ShowWindow(wd.hWnd, SW_SHOWNA);
} else {
@@ -926,7 +932,7 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- if (wd.fullscreen) {
+ if (wd.fullscreen || wd.maximized) {
return;
}
@@ -1059,6 +1065,10 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
+ if (wd.fullscreen || wd.maximized) {
+ return;
+ }
+
int w = p_size.width;
int h = p_size.height;
@@ -1076,10 +1086,6 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
}
#endif
- if (wd.fullscreen) {
- return;
- }
-
RECT rect;
GetWindowRect(wd.hWnd, &rect);
@@ -3599,6 +3605,16 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
wd.wtctx = 0;
}
+ if (p_mode == WINDOW_MODE_MAXIMIZED) {
+ wd.maximized = true;
+ wd.minimized = false;
+ }
+
+ if (p_mode == WINDOW_MODE_MINIMIZED) {
+ wd.maximized = false;
+ wd.minimized = true;
+ }
+
wd.last_pressure = 0;
wd.last_pressure_update = 0;
wd.last_tilt = Vector2();