From 0078248ae6562ce13564a789875b5d8e113ee385 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sat, 14 Mar 2026 19:00:57 -0600 Subject: [PATCH 1/3] frameless fix and add pixel input scaling --- src/figdraw/windowing/siwinshim.nim | 87 ++++++++++++++++++----------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/src/figdraw/windowing/siwinshim.nim b/src/figdraw/windowing/siwinshim.nim index ff86b2f..6fbdad6 100644 --- a/src/figdraw/windowing/siwinshim.nim +++ b/src/figdraw/windowing/siwinshim.nim @@ -212,7 +212,10 @@ proc newSiwinWindow*( vkCtx.instanceHandle(), size = size, title = title, + resizable = resizable, fullscreen = fullscreen, + frameless = frameless, + transparent = transparent, ) if fullscreen: result.fullscreen = true @@ -239,8 +242,20 @@ proc backingSize*(window: Window): IVec2 = else: window.size +proc inputUsesBackingPixels*(window: Window): bool = + when defined(macosx): + not window.isNil + elif defined(linux) or defined(bsd): + window of siWaylandWindow.WindowWayland + else: + false + proc logicalSize*(window: Window): Vec2 = - vec2(window.backingSize()).descaled() + if window.isNil: + return vec2(0.0'f32, 0.0'f32) + if window.inputUsesBackingPixels(): + return vec2(window.backingSize()).descaled() + vec2(window.size) proc contentScale*(window: Window): float32 = when defined(macosx): @@ -337,42 +352,50 @@ proc setupBackend*(renderer: FigRenderer, window: Window) = raise exc when UseVulkanBackend: if renderer.backendKind() == rbVulkan: - let vkCtx = renderer.ctx.VulkanContext - var hasPresentTarget = false - when defined(linux) or defined(bsd): - if window of siX11Window.WindowX11SoftwareRendering: - siX11Window.WindowX11SoftwareRendering(window).setSoftwarePresentEnabled( - false - ) - let surface = window.vulkanSurface() - if not surface.isNil: + try: + let vkCtx = renderer.ctx.VulkanContext + var hasPresentTarget = false when defined(linux) or defined(bsd): - if window of siWaylandWindow.WindowWayland: - vkCtx.setExternalSurface( - surface, presentTargetWayland, ownedByContext = true + if window of siX11Window.WindowX11SoftwareRendering: + siX11Window.WindowX11SoftwareRendering(window).setSoftwarePresentEnabled( + false ) + let surface = window.vulkanSurface() + if not surface.isNil: + when defined(linux) or defined(bsd): + if window of siWaylandWindow.WindowWayland: + vkCtx.setExternalSurface( + surface, presentTargetWayland, ownedByContext = true + ) + hasPresentTarget = true + else: + vkCtx.setExternalSurface( + surface, presentTargetXlib, ownedByContext = true + ) + hasPresentTarget = true + elif defined(windows): + vkCtx.setExternalSurface(surface, presentTargetWin32, ownedByContext = true) hasPresentTarget = true - else: - vkCtx.setExternalSurface(surface, presentTargetXlib, ownedByContext = true) + elif defined(macosx): + vkCtx.setExternalSurface(surface, presentTargetMetal, ownedByContext = true) hasPresentTarget = true - elif defined(windows): - vkCtx.setExternalSurface(surface, presentTargetWin32, ownedByContext = true) - hasPresentTarget = true - elif defined(macosx): - vkCtx.setExternalSurface(surface, presentTargetMetal, ownedByContext = true) - hasPresentTarget = true - when defined(linux) or defined(bsd): - if surface.isNil and window of siX11Window.WindowX11: - let x11Window = siX11Window.WindowX11(window) - vkCtx.setPresentXlibTarget( - x11Window.nativeDisplayHandle(), x11Window.nativeWindowHandle() + when defined(linux) or defined(bsd): + if surface.isNil and window of siX11Window.WindowX11: + let x11Window = siX11Window.WindowX11(window) + vkCtx.setPresentXlibTarget( + x11Window.nativeDisplayHandle(), x11Window.nativeWindowHandle() + ) + hasPresentTarget = true + if not hasPresentTarget: + raise newException( + ValueError, + "Vulkan present target unavailable for this siwin window (Wayland/X11 mismatch)", ) - hasPresentTarget = true - if not hasPresentTarget: - raise newException( - ValueError, - "Vulkan present target unavailable for this siwin window (Wayland/X11 mismatch)", - ) + except CatchableError as exc: + when UseOpenGlFallback: + renderer.useOpenGlFallback(exc.msg) + else: + raise exc proc beginFrame*(renderer: FigRenderer[SiwinRenderBackend]) = ## Per-frame pre-render backend maintenance. From ec36eb07a88cc120678bc93fb12edc3f1d7fe47e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sat, 14 Mar 2026 19:01:42 -0600 Subject: [PATCH 2/3] frameless fix and add pixel input scaling --- src/figdraw/windowing/siwinshim.nim | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/figdraw/windowing/siwinshim.nim b/src/figdraw/windowing/siwinshim.nim index 6fbdad6..8a82de6 100644 --- a/src/figdraw/windowing/siwinshim.nim +++ b/src/figdraw/windowing/siwinshim.nim @@ -250,11 +250,21 @@ proc inputUsesBackingPixels*(window: Window): bool = else: false +proc inputDeviceScale*(window: Window): float32 = + if window.isNil: + return 1.0'f32 + let scale = window.contentScale() + if scale > 0.0'f32: + return scale + 1.0'f32 + proc logicalSize*(window: Window): Vec2 = if window.isNil: return vec2(0.0'f32, 0.0'f32) if window.inputUsesBackingPixels(): - return vec2(window.backingSize()).descaled() + let scale = window.inputDeviceScale() + let backing = window.backingSize() + return vec2(backing.x.float32 / scale, backing.y.float32 / scale) vec2(window.size) proc contentScale*(window: Window): float32 = From c3453b48e0287ba8050097534f25288462b9b2bf Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sat, 14 Mar 2026 20:52:28 -0600 Subject: [PATCH 3/3] frameless fix and add pixel input scaling --- src/figdraw/windowing/siwinshim.nim | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/figdraw/windowing/siwinshim.nim b/src/figdraw/windowing/siwinshim.nim index 8a82de6..2482f7c 100644 --- a/src/figdraw/windowing/siwinshim.nim +++ b/src/figdraw/windowing/siwinshim.nim @@ -250,13 +250,7 @@ proc inputUsesBackingPixels*(window: Window): bool = else: false -proc inputDeviceScale*(window: Window): float32 = - if window.isNil: - return 1.0'f32 - let scale = window.contentScale() - if scale > 0.0'f32: - return scale - 1.0'f32 +proc inputDeviceScale*(window: Window): float32 proc logicalSize*(window: Window): Vec2 = if window.isNil: @@ -286,6 +280,14 @@ proc contentScale*(window: Window): float32 = else: 1.0 +proc inputDeviceScale*(window: Window): float32 = + if window.isNil: + return 1.0'f32 + let scale = window.contentScale() + if scale > 0.0'f32: + return scale + 1.0'f32 + proc configureUiScale*(window: Window, envVar = "HDI"): bool = ## Returns true when scale should track contentScale (auto mode). let hdiEnv = getEnv(envVar)