Overhaul of InfiniFrame.Native C++ backend & comprehensive documentation#98
Overhaul of InfiniFrame.Native C++ backend & comprehensive documentation#98freakdaniel wants to merge 44 commits intoInfiniLore:corefrom
Conversation
…ract models, and fix issues InfiniLore#84 and InfiniLore#94 - Reorganized InfiniFrame.Native source tree into platform subdirectories: Windows/, Linux/, Mac/ for platform-specific implementations Models/ for shared data model headers - Renamed platform entry files to Window.cpp / Window.mm for consistency - Extracted all data models into Models/: InfiniFrame.h, InfiniFrameDialog.h, Types.h, Monitor.h, Callbacks.h, InitParams.h, DialogEnums.h - Added CMAKE_SOURCE_DIR to include paths so all files use root-relative includes - Updated all #include directives across Windows, Linux, Mac, and Exports files to reference Models/InfiniFrame.h and Models/InfiniFrameDialog.h - Fix InfiniLore#84: RegisterMessageHandler now silently overwrites duplicate message IDs instead of throwing on collision (ConcurrentDictionary indexer instead of TryAdd) - Fix InfiniLore#94: WaitForClose no longer acquires a global MessageLoopState lock, enabling independent per-thread message loops; deleted MessageLoopState.cs - Fix InfiniLore#94 Windows: added thread_local messageLoopRootWindowHandle and mutex- protected hwndToInfiniFrame map for safe concurrent window registration - Fix InfiniLore#94 Linux: moved gtk_main_quit() signal connection from constructor into WaitForExit() so each nested gtk_main() level is exited by its own window's destroy signal - Fix InfiniLore#94 macOS: WaitForExit() checks [NSApp isRunning] so first caller uses [NSApp run], subsequent callers spin NSRunLoop until NSWindowWillCloseNotification fires for their specific window, working around Apple's restriction on recursive NSApp run calls
… Windows backend InitParams.h: fix callback fields declared as pointer-to-function-pointer (ClosingCallback*) instead of the correct function pointer type (ClosingCallback), removing unintended double indirection — updates Linux and macOS constructor assignments accordingly Windows/Window.cpp: - fix StartUrl and StartString not being converted via ToUTF16String in the constructor, causing double-reinterpretation in AttachWebView that silently broke non-ASCII URLs - fix AttachWebView to call WebView2 Navigate/NavigateToString directly with already-converted wstrings instead of going through NavigateToUrl/NavigateToString again - fix SetWebView2RuntimePath to convert UTF-8 input via Utf8ToWide instead of raw wcsncpy_s - replace C-style casts with reinterpret_cast in WM_USER_INVOKE handler - remove dead WM_MOVING case, commented-out calls in WM_MOVE and NotifyWebView2WindowMove, debug swprintf block in Center(), TODO comment in Invoke() Exports.cpp: - remove 5 dead callback setter exports (SetClosingCallback, SetFocusInCallback, SetFocusOutCallback, SetMovedCallback, SetResizedCallback) superseded by init params - remove default parameter from InfiniFrame_ShowSaveFile — not valid at ABI boundaries NativeDll.cs / InfiniFrameNative.cs: add missing InfiniFrame_Restore P/Invoke binding Linux/Window.cpp: - fix custom scheme handler to use free() instead of delete[] for contentType - pass free as GDestroyNotify to g_memory_input_stream_new_from_data for correct lifetime Mac/UrlSchemeHandler.mm: - guard against null contentType before constructing NSString (crash on 404 responses) - guard against null/empty dotNetResponse before passing data to urlSchemeTask CMakeLists.txt: add simdutf.cpp and simdutf.h to build sources; bump C++ standard to cxx_std_23 InfiniWindowExtensions.cs: replace Marshal.PtrToStringAuto with InfiniFrameNative.PtrToNativeString for platform-correct UTF-16/UTF-8 string reading InfiniFrameWindow.cs: explicitly pass null for defaultFileName in ShowSaveFile call after removing the default parameter from the native export signature
Major restructuring: - Reorganized Models directory into specialized directories (Core, Types, Interop, Utils, Platform) - Renamed InfiniFrame class to InfiniFrameWindow to match filename - Added alias using InfiniFrame = InfiniFrameWindow for backward compatibility - Moved all types into InfiniFrame namespace - Updated CMakeLists.txt with new file paths and FetchContent dependencies (fmt, simdjson v4.3.1) Critical fixes: - Fixed macOS deadlock by replacing dispatch_sync with dispatch_async - Removed blocking g_main_context_iteration loop on Linux - Added RAII for GDI objects (HBRUSH) to prevent resource leaks - Replaced raw new/delete with std::make_unique in Exports.cpp Code quality improvements: - Added comprehensive XML documentation to all Exports.cpp functions (70+ methods) - Standardized comment style (Sentence case instead of UPPERCASE) - Removed redundant C++23 mentions in comments - Cleaned up excessive inline comments - Simplified Exports.cpp using directives (single using namespace InfiniFrame) Modern C++23 features: - std::expected for error handling - RAII wrappers for native resources - Smart pointers throughout codebase fmt library for type-safe formatting simdjson for high-performance - JSON parsing Build improvements: - Enabled sanitizers for Debug builds (ASan, UBSan, LeakSan) - Added precompiled headers for faster compilation - Fixed platform-specific include paths All changes maintain C API backward compatibility with existing .NET interop layer
… clean up dead code Architecture - Introduce InfiniFrameWindowImpl.h as shared base struct for all platform Impl definitions - Add InfiniFrame.h umbrella header used by Exports.cpp instead of individual includes - Complete Pimpl migration for Linux and macOS (Windows was already done) - Add platform-guarded private helpers to InfiniFrameWindow.h: EnsureWebViewIsInstalled/InstallWebView2 (Win32), OnConfigureEvent/OnWindowStateEvent (Linux), WindowProc friend declaration (Win32) Namespace removal - Remove namespace InfiniFrame from Dialog.h and InitParams.h - Remove using InfiniFrame = InfiniFrameWindow alias from InitParams.h and InfiniFrameWindow.h - Update Exports.cpp to reference InfiniFrameWindow directly throughout Dead code removal - Delete Dependencies/json.hpp (25k lines, nlohmann) - Replace json.hpp usage in Linux set_webkit_customsettings with simdjson ondemand - Remove json.hpp include from Mac Window.mm - Remove WideStringDeleter, CStringDeleter, ToNativeString from Basic.h - Remove naive ASCII-only Utf8ToWide/WideToUtf8 from Common.h Style - Strip alignment spacing from all Impl field declarations across Windows, Linux, and Mac - Rename WindowImplBase to InfiniFrameWindowImpl (file, struct name, all usages) Misc - Remove unused wwwroot placeholder files from examples and tests
…itParams, and remove unused resources - Fix headers names - Update #include 's - Remove unused headers from CMakeLists
- Linux: Replace `.error() == simdjson::SUCCESS` with `== simdjson::SUCCESS` to match simdjson v4.4.0 API where get<T>() returns error_code directly - Linux: Move OnConfigureEvent/OnWindowStateEvent from private to public so GTK signal handlers can call them - macOS: Fix unknown type 'InfiniFrame' -> 'InfiniFrameWindow' in WindowDelegate.h and NavigationDelegate.h
- macOS: #import "Models/InfiniFrameDialog.h" -> "Core/InfiniFrameDialog.h" (Models/ directory does not exist; header lives in Core/) - Linux: add #include <gtk/gtk.h> so GTK types and functions are declared (Dialog.cpp uses GTK directly without webkit2 to pull it in transitively)
- Add _temporaryFilesPath to macOS Impl struct (was only in Linux Impl) - Replace field.key().value().data() with field.unescaped_key().value() - Remove .error() from value.get<T>() calls because get<T>() returns error_code directly
- Added _hasSavedRect and _savedRect for restoring window on current monitor of window - Use new style for macOS with collectionBehavior which also stores window screen
|
Re-running tests bcs of the last commit |
|
@AnnaSasDev seems i am done at this point. Other things which i want to implement are going out from the current scope of the PR |
|
There seems to be some form of regression that is made clear during testing. Where tests completed in a few minutes, is now taking several tens of minutes. |
- Included `docs/` folder with Guides, Reference, and Getting Started documentation in the solution file.
|
Also there are more build warnings now during the building of 0>Exports.cpp(53,76): Warning C4100 : 'instance': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Exports.cpp')
0>wintoastlib.cpp(1091,17): Warning C4456 : declaration of 'hr' hides previous local declaration [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Dependencies/wintoastlib.cpp')
C:\Dev\InfiniFrame\src\InfiniFrame.Native\Dependencies\wintoastlib.cpp(1088,13):
see declaration of 'hr'
0>wintoastlib.cpp(304,80): Warning C4100 : 'notify': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Dependencies/wintoastlib.cpp')
C:\Dev\InfiniFrame\src\InfiniFrame.Native\Dependencies\wintoastlib.cpp(304,80):
the template instantiation context (the oldest one first) is
C:\Dev\InfiniFrame\src\InfiniFrame.Native\Dependencies\wintoastlib.cpp(815,48):
see reference to function template instantiation 'HRESULT Util::setEventHandlers<WinToastLib::WinToast::showToast::<lambda_1>>(ABI::Windows::UI::Notifications::IToastNotification *,std::shared_ptr<WinToastLib::IWinToastHandler>,INT64,EventRegistrationToken &,EventRegistrationToken &,EventRegistrationToken &,FunctorT &&)' being compiled
with
[
FunctorT=WinToastLib::WinToast::showToast::<lambda_1>
]
0>wintoastlib.cpp(371,100): Warning C4100 : 'notify': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Dependencies/wintoastlib.cpp')
0>wintoastlib.cpp(388,119): Warning C4100 : 'e': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Dependencies/wintoastlib.cpp')
0>wintoastlib.cpp(388,88): Warning C4100 : 'notify': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Dependencies/wintoastlib.cpp')
0>ToastHandler.h(45,29): Warning C4100 : 'actionIndex': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>ToastHandler.h(54,38): Warning C4100 : 'response': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>ToastHandler.h(63,49): Warning C4100 : 'state': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>Window.cpp(1192,27): Warning C4100 : 'webview': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>Window.cpp(1202,27): Warning C4100 : 'sender': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>Window.cpp(1248,28): Warning C4100 : 'sender': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>Window.cpp(1402,21): Warning C4100 : 'error': unreferenced parameter [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
(compiling source file '../../../Platform/Windows/Window.cpp')
0>wintoastlib.cpp(824,1): Warning C4701 : potentially uninitialized local variable 'failedToken' used [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
0>wintoastlib.cpp(824,1): Warning C4701 : potentially uninitialized local variable 'dismissedToken' used [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
0>wintoastlib.cpp(824,1): Warning C4701 : potentially uninitialized local variable 'activatedToken' used [C:\Dev\InfiniFrame\src\InfiniFrame.Native\build\x64\Debug\InfiniFrame.Native.vcxproj]
Creating library C:/Dev/InfiniFrame/src/InfiniFrame.Native/build/x64/Debug/Debug/InfiniFrame.Native.lib and object C:/Dev/InfiniFrame/src/InfiniFrame.Native/build/x64/Debug/Debug/InfiniFrame.Native.exp
|
- Adjusted `.gitignore` to improve handling of `cmake-build` directories and native build outputs. - Updated `InfiniFrame.Native.proj` to explicitly exclude build artifacts and package directories from the project.
|
Alligned some code style consistency with the C# code. |
- Add /W0 flag to wintoastlib - Add caching to CMake - Add --parallel to CMake
- Added run for GSettings schemas - Added saving for topmost in window Impl
Description
Introducing: reorganization of the source tree into platform subdirectories, a complete Pimpl architecture migration, critical bug fixes for concurrent window usage, ABI/interop correctness fixes, modernization of the codebase to C++23, and comprehensive user-facing documentation for all InfiniFrame NuGet packages
Development System
Type of Change
Changes Made
Native source reorganization
InfiniFrame.Windows.cpp,InfiniFrame.Linux.cpp,InfiniFrame.Mac.mm) intoPlatform/Windows/,Platform/Linux/, andPlatform/Mac/subdirectories. Also renamed entry points toWindow.cpp/Window.mmfor consistencyCore/,Types/,Utils/Dependencies/json.hpp(nlohmann) and replace withsimdjson(ondemand API)simdutffor correct UTF-8 to UTF-16 conversionsPimpl & architecture
InfiniFrameWindowImpl.has a shared base struct for all platformImpldefinitionsMessageLoopState.cs(per-window message loops no longer share a global lock)Bug fixes
InfiniFrameWindowMessageHandlers.RegisterMessageHandlershould have non breaking behaviour on duplicate message id #84RegisterMessageHandlernow silently overwrites duplicate message IDs instead of throwing on collisionWaitForCloseno longer acquires a globalMessageLoopStatelock. Independent per-thread message loops are now supported on all three platformsSetFullScreenis now monitor-aware on all three platforms:enterFullScreenMode:[NSScreen mainScreen]contentView API totoggleFullScreen:withNSWindowCollectionBehaviorFullScreenPrimary, which is monitor-aware and handles geometry restore nativelyStartUrl/StartStringnow go throughToUTF16Stringon Windows, andSetWebView2RuntimePathusesUtf8ToWideinstead of rawwcsncpy_sWaitForCloseno longer acquires a globalMessageLoopStatelock. Independent per-thread message loops are now supported on all three platformsStartUrl/StartStringnot being converted viaToUTF16Stringon Windows (silent breakage for non-ASCII URLs)SetWebView2RuntimePathusing rawwcsncpy_sinstead ofUtf8ToWidedispatch_syncwithdispatch_asyncdelete[]on amalloc-allocatedcontentType(UB)Mac/UrlSchemeHandler.mmfor nullcontentTypeand empty.NETresponse (crash on 404)Build & tooling
simdutfandsimdjson, viaFetchContentInterop (.NET)
InfiniFrame_RestoreP/Invoke binding inInfiniFrameNative.csMarshal.PtrToStringAutowithInfiniFrameNative.PtrToNativeStringfor platform-correct string readingDocumentation
README.mdwith package table, quick-start snippets for all three integration paths, architecture diagram, and links to the full docsdocs/GettingStarted.md— prerequisites, platform requirements, and a complete first-app walkthrough for each integration modeldocs/Guides/CoreWindow.md— builder pattern, window configuration, browser features, runtime control, events, messaging, dialogs, custom schemes, monitor info, and DI integrationdocs/Guides/Blazor.md— project setup, DI, file providers, HttpClient, lifecycle, and error handling forInfiniLore.InfiniFrame.BlazorWebViewdocs/Guides/WebServer.md— builder API, URL resolution, DI access, graceful shutdown, thread model, and Blazor Server example forInfiniLore.InfiniFrame.WebServerdocs/Guides/CustomChrome.md— chromeless setup, Blazor chrome components, full layout example, and CSS tipsdocs/Guides/JsInterop.md— web messaging,IInfiniFrameJspointer capture, built-in message handlers, and structured JSON patternsdocs/Reference/WindowApi.md,BuilderApi.md,Events.md,Types.md— full API reference for all public surfacesREADME.mdto eachsrc/library for NuGet consumersexamples/README.md— index of all five examples with integration type, description, and links to relevant guidesREADME.mdto eachexamples/project describing what it demonstrates, key code, and links back to the relevant docsdocs/Guides/(Blazor, WebServer, JsInterop, CoreWindow) — each guide now points to the runnable examples that correspond to itdocs/BreakingChanges.md— Photino vs InfiniFrame reference updatesREADME.mdRelated Issues
Closes #84
Closes #94
Closes #90
Closes #89
Closes #29
Checklist