|
|
@@ -167,6 +167,11 @@ struct LauncherRootView: View {
|
|
|
.padding(.horizontal, 10)
|
|
|
.padding(.top, 14)
|
|
|
.padding(.bottom, 8)
|
|
|
+ .overlay(alignment: .top) {
|
|
|
+ WindowDragHandle()
|
|
|
+ .frame(height: 6)
|
|
|
+ .padding(.horizontal, 12)
|
|
|
+ }
|
|
|
}
|
|
|
.sheet(item: $selectedApp) { app in
|
|
|
AppDetailView(app: app)
|
|
|
@@ -530,6 +535,24 @@ struct LauncherRootView: View {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/// Dedicated drag strip so the window remains movable while text fields stay fully interactive.
|
|
|
+private struct WindowDragHandle: NSViewRepresentable {
|
|
|
+ func makeNSView(context: Context) -> DragHandleView {
|
|
|
+ let view = DragHandleView()
|
|
|
+ view.wantsLayer = true
|
|
|
+ view.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
+ return view
|
|
|
+ }
|
|
|
+
|
|
|
+ func updateNSView(_ nsView: DragHandleView, context: Context) {}
|
|
|
+}
|
|
|
+
|
|
|
+private final class DragHandleView: NSView {
|
|
|
+ override func mouseDown(with event: NSEvent) {
|
|
|
+ window?.performDrag(with: event)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
private struct TileReorderDropDelegate: DropDelegate {
|
|
|
let destinationAppID: UUID
|
|
|
@Binding var draggedAppID: UUID?
|