diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index bf96e1e6c..be4103f77 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -353,6 +353,7 @@ pub const Surface = struct { win.setScrollCallback(scrollCallback); win.setCursorPosCallback(cursorPosCallback); win.setMouseButtonCallback(mouseButtonCallback); + win.setDropCallback(dropCallback); // Build our result self.* = .{ @@ -964,4 +965,39 @@ pub const Surface = struct { return; }; } + + fn dropCallback(window: glfw.Window, paths: [][*:0]const u8) void { + const tracy = trace(@src()); + defer tracy.end(); + + const surface = window.getUserPointer(CoreSurface) orelse return; + + var list = std.ArrayList(u8).init(surface.alloc); + defer list.deinit(); + + for (paths) |path| { + const path_slice = std.mem.span(path); + + // preallocate worst case of escaping every char + space + list.ensureTotalCapacity(path_slice.len * 2 + 1) catch |err| { + log.err("error in drop callback err={}", .{err}); + return; + }; + + const writer = list.writer(); + for (path_slice) |c| { + if (std.mem.indexOfScalar(u8, "\\ ()[]{}<>\"'`!#$&;|*?\t", c)) |_| { + writer.print("\\{c}", .{c}) catch unreachable; // memory preallocated + } else writer.writeByte(c) catch unreachable; // same here + } + writer.writeByte(' ') catch unreachable; // separate paths + + surface.textCallback(list.items) catch |err| { + log.err("error in drop callback err={}", .{err}); + return; + }; + + list.clearRetainingCapacity(); // avoid unnecessary reallocations + } + } };