diff --git a/build.zig b/build.zig
index aaa3ca7..1ca61cb 100644
--- a/build.zig
+++ b/build.zig
@@ -241,7 +241,11 @@ pub fn build(b: *std.Build) void {
                     "libs/imgui/backends/imgui_impl_glfw.cpp",
                     "libs/imgui/backends/imgui_impl_wgpu.cpp",
                 },
-                .flags = cflags,
+                .flags = &(cflags.* ++ .{
+                    "-DGLFW_INCLUDE_NONE",
+                    // TODO: This should be IMGUI_IMPL_WEBGPU_BACKEND_DAWN but we're using an old version of Dawn that looks more like wgpu_native
+                    "-DIMGUI_IMPL_WEBGPU_BACKEND_WGPU",
+                }),
             });
         },
         .glfw_opengl3 => {
@@ -265,7 +269,7 @@ pub fn build(b: *std.Build) void {
                     "libs/imgui/backends/imgui_impl_glfw.cpp",
                     "libs/imgui/backends/imgui_impl_dx12.cpp",
                 },
-                .flags = cflags,
+                .flags = &(cflags.* ++ .{"-DGLFW_INCLUDE_NONE"}),
             });
             imgui.linkSystemLibrary("d3dcompiler_47");
         },
diff --git a/libs/imgui/backends/imgui_impl_glfw.cpp b/libs/imgui/backends/imgui_impl_glfw.cpp
index 796bad7..7a0b1f5 100644
--- a/libs/imgui/backends/imgui_impl_glfw.cpp
+++ b/libs/imgui/backends/imgui_impl_glfw.cpp
@@ -90,8 +90,7 @@
 
 #include "imgui.h"
 #ifndef IMGUI_DISABLE
-// FIX(zig-gamedev):
-// #include "imgui_impl_glfw.h"
+#include "imgui_impl_glfw.h"
 
 // Clang warnings with -Weverything
 #if defined(__clang__)
@@ -101,8 +100,6 @@
 #endif
 
 // GLFW
-// FIX(zig-gamedev):
-#define GLFW_INCLUDE_NONE
 #include <GLFW/glfw3.h>
 
 #ifdef _WIN32
@@ -160,41 +157,6 @@
 #define GLFW_HAS_GAMEPAD_API            (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
 #define GLFW_HAS_GETKEYNAME             (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
 #define GLFW_HAS_GETERROR               (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
-#include <math.h>
-
-// FIX(zig-gamedev):
-extern "C" {
-
-bool     ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
-bool     ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
-bool     ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
-void     ImGui_ImplGlfw_Shutdown();
-void     ImGui_ImplGlfw_NewFrame();
-
-// GLFW callbacks install
-// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
-// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
-void     ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window);
-void     ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window);
-
-// GFLW callbacks options:
-// - Set 'chain_for_all_windows=true' to enable chaining callbacks for all windows (including secondary viewports created by backends or by user)
-void     ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows);
-
-// GLFW callbacks (individual callbacks to call yourself if you didn't install callbacks)
-void     ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused);        // Since 1.84
-void     ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered);        // Since 1.84
-void     ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y);   // Since 1.87
-void     ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
-void     ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
-void     ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
-void     ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
-void     ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
-
-// GLFW helpers
-void     ImGui_ImplGlfw_Sleep(int milliseconds);
-
-} // extern "C"
 
 // GLFW data
 enum GlfwClientApi
@@ -218,8 +180,6 @@ struct ImGui_ImplGlfw_Data
     bool                    InstalledCallbacks;
     bool                    CallbacksChainForAllWindows;
     bool                    WantUpdateMonitors;
-
-    ImVec2                  DpiScale; // fix(zig-gamedev)
 #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
     const char*             CanvasSelector;
 #endif
@@ -510,7 +470,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
 {
     ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
     if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
-        bd->PrevUserCallbackCursorPos(window, x * bd->DpiScale.x, y * bd->DpiScale.y); // fix(zig-gamedev)
+        bd->PrevUserCallbackCursorPos(window, x, y);
 
     ImGuiIO& io = ImGui::GetIO();
     if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
@@ -520,8 +480,8 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
         x += window_x;
         y += window_y;
     }
-    io.AddMousePosEvent((float)x * bd->DpiScale.x, (float)y * bd->DpiScale.y); // fix(zig-gamedev)
-    bd->LastValidMousePos = ImVec2((float)x * bd->DpiScale.x, (float)y * bd->DpiScale.y); // fix(zig-gamedev)
+    io.AddMousePosEvent((float)x, (float)y);
+    bd->LastValidMousePos = ImVec2((float)x, (float)y);
 }
 
 // Workaround: X11 seems to send spurious Leave/Enter events which would make us lose our position,
@@ -668,8 +628,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
     bd->Time = 0.0;
     bd->WantUpdateMonitors = true;
 
-    bd->DpiScale = ImVec2{ 1.0f, 1.0f }; // fix(zig-gamedev)
-
     ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
     platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); };
     platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(nullptr); };
@@ -837,8 +795,8 @@ static void ImGui_ImplGlfw_UpdateMouseData()
                     mouse_x += window_x;
                     mouse_y += window_y;
                 }
-                bd->LastValidMousePos = ImVec2((float)mouse_x * bd->DpiScale.x, (float)mouse_y * bd->DpiScale.y); // fix(zig-gamedev)
-                io.AddMousePosEvent((float)mouse_x * bd->DpiScale.x, (float)mouse_y * bd->DpiScale.y); // fix(zig-gamedev)
+                bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
+                io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
             }
         }
 
@@ -1007,11 +965,6 @@ void ImGui_ImplGlfw_NewFrame()
     io.DisplaySize = ImVec2((float)w, (float)h);
     if (w > 0 && h > 0)
         io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
-
-    // fix(zig-gamedev)
-    bd->DpiScale.x = ceil(io.DisplayFramebufferScale.x);
-    bd->DpiScale.y = ceil(io.DisplayFramebufferScale.y);
-
     if (bd->WantUpdateMonitors)
         ImGui_ImplGlfw_UpdateMonitors();
 
diff --git a/libs/imgui/backends/imgui_impl_glfw.h b/libs/imgui/backends/imgui_impl_glfw.h
index 16930d1..f833b31 100644
--- a/libs/imgui/backends/imgui_impl_glfw.h
+++ b/libs/imgui/backends/imgui_impl_glfw.h
@@ -11,7 +11,9 @@
 //  [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
 //  [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
 // Missing features or Issues:
-//  [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
+//  [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
+//  [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
+//  [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
 
 // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
 // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -29,11 +31,13 @@ struct GLFWwindow;
 struct GLFWmonitor;
 
 // Follow "Getting Started" link and check examples/ folder to learn about using backends!
-IMGUI_IMPL_API bool     ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
-IMGUI_IMPL_API bool     ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
-IMGUI_IMPL_API bool     ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
-IMGUI_IMPL_API void     ImGui_ImplGlfw_Shutdown();
-IMGUI_IMPL_API void     ImGui_ImplGlfw_NewFrame();
+extern "C" { // fix(zig-gamedev)
+  IMGUI_IMPL_API bool     ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
+  IMGUI_IMPL_API bool     ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
+  IMGUI_IMPL_API bool     ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
+  IMGUI_IMPL_API void     ImGui_ImplGlfw_Shutdown();
+  IMGUI_IMPL_API void     ImGui_ImplGlfw_NewFrame();
+};
 
 // Emscripten related initialization phase methods (call after ImGui_ImplGlfw_InitForOpenGL)
 #ifdef __EMSCRIPTEN__
diff --git a/libs/imgui/backends/imgui_impl_wgpu.cpp b/libs/imgui/backends/imgui_impl_wgpu.cpp
index b565c4d..12a9444 100644
--- a/libs/imgui/backends/imgui_impl_wgpu.cpp
+++ b/libs/imgui/backends/imgui_impl_wgpu.cpp
@@ -45,9 +45,6 @@
 // When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
 // or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
 
-// FIX(zig-gamedev)
-#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
-
 #ifndef __EMSCRIPTEN__
     #if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
     #error exactly one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be defined!
@@ -61,8 +58,7 @@
 #include "imgui.h"
 #ifndef IMGUI_DISABLE
 
-// FIX(zig-gamedev):
-// #include "imgui_impl_wgpu.h"
+#include "imgui_impl_wgpu.h"
 
 #include <limits.h>
 #include <webgpu/webgpu.h>
@@ -71,47 +67,6 @@
 extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
 #define MEMALIGN(_SIZE,_ALIGN)        (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1))    // Memory align (copied from IM_ALIGN() macro).
 
-// FIX(zig-gamedev): We removed header file and declare all our external functions here.
-extern "C" {
-
-// Initialization data, for ImGui_ImplWGPU_Init()
-struct ImGui_ImplWGPU_InitInfo
-{
-    WGPUDevice              Device;
-    int                     NumFramesInFlight = 3;
-    WGPUTextureFormat       RenderTargetFormat = WGPUTextureFormat_Undefined;
-    WGPUTextureFormat       DepthStencilFormat = WGPUTextureFormat_Undefined;
-    WGPUMultisampleState    PipelineMultisampleState = {};
-
-    ImGui_ImplWGPU_InitInfo()
-    {
-        PipelineMultisampleState.count = 1;
-        PipelineMultisampleState.mask = UINT32_MAX;
-        PipelineMultisampleState.alphaToCoverageEnabled = false;
-    }
-};
-
-// Follow "Getting Started" link and check examples/ folder to learn about using backends!
-IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info);
-IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown();
-IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
-IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
-
-// Use if you want to reset your rendering device without losing Dear ImGui state.
-IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
-IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
-
-// [BETA] Selected render state data shared with callbacks.
-// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplWGPU_RenderDrawData() call.
-// (Please open an issue if you feel you need access to more data)
-struct ImGui_ImplWGPU_RenderState
-{
-    WGPUDevice                  Device;
-    WGPURenderPassEncoder       RenderPassEncoder;
-};
-
-} // extern "C"
-
 // WebGPU data
 struct RenderResources
 {
@@ -399,7 +354,8 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
     }
 
     // Setup viewport
-    wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1);
+    // FIX(zig-gamedev): Clamp bounds to workaround WGPU on Vulkan validation error
+    wgpuRenderPassEncoderSetViewport(ctx, 0, 0, (float)(int)(draw_data->FramebufferScale.x * draw_data->DisplaySize.x), (float)(int)(draw_data->FramebufferScale.y * draw_data->DisplaySize.y), 0, 1);
 
     // Bind shader and vertex buffers
     wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
diff --git a/libs/imgui/backends/imgui_impl_wgpu.h b/libs/imgui/backends/imgui_impl_wgpu.h
index 0457a63..f5f84e0 100644
--- a/libs/imgui/backends/imgui_impl_wgpu.h
+++ b/libs/imgui/backends/imgui_impl_wgpu.h
@@ -8,9 +8,6 @@
 // This requirement will be removed once WebGPU stabilizes and backends converge on a unified interface.
 //#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN
 
-// FIX(zig-gamedev)
-#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
-
 // Implemented features:
 //  [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
 //  [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
@@ -32,6 +29,9 @@
 
 #include <webgpu/webgpu.h>
 
+// FIX(zig-gamedev)
+extern "C" {
+
 // Initialization data, for ImGui_ImplWGPU_Init()
 struct ImGui_ImplWGPU_InitInfo
 {
@@ -68,4 +68,7 @@ struct ImGui_ImplWGPU_RenderState
     WGPURenderPassEncoder       RenderPassEncoder;
 };
 
+// FIX(zig-gamedev)
+} // extern "C"
+
 #endif // #ifndef IMGUI_DISABLE
diff --git a/src/backend_glfw_wgpu.zig b/src/backend_glfw_wgpu.zig
index e6fa517..714b8fa 100644
--- a/src/backend_glfw_wgpu.zig
+++ b/src/backend_glfw_wgpu.zig
@@ -10,8 +10,6 @@ pub fn init(
     wgpu_swap_chain_format: u32, // wgpu.TextureFormat
     wgpu_depth_format: u32, // wgpu.TextureFormat
 ) void {
-    backend_glfw.init(window);
-
     var info = ImGui_ImplWGPU_InitInfo{
         .device = wgpu_device,
         .num_frames_in_flight = 1,
@@ -23,6 +21,8 @@ pub fn init(
     if (!ImGui_ImplWGPU_Init(&info)) {
         unreachable;
     }
+
+    backend_glfw.init(window);
 }
 
 pub fn deinit() void {
@@ -30,13 +30,18 @@ pub fn deinit() void {
     backend_glfw.deinit();
 }
 
-pub fn newFrame(fb_width: u32, fb_height: u32) void {
+var _width: u32 = 0;
+var _height: u32 = 0;
+pub fn newFrame(width: u32, height: u32) void {
+    if (width != _width or height != _height) {
+        ImGui_ImplWGPU_InvalidateDeviceObjects();
+        if (ImGui_ImplWGPU_CreateDeviceObjects()) {
+            _width = width;
+            _height = height;
+        }
+    }
     ImGui_ImplWGPU_NewFrame();
     backend_glfw.newFrame();
-
-    gui.io.setDisplaySize(@floatFromInt(fb_width), @floatFromInt(fb_height));
-    gui.io.setDisplayFramebufferScale(1.0, 1.0);
-
     gui.newFrame();
 }
 
@@ -61,7 +66,9 @@ pub const ImGui_ImplWGPU_InitInfo = extern struct {
 
 // Those functions are defined in 'imgui_impl_wgpu.cpp`
 // (they include few custom changes).
-extern fn ImGui_ImplWGPU_Init(init_info: *ImGui_ImplWGPU_InitInfo) bool;
-extern fn ImGui_ImplWGPU_NewFrame() void;
-extern fn ImGui_ImplWGPU_RenderDrawData(draw_data: *const anyopaque, pass_encoder: *const anyopaque) void;
-extern fn ImGui_ImplWGPU_Shutdown() void;
+extern fn ImGui_ImplWGPU_Init(init_info: *ImGui_ImplWGPU_InitInfo) callconv(.c) bool;
+extern fn ImGui_ImplWGPU_InvalidateDeviceObjects() callconv(.c) void;
+extern fn ImGui_ImplWGPU_CreateDeviceObjects() callconv(.c) bool;
+extern fn ImGui_ImplWGPU_NewFrame() callconv(.c) void;
+extern fn ImGui_ImplWGPU_RenderDrawData(draw_data: *const anyopaque, pass_encoder: *const anyopaque) callconv(.c) void;
+extern fn ImGui_ImplWGPU_Shutdown() callconv(.c) void;