Skip to content

Instantly share code, notes, and snippets.

@sindresorhus
Last active April 21, 2022 18:22
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sindresorhus/e3ec0d4760aa85b0d1978121a3d5eddc to your computer and use it in GitHub Desktop.
Save sindresorhus/e3ec0d4760aa85b0d1978121a3d5eddc to your computer and use it in GitHub Desktop.
Creates a NSStatusBarButton with proxy methods for the NSStatusItem methods, so you don't have to deal with that class anymore. Most of the NSStatusItem properties are deprecated, so it's much nicer to deal with the NSStatusBarButton directly.
final class AssociatedObject<T: Any> {
subscript(index: Any) -> T? {
get {
return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T?
} set {
objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
extension NSStatusBar {
static func statusItem(withLength length: CGFloat = NSSquareStatusItemLength) -> NSStatusItem {
return system().statusItem(withLength: length)
}
}
extension NSStatusBarButton {
private struct AssociatedKeys {
static var statusItemHolder = AssociatedObject<NSStatusItem>()
}
var statusBar: NSStatusBar {
return NSStatusBar.system()
}
var length: CGFloat {
get {
return statusItem.length
}
set {
statusItem.length = newValue
}
}
override open var menu: NSMenu? {
get {
return statusItem.menu
}
set {
statusItem.menu = newValue
}
}
var statusItem: NSStatusItem {
get {
return AssociatedKeys.statusItemHolder[self]!
}
set {
AssociatedKeys.statusItemHolder[self] = newValue
}
}
}
/// Creates a NSStatusBarButton with proxy methods for the NSStatusItem methods, so you don't have to deal with that class anymore. Most of the NSStatusItem properties are deprecated, so it's much nicer to deal with the NSStatusBarButton directly.
func StatusBarButton() -> NSStatusBarButton {
let statusItem = NSStatusBar.statusItem()
statusItem.isVisible = true
statusItem.behavior = [.removalAllowed, .terminationOnRemoval]
let button = statusItem.button!
button.statusItem = statusItem
return button
}
func main() {
let statusBarButton = StatusBarButton()
statusBarButton.menu = NSMenu()
statusBarButton.image = #imageLiteral(resourceName: "menubar-icon")
}
@Kentzo
Copy link

Kentzo commented Jul 6, 2018

That is butchering :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment