Fix for windows

This commit is contained in:
2026-07-26 00:44:17 -05:00
parent f932a7704b
commit 9dbabcd89b
3 changed files with 168 additions and 54 deletions
+107 -49
View File
@@ -97,11 +97,14 @@ public unsafe static class ImGuiSDL3Platform
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
// We will use MouseCanReportHoveredViewport to set HasMouseHoveredViewport dynamically each frame.
#if __APPLE__
data.MouseCanReportHoveredViewport = false;
#else
data.MouseCanReportHoveredViewport = data.MouseCanUseGlobalState;
#endif
if (OperatingSystem.IsMacOS())
{
data.MouseCanReportHoveredViewport = false;
}
else
{
data.MouseCanReportHoveredViewport = data.MouseCanUseGlobalState;
}
ImGuiPlatformIOPtr platformIo = ImGui.GetPlatformIO();
platformIo.PlatformGetClipboardTextFn = DelegateStorage.GetClipboardDelegate.GetPtrForDelegate();
@@ -148,9 +151,10 @@ public unsafe static class ImGuiSDL3Platform
io.DisplaySize = size;
io.DisplayFramebufferScale = framebufferScale;
#if WIN32
data.WantUpdateMonitors = true;
#endif
if (OperatingSystem.IsWindows())
{
data.WantUpdateMonitors = true;
}
if (data.WantUpdateMonitors)
UpdateMonitors();
@@ -213,15 +217,20 @@ public unsafe static class ImGuiSDL3Platform
if (SDL.GetWindowFlags(window).HasFlag(SDL.WindowFlags.Minimized))
w = h = 0;
#if __APPLE__
// SDL_GetWindowDisplayScale() seems more reliable during resolution changes e.g. going fullscreen (#8703, #4414)
float fbScaleX = SDL.GetWindowDisplayScale(window);
float fbScaleY = fbScaleX;
#else
SDL.GetWindowSizeInPixels(window, out int displayW, out int displayH);
float fbScaleX = w > 0 ? displayW / (float)w : 1.0f;
float fbScaleY = h > 0 ? displayH / (float)h : 1.0f;
#endif
float fbScaleX;
float fbScaleY;
if (OperatingSystem.IsMacOS())
{
// SDL_GetWindowDisplayScale() seems more reliable during resolution changes e.g. going fullscreen (#8703, #4414)
fbScaleX = SDL.GetWindowDisplayScale(window);
fbScaleY = fbScaleX;
}
else
{
SDL.GetWindowSizeInPixels(window, out int displayW, out int displayH);
fbScaleX = w > 0 ? displayW / (float)w : 1.0f;
fbScaleY = h > 0 ? displayH / (float)h : 1.0f;
}
out_size = new Vector2(w, h);
out_framebuffer_scale = new Vector2(fbScaleX, fbScaleY);
@@ -812,10 +821,7 @@ public unsafe static class ImGuiSDL3Platform
platformIO.PlatformDestroyWindow = DelegateStorage.DestroyWindowDelegate.GetPtrForDelegate();
platformIO.PlatformShowWindow = DelegateStorage.ShowWindowDelegate.GetPtrForDelegate();
platformIO.PlatformSetWindowPos = DelegateStorage.SetWindowPosDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowPos = DelegateStorage.GetWindowPosDelegate.GetPtrForDelegate();
platformIO.PlatformSetWindowSize = DelegateStorage.SetWindowSizeDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowSize = DelegateStorage.GetWindowSizeDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowFramebufferScale = DelegateStorage.GetWindowFramebufferScaleDelegate.GetPtrForDelegate();
platformIO.PlatformSetWindowFocus = DelegateStorage.SetWindowFocusDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowFocus = DelegateStorage.GetWindowFocusDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowMinimized = DelegateStorage.GetWindowMinimizedDelegate.GetPtrForDelegate();
@@ -825,6 +831,19 @@ public unsafe static class ImGuiSDL3Platform
platformIO.PlatformRenderWindow = DelegateStorage.RenderWindowDelegate.GetPtrForDelegate();
platformIO.PlatformSwapBuffers = DelegateStorage.SwapBuffersDelegate.GetPtrForDelegate();
if (OperatingSystem.IsWindows())
{
platformIO.PlatformGetWindowPos = DelegateStorage.GetWindowPosWindowsDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowSize = DelegateStorage.GetWindowSizeWindowsDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowFramebufferScale = DelegateStorage.GetWindowFramebufferScaleWindowsDelegate.GetPtrForDelegate();
}
else
{
platformIO.PlatformGetWindowPos = DelegateStorage.GetWindowPosDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowSize = DelegateStorage.GetWindowSizeDelegate.GetPtrForDelegate();
platformIO.PlatformGetWindowFramebufferScale = DelegateStorage.GetWindowFramebufferScaleDelegate.GetPtrForDelegate();
}
// Register main window handle (owned by the main application, not by us).
// This is mostly for simplicity and consistency so that our code (e.g. mouse handling) can use
// the same logic for main and secondary viewports.
@@ -840,13 +859,14 @@ public unsafe static class ImGuiSDL3Platform
mainViewport.PlatformUserData = ImGuiUserData<ViewPortData>.Store(vd);
mainViewport.PlatformHandle = (void*)(nint)vd.WindowID;
#if WINDOWS
mainViewport.PlatformHandleRaw = SDL.GetPointerProperty(
SDL.GetWindowProperties(window),
SDL.Properties.WindowWin32HWNDPointer,
nint.Zero
).ToPointer();
#endif
if (OperatingSystem.IsWindows())
{
mainViewport.PlatformHandleRaw = SDL.GetPointerProperty(
SDL.GetWindowProperties(window),
SDL.Props.WindowWin32HWNDPointer,
nint.Zero
).ToPointer();
}
}
public static ImGuiViewportPtr? GetViewportForWindowId(uint id)
@@ -863,11 +883,19 @@ public unsafe static class ImGuiSDL3Platform
{
viewport.PlatformHandle = (void*)(nint)SDL.GetWindowID(window);
viewport.PlatformHandleRaw = (void*)nint.Zero;
#if _WIN32 && !__WINTR__
viewport.PlatformHandleRaw = SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowWin32HWNDPointer, 0).ToPointer();
#elif __APPLE__ && SDL_VIDEO_DRIVER_COCOA
viewport.PlatformHandleRaw = SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowCocoaWindow, 0).ToPointer();
#endif
if (OperatingSystem.IsWindows())
{
viewport.PlatformHandleRaw = SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowWin32HWNDPointer, 0).ToPointer();
}
else if (OperatingSystem.IsMacOS() && SDL.GetHint("SDL_VIDEO_DRIVER_COCOA") != null)
{
viewport.PlatformHandleRaw = SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowCocoaWindowPointer, 0).ToPointer();
}
// #if _WIN32 && !__WINTR__
// viewport.PlatformHandleRaw = SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowWin32HWNDPointer, 0).ToPointer();
// #elif __APPLE__ && SDL_VIDEO_DRIVER_COCOA
// viewport.PlatformHandleRaw = SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowCocoaWindow, 0).ToPointer();
// #endif
}
public static void Dispose()
@@ -965,6 +993,8 @@ public unsafe static class ImGuiSDL3Platform
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Vector2 ViewportCallbackGetVec2(ImGuiViewportPtr ctx);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Vector2* ViewportCallbackGetVec2Windows(Vector2* result, ImGuiViewportPtr ctx);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool ViewportCallbackBool(ImGuiViewportPtr ctx);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void ViewportCallbackSetString(ImGuiViewportPtr ctx, string title);
@@ -1018,10 +1048,12 @@ public unsafe static class ImGuiSDL3Platform
vd.Window = SDL.CreateWindow("No Title Yet", (int)viewport.Size.X, (int)viewport.Size.Y, flags);
vd.WindowID = SDL.GetWindowID(vd.Window);
#if !__APPLE__ // On Mac, SDL3 parenting appears to prevent viewport from appearing on another monitor
if (vd.ParentWindow != nint.Zero)
SDL.SetWindowParent(vd.Window, vd.ParentWindow);
#endif
if (!OperatingSystem.IsMacOS()) // On Mac, SDL3 parenting appears to prevent viewport from appearing on another monitor
{
if (vd.ParentWindow != nint.Zero)
SDL.SetWindowParent(vd.Window, vd.ParentWindow);
}
SDL.SetWindowPosition(vd.Window, (int)viewport.Pos.X, (int)viewport.Pos.Y);
vd.WindowOwned = true;
@@ -1037,13 +1069,14 @@ public unsafe static class ImGuiSDL3Platform
Program.Logger.Log($"New SDL Viewport: {vd.Window} {vd.WindowID} {viewport.Pos.X} {viewport.Pos.Y} {viewport.Size.X} {viewport.Size.Y}");
#if WINDOWS
viewport.PlatformHandleRaw = SDL.GetPointerProperty(
SDL.GetWindowProperties(vd.Window),
SDL.Properties.WindowWin32HWNDPointer,
nint.Zero
).ToPointer();
#endif
if (OperatingSystem.IsWindows())
{
viewport.PlatformHandleRaw = SDL.GetPointerProperty(
SDL.GetWindowProperties(vd.Window),
SDL.Props.WindowWin32HWNDPointer,
nint.Zero
).ToPointer();
}
}
internal static readonly ViewportCallback DestroyWindowDelegate = DestroyWindow;
@@ -1071,12 +1104,16 @@ public unsafe static class ImGuiSDL3Platform
{
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
#if __APPLE__
// On macOS new windows should always appear on top so they aren't hidden under existing ones.
SDL.SetHint(SDL.Hints.WindowActivateWhenShown, "1");
#else
SDL.SetHint(SDL.Hints.WindowActivateWhenShown, (viewport.Flags & ImGuiViewportFlags.NoFocusOnAppearing) != 0 ? "0" : "1");
#endif
if (OperatingSystem.IsMacOS())
{
// On macOS new windows should always appear on top so they aren't hidden under existing ones.
SDL.SetHint(SDL.Hints.WindowActivateWhenShown, "1");
}
else
{
SDL.SetHint(SDL.Hints.WindowActivateWhenShown, (viewport.Flags & ImGuiViewportFlags.NoFocusOnAppearing) != 0 ? "0" : "1");
}
SDL.ShowWindow(vd.Window);
}
@@ -1120,6 +1157,13 @@ public unsafe static class ImGuiSDL3Platform
return new Vector2(x, y);
}
internal static readonly ViewportCallbackGetVec2Windows GetWindowPosWindowsDelegate = GetWindowPosWindows;
private static Vector2* GetWindowPosWindows(Vector2* result, ImGuiViewportPtr viewport)
{
*result = GetWindowPos(viewport);
return result;
}
internal static readonly ViewportCallbackSetVec2 SetWindowSizeDelegate = SetWindowSize;
private static void SetWindowSize(ImGuiViewportPtr viewport, Vector2 size)
{
@@ -1135,6 +1179,13 @@ public unsafe static class ImGuiSDL3Platform
return new Vector2(w, h);
}
internal static readonly ViewportCallbackGetVec2Windows GetWindowSizeWindowsDelegate = GetWindowSizeWindows;
private static Vector2* GetWindowSizeWindows(Vector2* result, ImGuiViewportPtr viewport)
{
*result = GetWindowSize(viewport);
return result;
}
internal static readonly ViewportCallbackGetVec2 GetWindowFramebufferScaleDelegate = GetWindowFramebufferScale;
private static Vector2 GetWindowFramebufferScale(ImGuiViewportPtr viewport)
{
@@ -1143,6 +1194,13 @@ public unsafe static class ImGuiSDL3Platform
return framebufferScale;
}
internal static readonly ViewportCallbackGetVec2Windows GetWindowFramebufferScaleWindowsDelegate = GetWindowFramebufferScaleWindows;
private static Vector2* GetWindowFramebufferScaleWindows(Vector2* result, ImGuiViewportPtr viewport)
{
*result = GetWindowFramebufferScale(viewport);
return result;
}
internal static readonly ViewportCallback SetWindowFocusDelegate = SetWindowFocus;
private static void SetWindowFocus(ImGuiViewportPtr viewport)
{
+58 -5
View File
@@ -105,7 +105,60 @@ public sealed unsafe class OpenGLTexture : IDisposable
}
}
public static OpenGLTexture FromBgra32(GL gl, nint pixels, int width, int height, int stride)
{
if (pixels == nint.Zero)
{
throw new ArgumentException("Pixels cannot be null.", nameof(pixels));
}
uint texture = CreateTexture(gl, pixels, width, height, stride, GLPixelFormat.Bgra);
return new OpenGLTexture(gl, texture, width, height);
}
public static OpenGLTexture FromHandle(GL gl, uint handle, int width, int height)
{
if (handle == 0)
{
throw new ArgumentException("Texture handle cannot be zero.", nameof(handle));
}
return new OpenGLTexture(gl, handle, width, height);
}
public void UpdateBgra32(nint pixels, int stride)
{
if (pixels == nint.Zero)
{
throw new ArgumentException("Pixels cannot be null.", nameof(pixels));
}
_gl.GetIntegerv(GLGetPName.TextureBinding2D, out int previousTexture);
_gl.BindTexture(GLTextureTarget.Texture2D, Handle);
_gl.PixelStorei(GLPixelStoreParameter.UnpackAlignment, 1);
_gl.PixelStorei(GLPixelStoreParameter.UnpackRowLength, stride / 4);
_gl.TexSubImage2D(
GLTextureTarget.Texture2D,
0,
0,
0,
Width,
Height,
GLPixelFormat.Bgra,
GLPixelType.UnsignedByte,
pixels);
_gl.PixelStorei(GLPixelStoreParameter.UnpackRowLength, 0);
_gl.BindTexture(GLTextureTarget.Texture2D, (uint)previousTexture);
}
private static uint UploadRgba32(GL gl, SDL.Surface* surface)
{
return CreateTexture(gl, surface->Pixels, surface->Width, surface->Height, surface->Pitch, GLPixelFormat.Rgba);
}
private static uint CreateTexture(GL gl, nint pixels, int width, int height, int stride, GLPixelFormat pixelFormat)
{
uint texture = 0;
gl.GenTextures(1, ref texture);
@@ -119,17 +172,17 @@ public sealed unsafe class OpenGLTexture : IDisposable
gl.TexParameteri(GLTextureTarget.Texture2D, GLTextureParameterName.WrapT, (int)GLEnum.ClampToEdge);
gl.PixelStorei(GLPixelStoreParameter.UnpackAlignment, 1);
gl.PixelStorei(GLPixelStoreParameter.UnpackRowLength, surface->Pitch / 4);
gl.PixelStorei(GLPixelStoreParameter.UnpackRowLength, stride / 4);
gl.TexImage2D(
GLTextureTarget.Texture2D,
0,
GLInternalFormat.Rgba,
surface->Width,
surface->Height,
width,
height,
0,
GLPixelFormat.Rgba,
pixelFormat,
GLPixelType.UnsignedByte,
surface->Pixels);
pixels);
gl.PixelStorei(GLPixelStoreParameter.UnpackRowLength, 0);
gl.BindTexture(GLTextureTarget.Texture2D, (uint)previousTexture);
+3
View File
@@ -42,7 +42,10 @@ public sealed unsafe class SDL3Window : IDisposable
public SDL3Window(string name, int posX, int posY, int width, int height, SDL.WindowFlags flags = SDL.WindowFlags.Resizable | SDL.WindowFlags.HighPixelDensity)
{
if (OperatingSystem.IsLinux())
{
SDL.SetHint(SDL.Hints.VideoDriver, "x11");
SDL.SetHint(SDL.Hints.VideoForceEGL, "1");
}
if (!SDL.Init(SDL.InitFlags.Events | SDL.InitFlags.Video | SDL.InitFlags.Gamepad))
throw new Exception($"SDL_Init failed: {SDL.GetError()}");