Fix for windows
This commit is contained in:
+107
-49
@@ -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
@@ -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);
|
||||
|
||||
@@ -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()}");
|
||||
|
||||
Reference in New Issue
Block a user