Skip to content

Instantly share code, notes, and snippets.

@tyirvine
Created June 14, 2021 21:02
Show Gist options
  • Save tyirvine/93ee7b4d6f44ee333cdfc5f419f11389 to your computer and use it in GitHub Desktop.
Save tyirvine/93ee7b4d6f44ee333cdfc5f419f11389 to your computer and use it in GitHub Desktop.
This registers clicks on a view in SwiftUI even when the window is not key or main
//
// InactiveWindowTapHelper.swift
//
// Created by Ty Irvine on 2021-06-14.
//
// This registers clicks on a view in SwiftUI even when the window is not key or main.
//
// Usage ⤵︎
/*
Text("Hello world!")
.inactiveWindowTap { pressed in
print(pressed)
}
*/
import Foundation
import SwiftUI
extension View {
func inactiveWindowTap(_ pressed: @escaping (Bool) -> Void) -> some View {
modifier(InactiveWindowTapModifier(pressed))
}
}
struct InactiveWindowTapModifier: ViewModifier {
let pressed: (Bool) -> Void
init(_ pressed: @escaping (Bool) -> Void) {
self.pressed = pressed
}
func body(content: Content) -> some View {
content.overlay(
GeometryReader { proxy in
ClickableViewRepresentable(
pressed: pressed,
frame: proxy.frame(in: .global)
)
}
)
}
}
private struct ClickableViewRepresentable: NSViewRepresentable {
let pressed: (Bool) -> Void
let frame: NSRect
func updateNSView(_ nsView: ClickableView, context: Context) {
nsView.pressed = pressed
}
func makeNSView(context: Context) -> ClickableView {
ClickableView(frame: frame, pressed: pressed)
}
}
class ClickableView: NSView {
public var pressed: ((Bool) -> Void)?
init(frame: NSRect, pressed: ((Bool) -> Void)?) {
super.init(frame: frame)
self.pressed = pressed
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
return true
}
override func mouseDown(with event: NSEvent) {
pressed?(true)
}
override func mouseUp(with event: NSEvent) {
pressed?(false)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment