diff options
22 files changed, 158 insertions, 117 deletions
diff --git a/SConstruct b/SConstruct index 46942ca3b4..5ad4b614ca 100644 --- a/SConstruct +++ b/SConstruct @@ -167,7 +167,7 @@ opts.Add("p", "Platform (alias for 'platform')", "") opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True)) opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release"))) opts.Add(EnumVariable("arch", "CPU architecture", "auto", ["auto"] + architectures, architecture_aliases)) -opts.Add(EnumVariable("float", "Floating-point precision", "default", ("default", "32", "64"))) +opts.Add(EnumVariable("float", "Floating-point precision", "32", ("32", "64"))) opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size", "none"))) opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) opts.Add(BoolVariable("use_lto", "Use link-time optimization", False)) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 47837cd9e1..1145798240 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -557,6 +557,9 @@ <member name="display/window/ios/hide_home_indicator" type="bool" setter="" getter="" default="true"> If [code]true[/code], the home indicator is hidden automatically. This only affects iOS devices without a physical home button. </member> + <member name="display/window/per_pixel_transparency/allowed" type="bool" setter="" getter="" default="false"> + If [code]true[/code], allows per-pixel transparency for the window background. This affects performance, so leave it on [code]false[/code] unless you need it. + </member> <member name="display/window/size/always_on_top" type="bool" setter="" getter="" default="false"> Forces the main window to be always on top. [b]Note:[/b] This setting is ignored on iOS, Android, and Web. diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 7537636356..cc96294ca5 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -108,19 +108,6 @@ void RasterizerGLES3::begin_frame(double frame_step) { } void RasterizerGLES3::end_frame(bool p_swap_buffers) { - // if (OS::get_singleton()->is_layered_allowed()) { - // if (!OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { - //clear alpha - // glColorMask(false, false, false, true); - // glClearColor(0.5, 0, 0, 1); - // glClear(GL_COLOR_BUFFER_BIT); - // glColorMask(true, true, true, true); - // } - // } - - // glClearColor(1, 0, 0, 1); - // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (p_swap_buffers) { DisplayServer::get_singleton()->swap_buffers(); } else { diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index b52179b4f3..99ef57abae 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1706,10 +1706,10 @@ Error VulkanContext::_update_swap_chain(Window *window) { // Find a supported composite alpha mode - one of these is guaranteed to be set. VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = { - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, }; for (uint32_t i = 0; i < ARRAY_SIZE(compositeAlphaFlags); i++) { if (surfCapabilities.supportedCompositeAlpha & compositeAlphaFlags[i]) { diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index e2265f2f83..cde4490cd3 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1255,16 +1255,14 @@ void SceneTreeDock::_notification(int p_what) { // create_root_dialog HBoxContainer *top_row = memnew(HBoxContainer); - top_row->set_name("NodeShortcutsTopRow"); top_row->set_h_size_flags(SIZE_EXPAND_FILL); Label *l = memnew(Label(TTR("Create Root Node:"))); l->set_theme_type_variation("HeaderSmall"); top_row->add_child(l); top_row->add_spacer(); - Button *node_shortcuts_toggle = memnew(Button); + node_shortcuts_toggle = memnew(Button); node_shortcuts_toggle->set_flat(true); - node_shortcuts_toggle->set_name("NodeShortcutsToggle"); node_shortcuts_toggle->set_icon(get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); node_shortcuts_toggle->set_toggle_mode(true); node_shortcuts_toggle->set_tooltip_text(TTR("Switch to Favorite Nodes")); @@ -1276,18 +1274,15 @@ void SceneTreeDock::_notification(int p_what) { create_root_dialog->add_child(top_row); ScrollContainer *scroll_container = memnew(ScrollContainer); - scroll_container->set_name("NodeShortcutsScrollContainer"); create_root_dialog->add_child(scroll_container); scroll_container->set_v_size_flags(SIZE_EXPAND_FILL); scroll_container->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); VBoxContainer *node_shortcuts = memnew(VBoxContainer); - node_shortcuts->set_name("NodeShortcuts"); scroll_container->add_child(node_shortcuts); node_shortcuts->set_h_size_flags(SIZE_EXPAND_FILL); - VBoxContainer *beginner_node_shortcuts = memnew(VBoxContainer); - beginner_node_shortcuts->set_name("BeginnerNodeShortcuts"); + beginner_node_shortcuts = memnew(VBoxContainer); node_shortcuts->add_child(beginner_node_shortcuts); button_2d = memnew(Button); @@ -1308,8 +1303,7 @@ void SceneTreeDock::_notification(int p_what) { button_ui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons"))); button_ui->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_USER_INTERFACE, false)); - VBoxContainer *favorite_node_shortcuts = memnew(VBoxContainer); - favorite_node_shortcuts->set_name("FavoriteNodeShortcuts"); + favorite_node_shortcuts = memnew(VBoxContainer); node_shortcuts->add_child(favorite_node_shortcuts); button_custom = memnew(Button); @@ -3227,25 +3221,11 @@ void SceneTreeDock::_local_tree_selected() { } void SceneTreeDock::_update_create_root_dialog() { - BaseButton *toggle = Object::cast_to<BaseButton>(create_root_dialog->get_node(String("NodeShortcutsTopRow/NodeShortcutsToggle"))); - Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcutsScrollContainer/NodeShortcuts")); - - if (!toggle || !node_shortcuts) { - return; - } - - Control *beginner_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("BeginnerNodeShortcuts"))); - Control *favorite_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("FavoriteNodeShortcuts"))); - - if (!beginner_nodes || !favorite_nodes) { - return; - } - - EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", toggle->is_pressed()); + EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", node_shortcuts_toggle->is_pressed()); EditorSettings::get_singleton()->save(); - if (toggle->is_pressed()) { - for (int i = 0; i < favorite_nodes->get_child_count(); i++) { - favorite_nodes->get_child(i)->queue_delete(); + if (node_shortcuts_toggle->is_pressed()) { + for (int i = 0; i < favorite_node_shortcuts->get_child_count(); i++) { + favorite_node_shortcuts->get_child(i)->queue_delete(); } Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorites.Node"), FileAccess::READ); @@ -3255,7 +3235,7 @@ void SceneTreeDock::_update_create_root_dialog() { if (!l.is_empty()) { Button *button = memnew(Button); - favorite_nodes->add_child(button); + favorite_node_shortcuts->add_child(button); button->set_text(l); button->set_clip_text(true); String name = l.get_slicec(' ', 0); @@ -3268,14 +3248,14 @@ void SceneTreeDock::_update_create_root_dialog() { } } - if (!favorite_nodes->is_visible_in_tree()) { - favorite_nodes->show(); - beginner_nodes->hide(); + if (!favorite_node_shortcuts->is_visible_in_tree()) { + favorite_node_shortcuts->show(); + beginner_node_shortcuts->hide(); } } else { - if (!beginner_nodes->is_visible_in_tree()) { - beginner_nodes->show(); - favorite_nodes->hide(); + if (!beginner_node_shortcuts->is_visible_in_tree()) { + beginner_node_shortcuts->show(); + favorite_node_shortcuts->hide(); } button_clipboard->set_visible(!node_clipboard.is_empty()); } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index e15865036b..dc228e1c93 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -119,6 +119,10 @@ class SceneTreeDock : public VBoxContainer { Button *button_detach_script = nullptr; MenuButton *button_tree_menu = nullptr; + Button *node_shortcuts_toggle = nullptr; + VBoxContainer *beginner_node_shortcuts = nullptr; + VBoxContainer *favorite_node_shortcuts = nullptr; + Button *button_2d = nullptr; Button *button_3d = nullptr; Button *button_ui = nullptr; diff --git a/main/main.cpp b/main/main.cpp index a0d2f594ac..650d1159e0 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1555,17 +1555,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF("internationalization/locale/include_text_server_data", false); OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true); - - // FIXME: Restore support. -#if 0 - //OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false); - video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false); -#endif + OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false); if (editor || project_manager) { // The editor and project manager always detect and use hiDPI if needed OS::get_singleton()->_allow_hidpi = true; - OS::get_singleton()->_allow_layered = false; } if (rtm == -1) { diff --git a/modules/mono/README.md b/modules/mono/README.md index ebbc6b0f80..366777cfc1 100644 --- a/modules/mono/README.md +++ b/modules/mono/README.md @@ -43,3 +43,13 @@ This option ensures the packages will be added to the specified local NuGet source and that conflicting versions of the package are removed from the NuGet cache. It's recommended to always use this option when building the C# solutions during development to avoid mistakes. + +# Double Precision Support (REAL_T_IS_DOUBLE) + +Follow the above instructions but build Godot with the float=64 argument to scons + +When building the NuGet packages, specify `--float=64` - for example: +```sh +./modules/mono/build_scripts/build_assemblies.py --godot-output-dir ./bin \ + --push-nupkgs-local ~/MyLocalNugetSource --float=64 +``` diff --git a/modules/mono/build_scripts/build_assemblies.py b/modules/mono/build_scripts/build_assemblies.py index fa3be684bd..6f66ce9efa 100755 --- a/modules/mono/build_scripts/build_assemblies.py +++ b/modules/mono/build_scripts/build_assemblies.py @@ -195,7 +195,7 @@ def run_msbuild(tools: ToolsLocation, sln: str, msbuild_args: [str] = None): return subprocess.call(args, env=msbuild_env) -def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local): +def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local, float_size): target_filenames = [ "GodotSharp.dll", "GodotSharp.pdb", @@ -216,6 +216,8 @@ def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local): args = ["/restore", "/t:Build", "/p:Configuration=" + build_config, "/p:NoWarn=1591"] if push_nupkgs_local: args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local] + if float_size == "64": + args += ["/p:GodotFloat64=true"] sln = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln") exit_code = run_msbuild( @@ -256,9 +258,9 @@ def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local): return 0 -def build_all(msbuild_tool, module_dir, output_dir, godot_platform, dev_debug, push_nupkgs_local): +def build_all(msbuild_tool, module_dir, output_dir, godot_platform, dev_debug, push_nupkgs_local, float_size): # Godot API - exit_code = build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local) + exit_code = build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local, float_size) if exit_code != 0: return exit_code @@ -269,6 +271,8 @@ def build_all(msbuild_tool, module_dir, output_dir, godot_platform, dev_debug, p ) if push_nupkgs_local: args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local] + if float_size == "64": + args += ["/p:GodotFloat64=true"] exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args) if exit_code != 0: return exit_code @@ -277,6 +281,8 @@ def build_all(msbuild_tool, module_dir, output_dir, godot_platform, dev_debug, p args = ["/restore", "/t:Build", "/p:Configuration=Release"] if push_nupkgs_local: args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local] + if float_size == "64": + args += ["/p:GodotFloat64=true"] sln = os.path.join(module_dir, "editor/Godot.NET.Sdk/Godot.NET.Sdk.sln") exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args) if exit_code != 0: @@ -300,6 +306,7 @@ def main(): parser.add_argument("--godot-platform", type=str, default="") parser.add_argument("--mono-prefix", type=str, default="") parser.add_argument("--push-nupkgs-local", type=str, default="") + parser.add_argument("--float", type=str, default="32", choices=["32", "64"], help="Floating-point precision") args = parser.parse_args() @@ -321,6 +328,7 @@ def main(): args.godot_platform, args.dev_debug, args.push_nupkgs_local, + args.float, ) sys.exit(exit_code) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 2e59987fe6..64792a795f 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1754,20 +1754,16 @@ void CSharpInstance::mono_object_disposed_baseref(GCHandleIntPtr p_gchandle_to_f } void CSharpInstance::connect_event_signals() { - CSharpScript *top = script.ptr(); - while (top != nullptr) { - for (CSharpScript::EventSignalInfo &signal : top->get_script_event_signals()) { - String signal_name = signal.name; - - // TODO: Use pooling for ManagedCallable instances. - EventSignalCallable *event_signal_callable = memnew(EventSignalCallable(owner, signal_name)); + // The script signals list includes the signals declared in base scripts. + for (CSharpScript::EventSignalInfo &signal : script->get_script_event_signals()) { + String signal_name = signal.name; - Callable callable(event_signal_callable); - connected_event_signals.push_back(callable); - owner->connect(signal_name, callable); - } + // TODO: Use pooling for ManagedCallable instances. + EventSignalCallable *event_signal_callable = memnew(EventSignalCallable(owner, signal_name)); - top = top->base_script.ptr(); + Callable callable(event_signal_callable); + connected_event_signals.push_back(callable); + owner->connect(signal_name, callable); } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props index 59ce1da17b..0459257106 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props @@ -62,7 +62,7 @@ </PropertyGroup> <PropertyGroup> - <GodotRealTIsDouble Condition=" '$(GodotRealTIsDouble)' == '' ">false</GodotRealTIsDouble> + <GodotFloat64 Condition=" '$(GodotFloat64)' == '' ">false</GodotFloat64> </PropertyGroup> <!-- Godot DefineConstants. --> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets index aad4ea4553..bff9760b32 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets @@ -10,9 +10,9 @@ <!-- Define constant to determine whether the real_t type in Godot is double precision or not. By default this is false, like the official Godot builds. If someone is using a custom - Godot build where real_t is double, they can override the GodotRealTIsDouble property. + Godot build where real_t is double, they can override the GodotFloat64 property. --> - <DefineConstants Condition=" '$(GodotRealTIsDouble)' == 'true' ">GODOT_REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants> + <DefineConstants Condition=" '$(GodotFloat64)' == 'true' ">GODOT_REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants> </PropertyGroup> <!-- C# source generators --> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index aae7a5ebfa..5827d3e591 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -36,6 +36,7 @@ </ItemGroup> <PropertyGroup> <DefineConstants>$(DefineConstants);GODOT</DefineConstants> + <DefineConstants Condition=" '$(GodotFloat64)' == 'true' ">REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants> </PropertyGroup> <ItemGroup> <PackageReference Include="ReflectionAnalyzers" Version="0.1.22-dev" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" /> diff --git a/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj b/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj index ebf09aab7b..5d69ad8ec6 100644 --- a/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj @@ -25,6 +25,7 @@ </PropertyGroup> <PropertyGroup> <DefineConstants>$(DefineConstants);GODOT</DefineConstants> + <DefineConstants Condition=" '$(GodotFloat64)' == 'true' ">REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\GodotSharp\GodotSharp.csproj"> diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index a329c7ee8c..607c583df8 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2221,7 +2221,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } break; case WINDOW_FLAG_TRANSPARENT: { - //todo reimplement + wd.layered_window = p_enabled; } break; case WINDOW_FLAG_NO_FOCUS: { wd.no_focus = p_enabled; @@ -2274,7 +2274,7 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co return wd.on_top; } break; case WINDOW_FLAG_TRANSPARENT: { - //todo reimplement + return wd.layered_window; } break; case WINDOW_FLAG_NO_FOCUS: { return wd.no_focus; @@ -4426,13 +4426,41 @@ DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, W DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { //Create window - long visualMask = VisualScreenMask; - int numberOfVisuals; - XVisualInfo vInfoTemplate = {}; - vInfoTemplate.screen = DefaultScreen(x11_display); - XVisualInfo *visualInfo = XGetVisualInfo(x11_display, visualMask, &vInfoTemplate, &numberOfVisuals); + XVisualInfo visualInfo; + bool vi_selected = false; - Colormap colormap = XCreateColormap(x11_display, RootWindow(x11_display, vInfoTemplate.screen), visualInfo->visual, AllocNone); +#ifdef GLES3_ENABLED + if (gl_manager) { + visualInfo = gl_manager->get_vi(x11_display); + vi_selected = true; + } +#endif + + if (!vi_selected) { + long visualMask = VisualScreenMask; + int numberOfVisuals; + XVisualInfo vInfoTemplate = {}; + vInfoTemplate.screen = DefaultScreen(x11_display); + XVisualInfo *vi_list = XGetVisualInfo(x11_display, visualMask, &vInfoTemplate, &numberOfVisuals); + ERR_FAIL_COND_V(!vi_list, INVALID_WINDOW_ID); + + visualInfo = vi_list[0]; + if (OS::get_singleton()->is_layered_allowed()) { + for (int i = 0; i < numberOfVisuals; i++) { + XRenderPictFormat *pict_format = XRenderFindVisualFormat(x11_display, vi_list[i].visual); + if (!pict_format) { + continue; + } + visualInfo = vi_list[i]; + if (pict_format->direct.alphaMask > 0) { + break; + } + } + } + XFree(vi_list); + } + + Colormap colormap = XCreateColormap(x11_display, RootWindow(x11_display, visualInfo.screen), visualInfo.visual, AllocNone); XSetWindowAttributes windowAttributes = {}; windowAttributes.colormap = colormap; @@ -4442,6 +4470,13 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; + if (OS::get_singleton()->is_layered_allowed()) { + windowAttributes.background_pixmap = None; + windowAttributes.background_pixel = 0; + windowAttributes.border_pixmap = None; + valuemask |= CWBackPixel; + } + WindowID id = window_id_counter++; WindowData &wd = windows[id]; @@ -4465,7 +4500,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V } { - wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), p_rect.position.x, p_rect.position.y, p_rect.size.width > 0 ? p_rect.size.width : 1, p_rect.size.height > 0 ? p_rect.size.height : 1, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes); + wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo.screen), p_rect.position.x, p_rect.position.y, p_rect.size.width > 0 ? p_rect.size.width : 1, p_rect.size.height > 0 ? p_rect.size.height : 1, 0, visualInfo.depth, InputOutput, visualInfo.visual, valuemask, &windowAttributes); // Enable receiving notification when the window is initialized (MapNotify) // so the focus can be set at the right time. @@ -4602,8 +4637,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V XSync(x11_display, False); //XSetErrorHandler(oldHandler); - - XFree(visualInfo); } window_set_mode(p_mode, id); @@ -5013,17 +5046,24 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } cursor_set_shape(CURSOR_BUSY); - XEvent xevent; + Vector<XEvent> save_events; while (XPending(x11_display) > 0) { + XEvent xevent{ 0 }; XNextEvent(x11_display, &xevent); if (xevent.type == ConfigureNotify) { _window_changed(&xevent); - } else if (xevent.type == MapNotify) { - // Have we failed to set fullscreen while the window was unmapped? - _validate_mode_on_map(main_window); + } else { + // Don't discard this event, we must resend it... + save_events.push_back(xevent); } } + // Resend events that would have been dropped by the early event queue + // processing we just performed. + for (XEvent &ev : save_events) { + XSendEvent(x11_display, ev.xany.window, False, 0, &ev); + } + events_thread.start(_poll_events_thread, this); _update_real_mouse_position(windows[MAIN_WINDOW_ID]); diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index dd9ac088d9..ea03b2328c 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -159,6 +159,7 @@ class DisplayServerX11 : public DisplayServer { bool minimized = false; bool maximized = false; bool is_popup = false; + bool layered_window = false; Rect2i parent_safe_rect; @@ -251,8 +252,6 @@ class DisplayServerX11 : public DisplayServer { CursorShape current_cursor = CURSOR_ARROW; HashMap<CursorShape, Vector<Variant>> cursors_cache; - bool layered_window = false; - String rendering_driver; void set_wm_fullscreen(bool p_enabled); void set_wm_above(bool p_enabled); diff --git a/platform/linuxbsd/gl_manager_x11.cpp b/platform/linuxbsd/gl_manager_x11.cpp index d3fb1d6705..04c1df71fb 100644 --- a/platform/linuxbsd/gl_manager_x11.cpp +++ b/platform/linuxbsd/gl_manager_x11.cpp @@ -127,10 +127,6 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) { GLXFBConfig fbconfig = nullptr; XVisualInfo *vi = nullptr; - gl_display.x_swa.event_mask = StructureNotifyMask; - gl_display.x_swa.border_pixel = 0; - gl_display.x_valuemask = CWBorderPixel | CWColormap | CWEventMask; - if (OS::get_singleton()->is_layered_allowed()) { GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs_layered, &fbcount); ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED); @@ -156,12 +152,6 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) { XFree(fbc); ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED); - - gl_display.x_swa.background_pixmap = None; - gl_display.x_swa.background_pixel = 0; - gl_display.x_swa.border_pixmap = None; - gl_display.x_valuemask |= CWBackPixel; - } else { GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED); @@ -189,8 +179,6 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) { } break; } - gl_display.x_swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); - XSync(x11_display, False); XSetErrorHandler(oldHandler); @@ -205,6 +193,10 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) { return OK; } +XVisualInfo GLManager_X11::get_vi(Display *p_display) { + return _displays[_find_or_create_display(p_display)].x_vi; +} + Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) { // make sure vector is big enough... // we can mirror the external vector, it is simpler @@ -223,8 +215,6 @@ Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window // the display could be invalid .. check NYI GLDisplay &gl_display = _displays[win.gldisplay_id]; - //const XVisualInfo &vi = gl_display.x_vi; - //XSetWindowAttributes &swa = gl_display.x_swa; ::Display *x11_display = gl_display.x11_display; ::Window &x11_window = win.x11_window; @@ -315,6 +305,16 @@ void GLManager_X11::swap_buffers() { return; } + // On X11, when enabled, transparancy is always active, so clear alpha manually. + if (OS::get_singleton()->is_layered_allowed()) { + if (!DisplayServer::get_singleton()->window_get_flag(DisplayServer::WINDOW_FLAG_TRANSPARENT, _current_window->window_id)) { + glColorMask(false, false, false, true); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glColorMask(true, true, true, true); + } + } + // print_line("\tswap_buffers"); // only for debugging without drawing anything diff --git a/platform/linuxbsd/gl_manager_x11.h b/platform/linuxbsd/gl_manager_x11.h index fb2c74a2b6..4f78c45c88 100644 --- a/platform/linuxbsd/gl_manager_x11.h +++ b/platform/linuxbsd/gl_manager_x11.h @@ -68,8 +68,6 @@ private: GLManager_X11_Private *context = nullptr; ::Display *x11_display; XVisualInfo x_vi; - XSetWindowAttributes x_swa; - unsigned long x_valuemask; }; // just for convenience, window and display struct @@ -102,6 +100,7 @@ private: Error _create_context(GLDisplay &gl_display); public: + XVisualInfo get_vi(Display *p_display); Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height); void window_destroy(DisplayServer::WindowID p_window_id); void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height); diff --git a/platform/macos/detect.py b/platform/macos/detect.py index e5bcb46b02..cfd3789b41 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -54,11 +54,13 @@ def get_mvk_sdk_path(): return [int_or_zero(i) for i in a.split(".")] dirname = os.path.expanduser("~/VulkanSDK") - files = os.listdir(dirname) + if not os.path.exists(dirname): + return "" ver_file = "0.0.0.0" ver_num = ver_parse(ver_file) + files = os.listdir(dirname) for file in files: if os.path.isdir(os.path.join(dirname, file)): ver_comp = ver_parse(file) @@ -145,7 +147,7 @@ def configure(env): env.Append(LINKFLAGS=["-isysroot", "$MACOS_SDK_PATH"]) else: # osxcross build - root = os.environ.get("OSXCROSS_ROOT", 0) + root = os.environ.get("OSXCROSS_ROOT", "") if env["arch"] == "arm64": basecmd = root + "/target/bin/arm64-apple-" + env["osxcross_sdk"] + "-" else: @@ -248,7 +250,7 @@ def configure(env): env.Append(LINKFLAGS=["-L" + mvk_path]) if not mvk_found: mvk_path = get_mvk_sdk_path() - if os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")): + if mvk_path and os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")): mvk_found = True env.Append(LINKFLAGS=["-L" + mvk_path]) if not mvk_found: diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 6530846c15..b4949de3f7 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1312,7 +1312,28 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W _update_window_style(p_window); } break; case WINDOW_FLAG_TRANSPARENT: { - // FIXME: Implement. + if (p_enabled) { + //enable per-pixel alpha + + DWM_BLURBEHIND bb = { 0 }; + HRGN hRgn = CreateRectRgn(0, 0, -1, -1); + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = hRgn; + bb.fEnable = TRUE; + DwmEnableBlurBehindWindow(wd.hWnd, &bb); + + wd.layered_window = true; + } else { + //disable per-pixel alpha + wd.layered_window = false; + + DWM_BLURBEHIND bb = { 0 }; + HRGN hRgn = CreateRectRgn(0, 0, -1, -1); + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = hRgn; + bb.fEnable = FALSE; + DwmEnableBlurBehindWindow(wd.hWnd, &bb); + } } break; case WINDOW_FLAG_NO_FOCUS: { wd.no_focus = p_enabled; @@ -1344,7 +1365,7 @@ bool DisplayServerWindows::window_get_flag(WindowFlags p_flag, WindowID p_window return wd.always_on_top; } break; case WINDOW_FLAG_TRANSPARENT: { - // FIXME: Implement. + return wd.layered_window; } break; case WINDOW_FLAG_NO_FOCUS: { return wd.no_focus; diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index afdf78b380..dbc9821970 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -352,7 +352,6 @@ class DisplayServerWindows : public DisplayServer { struct WindowData { HWND hWnd; - //layered window Vector<Vector2> mpath; @@ -392,10 +391,6 @@ class DisplayServerWindows : public DisplayServer { Vector2 last_tilt; bool last_pen_inverted = false; - HBITMAP hBitmap; //DIB section for layered window - uint8_t *dib_data = nullptr; - Size2 dib_size; - HDC hDC_dib; Size2 min_size; Size2 max_size; int width = 0, height = 0; diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 32c112d21f..b0bccc4571 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -105,6 +105,7 @@ void LightmapGIData::_set_light_textures_data(const Array &p_data) { Vector<Ref<Image>> images; for (int i = 0; i < p_data.size(); i++) { Ref<TextureLayered> texture = p_data[i]; + ERR_FAIL_COND_MSG(texture.is_null(), vformat("Invalid TextureLayered at index %d.", i)); for (int j = 0; j < texture->get_layers(); j++) { images.push_back(texture->get_layer_data(j)); } |