Complete branding in-code rename & fix native bugs#75
Complete branding in-code rename & fix native bugs#75AnnaSasDev merged 20 commits intoInfiniLore:corefrom
Conversation
Rename - Renamed all C++ source/header files from Photino.* to InfiniFrame.* - Renamed C++ class Photino to InfiniFrame, struct PhotinoInitParams to InfiniFrameInitParams - Renamed constructor/destructor on all platforms (InfiniFrame::InfiniFrame / ~InfiniFrame) - Renamed all C exports from Photino_* to InfiniFrame_* (Exports.cpp, Exports.Tests.cpp) - Renamed PhotinoDialog to InfiniFrameDialog - Renamed JS interop channel from photinointerop to infiniFrameInterop - Windows CLASS_NAME changed from L"Photino" to L"InfiniFrame" - Updated CMakeLists.txt source file references - Updated all C# P/Invoke entry points in NativeDll.cs and InfiniFrameNative.cs - Updated Blazor component injection from PhotinoWindow to Window - Updated comments across BlazorWebView, WebServer, Shared, Enums, FluentApi - Updated Directory.Build.props author field - Renamed delegate member variable photino to infiniFrame in Mac delegate headers Bug fixes (Windows) - SetMaxSize: fixed copy-paste bug comparing currWidth instead of currHeight against _maxHeight - GetTopmost/SetTopmost: fixed checking GWL_STYLE instead of GWL_EXSTYLE - GetMaximized/GetMinimized/GetResizable: out-parameter now initialized on both true and false paths - SetFullScreen: removed duplicate SetPosition/SetSize calls Bug fixes (Linux) - Constructor: _zoomEnabled now reads from initParams instead of hardcoded true - SetMaximized: removed incorrect _isFullScreen = maximized assignment - set_webkit_customsettings: fixed G_TYPE_BOOLEAN to G_TYPE_DOUBLE for float property values - on_permission_request: now checks _grantBrowserPermissions instead of always granting Bug fixes (macOS) - GetMaximized: now uses [_window isZoomed] with fullscreen guard instead of checking NSWindowStyleMaskFullScreen - Destructor: removed [NSApp release] (shared singleton), added cleanup for leaked string fields - Constructor: _contextMenuEnabled/_zoomEnabled now read from initParams instead of hardcoded true - Custom scheme names: ownership transferred to _ownedCustomSchemeNames vector for proper cleanup - SetUserAgent: now copies string with new char[] + strcpy instead of raw pointer assignment - GetPosition/SetPosition: Monitor objects from GetMonitors() now freed after use Code cleanup - Removed dead exit(0) after new operator - Removed unused escape_json function (Linux), replaced by nlohmann::json - Removed unused EnsureInvoke function (macOS) - Removed commented-out debug traces, MessageBox calls, PRINTF macros, paint code, Edit menu, SetPreference overloads - Removed self-include in header - Removed unused #include <cstdlib> from Exports.cpp - Replaced all NULL with nullptr in macOS code - Renamed local variable shadowing class name (Photino* Photino -> InfiniFrame* instance in WindowProc) C# imports - Converted legacy [DllImport] methods to [LibraryImport] with [MarshalAs(UnmanagedType.I1)] (GetResizable, GetMaximized, GetMinimized, GetZoomEnabled) CMake - Fixed OUTPUT_ARCH_DIR undefined on Linux (was producing empty path) - Separated test sources into TEST_SOURCES variable
- ToggleMaximized events: Uncommented OnMaximized()/OnRestored() so _suppressGrabbing is properly toggled - Double-click guard: Added Detail >= 2 check in OnPointerDown to skip the second pointerdown during double-click - OnPointerUp cleanup: Always resets _isGrabbing and releases pointer capture regardless of _suppressGrabbing - Test utility lifecycle: Dispose() now tracks and waits for the message loop Task before proceeding - Skip messages: Removed stale SkipOnWindows from ContextMenu/DevTools tests, fixed typos and improved skip reason messages
C# improvements: - MessageHandlers: Dictionary → ConcurrentDictionary for thread safety - InvokeUtilities: Debug.Assert contract + XML documentation - WebApp Thread: IsBackground = true for proper shutdown - Max/Min Width/Height: backing fields with native SetMaxSize/SetMinSize sync C++ modernization: - CMake: move C++20 to C++23 - Header: NativeString typedef (std::string/std::wstring), std::unique_ptr for _dialog and _toastHandler, removed _ownedCustomSchemeNames vectors - All platforms: new char[]/strcpy/delete[] to NativeString assignment, C-style casts to reinterpret_cast/static_cast/const_cast, std::make_unique for RAII, .empty() instead of nullptr checks
C++ (InfiniFrame.h + Linux/Mac/Windows implementations): - Replace typedef function pointers with modern using aliases - Add const qualifier to getter methods across all platforms - Add [[nodiscard]] to key getters, noexcept to Invoke* methods - Move _contextMenuEnabled/_zoomEnabled to private section - Replace C-style casts with static_cast/reinterpret_cast/const_cast - Replace NULL with nullptr in remaining locations - Change vector<Monitor*> with new/delete to vector<Monitor> by value (Mac) - Replace strtok with thread-safe strtok_r (Linux dialog) - Remove redundant #ifndef/#define guards where #pragma once exists C# (InfiniFrameWindow.cs): - Modernize using statements to using declarations
|
In the latest updates, you have started to add a lot of braking API changes on the C# side, like the setters for properties for Thanks for all the good work so far though! |
|
One extra thing, the "I have updated the documentation accordingly" can be ignored for now, unless it is inline documentation. There is currently no set documentation yet as this is still in preview |
|
Otherwise, subsequent changes may be too extensive within the scope of this PR (I intend to remove numerous auto-variables from the code for complete memory management and replace the remaining C-like code). Therefore, it can be said that I am finished at this point. All that remains is to test it... |
|
There seems to be an issue with the visibily of the checks, am resovling it in PR #80 |
|
Problems arose due to the merger with the bump bot changes. From what I saw in the lastest pipeline:
Rebase bugfix branch and problem will be solved |
Rename - Renamed all C++ source/header files from Photino.* to InfiniFrame.* - Renamed C++ class Photino to InfiniFrame, struct PhotinoInitParams to InfiniFrameInitParams - Renamed constructor/destructor on all platforms (InfiniFrame::InfiniFrame / ~InfiniFrame) - Renamed all C exports from Photino_* to InfiniFrame_* (Exports.cpp, Exports.Tests.cpp) - Renamed PhotinoDialog to InfiniFrameDialog - Renamed JS interop channel from photinointerop to infiniFrameInterop - Windows CLASS_NAME changed from L"Photino" to L"InfiniFrame" - Updated CMakeLists.txt source file references - Updated all C# P/Invoke entry points in NativeDll.cs and InfiniFrameNative.cs - Updated Blazor component injection from PhotinoWindow to Window - Updated comments across BlazorWebView, WebServer, Shared, Enums, FluentApi - Updated Directory.Build.props author field - Renamed delegate member variable photino to infiniFrame in Mac delegate headers Bug fixes (Windows) - SetMaxSize: fixed copy-paste bug comparing currWidth instead of currHeight against _maxHeight - GetTopmost/SetTopmost: fixed checking GWL_STYLE instead of GWL_EXSTYLE - GetMaximized/GetMinimized/GetResizable: out-parameter now initialized on both true and false paths - SetFullScreen: removed duplicate SetPosition/SetSize calls Bug fixes (Linux) - Constructor: _zoomEnabled now reads from initParams instead of hardcoded true - SetMaximized: removed incorrect _isFullScreen = maximized assignment - set_webkit_customsettings: fixed G_TYPE_BOOLEAN to G_TYPE_DOUBLE for float property values - on_permission_request: now checks _grantBrowserPermissions instead of always granting Bug fixes (macOS) - GetMaximized: now uses [_window isZoomed] with fullscreen guard instead of checking NSWindowStyleMaskFullScreen - Destructor: removed [NSApp release] (shared singleton), added cleanup for leaked string fields - Constructor: _contextMenuEnabled/_zoomEnabled now read from initParams instead of hardcoded true - Custom scheme names: ownership transferred to _ownedCustomSchemeNames vector for proper cleanup - SetUserAgent: now copies string with new char[] + strcpy instead of raw pointer assignment - GetPosition/SetPosition: Monitor objects from GetMonitors() now freed after use Code cleanup - Removed dead exit(0) after new operator - Removed unused escape_json function (Linux), replaced by nlohmann::json - Removed unused EnsureInvoke function (macOS) - Removed commented-out debug traces, MessageBox calls, PRINTF macros, paint code, Edit menu, SetPreference overloads - Removed self-include in header - Removed unused #include <cstdlib> from Exports.cpp - Replaced all NULL with nullptr in macOS code - Renamed local variable shadowing class name (Photino* Photino -> InfiniFrame* instance in WindowProc) C# imports - Converted legacy [DllImport] methods to [LibraryImport] with [MarshalAs(UnmanagedType.I1)] (GetResizable, GetMaximized, GetMinimized, GetZoomEnabled) CMake - Fixed OUTPUT_ARCH_DIR undefined on Linux (was producing empty path) - Separated test sources into TEST_SOURCES variable
- ToggleMaximized events: Uncommented OnMaximized()/OnRestored() so _suppressGrabbing is properly toggled - Double-click guard: Added Detail >= 2 check in OnPointerDown to skip the second pointerdown during double-click - OnPointerUp cleanup: Always resets _isGrabbing and releases pointer capture regardless of _suppressGrabbing - Test utility lifecycle: Dispose() now tracks and waits for the message loop Task before proceeding - Skip messages: Removed stale SkipOnWindows from ContextMenu/DevTools tests, fixed typos and improved skip reason messages
C# improvements: - MessageHandlers: Dictionary → ConcurrentDictionary for thread safety - InvokeUtilities: Debug.Assert contract + XML documentation - WebApp Thread: IsBackground = true for proper shutdown - Max/Min Width/Height: backing fields with native SetMaxSize/SetMinSize sync C++ modernization: - CMake: move C++20 to C++23 - Header: NativeString typedef (std::string/std::wstring), std::unique_ptr for _dialog and _toastHandler, removed _ownedCustomSchemeNames vectors - All platforms: new char[]/strcpy/delete[] to NativeString assignment, C-style casts to reinterpret_cast/static_cast/const_cast, std::make_unique for RAII, .empty() instead of nullptr checks
C++ (InfiniFrame.h + Linux/Mac/Windows implementations): - Replace typedef function pointers with modern using aliases - Add const qualifier to getter methods across all platforms - Add [[nodiscard]] to key getters, noexcept to Invoke* methods - Move _contextMenuEnabled/_zoomEnabled to private section - Replace C-style casts with static_cast/reinterpret_cast/const_cast - Replace NULL with nullptr in remaining locations - Change vector<Monitor*> with new/delete to vector<Monitor> by value (Mac) - Replace strtok with thread-safe strtok_r (Linux dialog) - Remove redundant #ifndef/#define guards where #pragma once exists C# (InfiniFrameWindow.cs): - Modernize using statements to using declarations
|
Now i see real errors. Working on it :) |
|
Try to run tests again please |
- Set* methods now update cached fields before checking _webviewWindow, so Get* can return correct values even before WebView2 initializes - Get* methods fall back to cached fields when _webviewWindow/_webviewController is null, preventing false negatives in FullIntegration tests - SetTransparentEnabled/GetTransparentEnabled now guard against null controller
|
So let me explain the current problem in the assembler. After running Github Actions, I came to the following conclusion: For some reason specifically for .NET 9.0 the GC collector is aggressive towards delegates We have public struct InfiniFrameNativeParameters : IEquatable<InfiniFrameNativeParameters>I added anchors in // InfiniFrameWindow.cs
//
// Keeps native callback delegates alive for the lifetime of the window
// Required because P/Invoke marshal-back of ref structs can replace delegate
// fields with new objects, leaving the originals eligible for GC
internal object[]? NativeCallbackAnchors;The anchor for // InfiniFrameWindowBuilder.cs
//
// Pin all native callback delegates so the GC cannot collect them after
// P/Invoke marshal-back replaces the struct fields with new delegate objects
window.NativeCallbackAnchors = [
startupParameters.ClosingHandler!,
startupParameters.ResizedHandler!,
startupParameters.MaximizedHandler!,
startupParameters.RestoredHandler!,
startupParameters.MinimizedHandler!,
startupParameters.MovedHandler!,
startupParameters.FocusInHandler!,
startupParameters.FocusOutHandler!,
startupParameters.WebMessageReceivedHandler!,
startupParameters.CustomSchemeHandler!,
];In reality this solution is a compromise, and ideally here are like 3 methods to resolve this in more clear way:
// InfiniFrameNativeParameters.cs
// Before
[StructLayout(LayoutKind.Sequential)]
public struct InfiniFrameNativeParameters { ... }
// After
[StructLayout(LayoutKind.Sequential)]
public class InfiniFrameNativeParameters { ... }// InfiniFrameNative.cs
// Before
internal static extern IntPtr Constructor(ref InfiniFrameNativeParameters parameters);
// After
internal static partial void Constructor(InfiniFrameNativeParameters parameters);
// InfiniFrameWindow.cs
//
// Explicit fields so GC sees direct references, no magic
private CppClosingDelegate? _nativeClosingHandler;
private CppFocusInDelegate? _nativeFocusInHandler;
private CppFocusOutDelegate? _nativeFocusOutHandler;
private CppResizedDelegate? _nativeResizedHandler;
private CppMaximizedDelegate? _nativeMaximizedHandler;
private CppRestoredDelegate? _nativeRestoredHandler;
private CppMinimizedDelegate? _nativeMinimizedHandler;
private CppMovedDelegate? _nativeMovedHandler;
private CppWebMessageReceivedDelegate? _nativeWebMessageReceivedHandler;
private CppWebResourceRequestedDelegate? _nativeCustomSchemeHandler;// InfiniFrameWindowBuilder.cs
//
// Create delegate objects explicitly and immediately save them to fields
window._nativeClosingHandler = Events.OnWindowClosing;
window._nativeFocusInHandler = Events.OnFocusIn;
window._nativeFocusOutHandler = Events.OnFocusOut;
window._nativeResizedHandler = Events.OnSizeChanged;
window._nativeMaximizedHandler = Events.OnMaximized;
window._nativeRestoredHandler = Events.OnRestored;
window._nativeMinimizedHandler = Events.OnMinimized;
window._nativeMovedHandler = Events.OnLocationChanged;
window._nativeWebMessageReceivedHandler = Events.OnWebMessageReceived;
window._nativeCustomSchemeHandler = window.OnCustomScheme;
// Fill in the struct from the saved fields
startupParameters.ClosingHandler = window._nativeClosingHandler;
startupParameters.FocusOutHandler = window._nativeFocusOutHandler;
// ...
window.StartupParameters = startupParameters;
// InfiniFrameWindow.cs
private GCHandle[] _delegateHandles = [];
// Called from Builder before Initialize()
internal void PinNativeCallbacks(params Delegate?[] delegates)
{
_delegateHandles = delegates
.Where(d => d is not null)
.Select(d => GCHandle.Alloc(d!))
.ToArray();
}
// MUST be in Dispose/Close otherwise there will be a memory leak
private void FreePinnedCallbacks()
{
foreach (var handle in _delegateHandles)
if (handle.IsAllocated)
handle.Free();
_delegateHandles = [];
}
public void Close() {
FreePinnedCallbacks(); // <- must be before or after closing the native window
// ...
} |
|
LMAO while I was figuring it out, I found another solution where you can remove anchors... Look at the difference between the two functions: // InfiniFrameNative.cs
//
// Constructor ref WITHOUT [In]:
internal static extern IntPtr Constructor(ref InfiniFrameNativeParameters parameters);// InfiniWindowNative.cs
//
// NativeParametersReturnAsIs ref WITH [In]:
private static extern void NativeParametersReturnAsIs(
[In] ref InfiniFrameNativeParameters parameters, // <--- [In] is present!
out IntPtr newParameters
);In case of using
So the simplest solution is to just add // InfiniFrameNative.cs
// Was:
internal static extern IntPtr Constructor(ref InfiniFrameNativeParameters parameters);
// Needed:
internal static extern IntPtr Constructor([In] ref InfiniFrameNativeParameters parameters);C++ in Constructor does not write anything back to params it only reads from it when creating a window. This means that marshal-back is not needed at all, and |
|
All tests passed in fork CI: https://github.com/freakdaniel/InfiniFrame/actions/runs/22895706656 |
|
Thanks for the work on the PR! |
|
As I said earlier... Thank you for all your hard work! I will prepare the next PR soon. I am drawing up a plan. There are still a lot of compromises and assumptions in the code |
absolutely! |
Description
Complete Photino-to-InfiniFrame rename across native and managed code, fix critical native bugs on all platforms, fix DragArea double-click race condition, and improve test infrastructure reliability
Development System
Type of Change
Changes Made
Rename (Photino to InfiniFrame)
Photino.*toInfiniFrame.*PhotinotoInfiniFrame, structPhotinoInitParamstoInfiniFrameInitParamsInfiniFrame::InfiniFrame/~InfiniFrame)Photino_*toInfiniFrame_*(Exports.cpp, Exports.Tests.cpp)PhotinoDialogtoInfiniFrameDialogphotinointeroptoinfiniFrameInteropCLASS_NAMEchanged fromL"Photino"toL"InfiniFrame"PhotinoWindowtoWindowphotinotoinfiniFramein Mac delegate headersHeader / all platforms (
InfiniFrame.h,*.cpp,*.mm)typedeffunction pointer declarations withusingaliasesconstqualifier to getter methods across all platforms[[nodiscard]]to key getters (GetDialog,GetUserAgent,GetIconFileName,GetTitle,GetScreenDpi)noexceptto allInvoke*methods_contextMenuEnabled/_zoomEnabledfrompublic:toprivate:; updated Linux static callback to use the getterstatic_cast/reinterpret_cast/const_castacross Mac, Windows and Linux filesNULLoccurrences withnullptr(Windows.cpp, Mac.UrlSchemeHandler.mm, Linux.Dialog.cpp)std::vector<Monitor*>with manualnew/deletetostd::vector<Monitor>by value (Mac)strtokwith thread-safestrtok_rin Linux dialog filter parsing#ifndef/#define/#endifguards fromInfiniFrame.Dialog.handInfiniFrame.Windows.ToastHandler.h(kept#pragma once)RAII / thread safety
GetDevToolsEnabled(Linux): removed stale cache mutation, now queries WebKit directly (compatible withconst)GetPosition/SetPosition: eliminateddeleteloops after switchingGetMonitors()to value semanticsC# adjustments
using (var x = ...)blocks to modernusing vardeclarations (inInfiniFrameWindow.cs)[DllImport]methods to[LibraryImport]with[MarshalAs(UnmanagedType.I1)](GetResizable,GetMaximized,GetMinimized,GetZoomEnabled)Code Cleanup
exit(0)afternewoperatorescape_jsonfunction (Linux), replaced bynlohmann::jsonEnsureInvokefunction (macOS)MessageBoxcalls,PRINTFmacros, paint code, Edit menu,SetPreferenceoverloads#include <cstdlib>from Exports.cppNULLwithnullptrin macOS codePhotino* PhotinotoInfiniFrame* instanceinWindowProc)CMake
OUTPUT_ARCH_DIRundefined on Linux (was producing empty path)TEST_SOURCESvariableFixed Bugs
Native (Windows)
SetMaxSize: fixed copy-paste bug comparingcurrWidthinstead ofcurrHeightagainst_maxHeightGetTopmost/SetTopmost: fixed checkingGWL_STYLEinstead ofGWL_EXSTYLEGetMaximized/GetMinimized/GetResizable: out-parameter now initialized on both true and false pathsSetFullScreen: removed duplicateSetPosition/SetSizecallsNative (Linux)
_zoomEnablednow reads frominitParamsinstead of hardcodedtrueSetMaximized: removed incorrect_isFullScreen = maximizedassignmentset_webkit_customsettings: fixedG_TYPE_BOOLEANtoG_TYPE_DOUBLEfor float property valueson_permission_request: now checks_grantBrowserPermissionsinstead of always grantingNative (macOS)
GetMaximized: now uses[_window isZoomed]with fullscreen guard instead of checkingNSWindowStyleMaskFullScreen[NSApp release](shared singleton), added cleanup for leaked string fields_contextMenuEnabled/_zoomEnablednow read frominitParamsinstead of hardcodedtrue_ownedCustomSchemeNamesvector for proper cleanupSetUserAgent: now copies string withnew char[]+strcpyinstead of raw pointer assignmentGetPosition/SetPosition: Monitor objects fromGetMonitors()now freed after useDragArea Double-Click Race Condition (#19)
OnMaximized()/OnRestored()event calls inToggleMaximized()so_suppressGrabbingflag is properly toggledDetail >= 2guard inOnPointerDownto skip the second pointerdown during a double-click sequenceOnPointerUpto always reset_isGrabbingand release pointer capture regardless of_suppressGrabbingstateTest Infrastructure Lifecycle (#24)
InfiniFrameWindowTestUtility.Dispose()now tracks and waits for the message loopTaskbefore proceeding, preventingMessageLoopStateleaks between tests[SkipOnWindows]from ContextMenu and DevTools tests (transport connection issue was caused by the lifecycle bug)Related Issues
Checklist