8 changed files with 358 additions and 288 deletions
@ -0,0 +1,51 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// ZeroTier One
|
||||
//
|
||||
// Created by Grant Limberg on 8/7/16.
|
||||
// Copyright © 2016 ZeroTier, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h> |
||||
|
||||
@class NetworkMonitor; |
||||
@class Network; |
||||
@class NodeStatus; |
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate> |
||||
|
||||
@property (weak, nonatomic) IBOutlet NSWindow *window; |
||||
|
||||
@property (nonatomic) NSStatusItem *statusItem; |
||||
|
||||
@property (nonatomic) NSPopover *networkListPopover; |
||||
@property (nonatomic) NSPopover *joinNetworkPopover; |
||||
@property (nonatomic) NSPopover *preferencesPopover; |
||||
@property (nonatomic) NSPopover *aboutPopover; |
||||
|
||||
@property (nonatomic) id transientMonitor; |
||||
|
||||
@property (nonatomic) NetworkMonitor *monitor; |
||||
|
||||
@property (nonatomic) NSMutableArray<Network*> *networks; |
||||
|
||||
@property (nonatomic) NodeStatus *status; |
||||
|
||||
@property (nonatomic) NSPasteboard *pasteboard; |
||||
|
||||
- (void)buildMenu; |
||||
|
||||
- (void)onNetworkListUpdated:(NSNotification*)note; |
||||
- (void)onNodeStatusUpdated:(NSNotification*)note; |
||||
|
||||
- (void)showNetworks; |
||||
- (void)joinNetwork; |
||||
- (void)showPreferences; |
||||
- (void)showAbout; |
||||
- (void)quit; |
||||
- (void)toggleNetwork:(NSMenuItem*)sender; |
||||
- (void)copyNodeID; |
||||
- (void)menuWillOpen:(NSMenu*)menu; |
||||
- (void)menuDidClose:(NSMenu*)menu; |
||||
|
||||
@end |
||||
@ -0,0 +1,281 @@
|
||||
// |
||||
// AppDelegate.m |
||||
// ZeroTier One |
||||
// |
||||
// Created by Grant Limberg on 8/7/16. |
||||
// Copyright © 2016 ZeroTier, Inc. All rights reserved. |
||||
// |
||||
|
||||
#import "AppDelegate.h" |
||||
#import "NetworkMonitor.h" |
||||
#import "Network.h" |
||||
#import "NodeStatus.h" |
||||
#import "JoinNetworkViewController.h" |
||||
#import "ShowNetworksViewController.h" |
||||
#import "PreferencesViewController.h" |
||||
#import "AboutViewController.h" |
||||
#import "ServiceCom.h" |
||||
|
||||
@implementation AppDelegate |
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { |
||||
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:-2.0f]; |
||||
self.networkListPopover = [[NSPopover alloc] init]; |
||||
self.joinNetworkPopover = [[NSPopover alloc] init]; |
||||
self.preferencesPopover = [[NSPopover alloc] init]; |
||||
self.aboutPopover = [[NSPopover alloc] init]; |
||||
self.transientMonitor = nil; |
||||
self.monitor = [[NetworkMonitor alloc] init]; |
||||
self.networks = [NSMutableArray<Network*> array]; |
||||
self.status = nil; |
||||
self.pasteboard = [NSPasteboard generalPasteboard]; |
||||
|
||||
[self.pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil]; |
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |
||||
NSDictionary *defaultsDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"firstRun"]; |
||||
[defaults registerDefaults:defaultsDict]; |
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; |
||||
|
||||
[nc addObserver:self |
||||
selector:@selector(onNetworkListUpdated:) |
||||
name:NetworkUpdateKey |
||||
object:nil]; |
||||
[nc addObserver:self |
||||
selector:@selector(onNodeStatusUpdated:) |
||||
name:StatusUpdateKey |
||||
object:nil]; |
||||
|
||||
self.statusItem.image = [NSImage imageNamed:@"MenuBarIconMac"]; |
||||
|
||||
[self buildMenu]; |
||||
|
||||
self.joinNetworkPopover.contentViewController = [[JoinNetworkViewController alloc] initWithNibName:@"JoinNetworkViewController" bundle:nil]; |
||||
self.joinNetworkPopover.behavior = NSPopoverBehaviorTransient; |
||||
|
||||
ShowNetworksViewController *showNetworksView = [[ShowNetworksViewController alloc] initWithNibName:@"ShowNetworksViewController" bundle:nil]; |
||||
showNetworksView.netMonitor = self.monitor; |
||||
self.networkListPopover.contentViewController = showNetworksView; |
||||
self.networkListPopover.behavior = NSPopoverBehaviorTransient; |
||||
|
||||
PreferencesViewController *prefsView = [[PreferencesViewController alloc] initWithNibName:@"PreferencesViewController" bundle:nil]; |
||||
self.preferencesPopover.contentViewController = prefsView; |
||||
self.preferencesPopover.behavior = NSPopoverBehaviorTransient; |
||||
|
||||
self.aboutPopover.contentViewController = [[AboutViewController alloc] initWithNibName:@"AboutViewController" bundle:nil]; |
||||
self.aboutPopover.behavior = NSPopoverBehaviorTransient; |
||||
|
||||
BOOL firstRun = [defaults boolForKey:@"firstRun"]; |
||||
|
||||
if(firstRun) { |
||||
[defaults setBool:NO forKey:@"firstRun"]; |
||||
[defaults synchronize]; |
||||
|
||||
[prefsView setLaunchAtLoginEnabled:YES]; |
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ |
||||
[self showAbout]; |
||||
}]; |
||||
} |
||||
|
||||
[self.monitor updateNetworkInfo]; |
||||
[self.monitor start]; |
||||
} |
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification { |
||||
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
||||
} |
||||
|
||||
- (void)showNetworks { |
||||
if(self.statusItem.button != nil) { |
||||
NSStatusBarButton *button = self.statusItem.button; |
||||
[self.networkListPopover showRelativeToRect:button.bounds |
||||
ofView:button |
||||
preferredEdge:NSMinYEdge]; |
||||
|
||||
if(self.transientMonitor == nil) { |
||||
self.transientMonitor = |
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown) |
||||
handler:^(NSEvent * _Nonnull e) { |
||||
[NSEvent removeMonitor:self.transientMonitor]; |
||||
self.transientMonitor = nil; |
||||
[self.networkListPopover close]; |
||||
}]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
- (void)joinNetwork { |
||||
if(self.statusItem.button != nil) { |
||||
NSStatusBarButton *button = self.statusItem.button; |
||||
[self.joinNetworkPopover showRelativeToRect:button.bounds |
||||
ofView:button |
||||
preferredEdge:NSMinYEdge]; |
||||
if(self.transientMonitor == nil) { |
||||
self.transientMonitor = |
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown) |
||||
handler:^(NSEvent * _Nonnull e) { |
||||
[NSEvent removeMonitor:self.transientMonitor]; |
||||
self.transientMonitor = nil; |
||||
[self.joinNetworkPopover close]; |
||||
}]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
- (void)showPreferences { |
||||
if(self.statusItem.button != nil) { |
||||
NSStatusBarButton *button = self.statusItem.button; |
||||
[self.preferencesPopover showRelativeToRect:button.bounds |
||||
ofView:button |
||||
preferredEdge:NSMinYEdge]; |
||||
if(self.transientMonitor == nil) { |
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown) |
||||
handler:^(NSEvent * _Nonnull e) { |
||||
[NSEvent removeMonitor:self.transientMonitor]; |
||||
self.transientMonitor = nil; |
||||
[self.preferencesPopover close]; |
||||
}]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
- (void)showAbout { |
||||
if(self.statusItem.button != nil) { |
||||
NSStatusBarButton *button = self.statusItem.button; |
||||
[self.aboutPopover showRelativeToRect:button.bounds |
||||
ofView:button |
||||
preferredEdge:NSMinYEdge]; |
||||
if(self.transientMonitor == nil) { |
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown) |
||||
handler:^(NSEvent * _Nonnull e) { |
||||
[NSEvent removeMonitor:self.transientMonitor]; |
||||
self.transientMonitor = nil; |
||||
[self.aboutPopover close]; |
||||
}]; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
- (void)quit { |
||||
[NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; |
||||
} |
||||
|
||||
- (void)onNetworkListUpdated:(NSNotification*)note { |
||||
NSArray<Network*> *netList = [note.userInfo objectForKey:@"networks"]; |
||||
[(ShowNetworksViewController*)self.networkListPopover.contentViewController setNetworks:netList]; |
||||
self.networks = [netList mutableCopy]; |
||||
|
||||
[self buildMenu]; |
||||
} |
||||
|
||||
- (void)onNodeStatusUpdated:(NSNotification*)note { |
||||
NodeStatus *status = [note.userInfo objectForKey:@"status"]; |
||||
self.status = status; |
||||
|
||||
[self buildMenu]; |
||||
} |
||||
|
||||
- (void)buildMenu { |
||||
NSMenu *menu = [[NSMenu alloc] init]; |
||||
menu.delegate = self; |
||||
|
||||
if(self.status != nil) { |
||||
NSString *nodeId = @"Node ID: "; |
||||
nodeId = [nodeId stringByAppendingString:self.status.address]; |
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:nodeId |
||||
action:@selector(copyNodeID) |
||||
keyEquivalent:@""]]; |
||||
[menu addItem:[NSMenuItem separatorItem]]; |
||||
} |
||||
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Network Details..." |
||||
action:@selector(showNetworks) |
||||
keyEquivalent:@"n"]]; |
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Join Network..." |
||||
action:@selector(joinNetwork) |
||||
keyEquivalent:@"j"]]; |
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]]; |
||||
|
||||
if([self.networks count] > 0) { |
||||
for(Network *net in self.networks) { |
||||
NSString *nwid = [NSString stringWithFormat:@"%10llx", net.nwid]; |
||||
NSString *networkName = @""; |
||||
if([net.name lengthOfBytesUsingEncoding:NSUTF8StringEncoding] == 0) { |
||||
networkName = nwid; |
||||
} |
||||
else { |
||||
networkName = [NSString stringWithFormat:@"%@ (%@)", nwid, net.name]; |
||||
} |
||||
|
||||
if(net.allowDefault && net.connected) { |
||||
networkName = [networkName stringByAppendingString:@" [default]"]; |
||||
} |
||||
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:networkName |
||||
action:@selector(toggleNetwork:) |
||||
keyEquivalent:@""]; |
||||
if(net.connected) { |
||||
item.state = NSOnState; |
||||
} |
||||
else { |
||||
item.state = NSOffState; |
||||
} |
||||
|
||||
item.representedObject = net; |
||||
|
||||
[menu addItem:item]; |
||||
} |
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]]; |
||||
} |
||||
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"About ZeroTier One..." |
||||
action:@selector(showAbout) |
||||
keyEquivalent:@""]]; |
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Preferences..." |
||||
action:@selector(showPreferences) |
||||
keyEquivalent:@""]]; |
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]]; |
||||
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Quit" |
||||
action:@selector(quit) |
||||
keyEquivalent:@"q"]]; |
||||
|
||||
self.statusItem.menu = menu; |
||||
} |
||||
|
||||
- (void)toggleNetwork:(NSMenuItem*)sender { |
||||
Network *network = sender.representedObject; |
||||
NSString *nwid = [NSString stringWithFormat:@"%10llx", network.nwid]; |
||||
|
||||
if(network.connected) { |
||||
[[ServiceCom sharedInstance] leaveNetwork:nwid]; |
||||
} |
||||
else { |
||||
[[ServiceCom sharedInstance] joinNetwork:nwid |
||||
allowManaged:network.allowManaged |
||||
allowGlobal:network.allowGlobal |
||||
allowDefault:(network.allowDefault && ![Network defaultRouteExists:self.networks])]; |
||||
} |
||||
} |
||||
|
||||
- (void)copyNodeID { |
||||
if(self.status != nil) { |
||||
[self.pasteboard setString:self.status.address forType:NSPasteboardTypeString]; |
||||
} |
||||
} |
||||
|
||||
- (void)menuWillOpen:(NSMenu*)menu { |
||||
|
||||
} |
||||
|
||||
- (void)menuDidClose:(NSMenu*)menu { |
||||
|
||||
} |
||||
|
||||
@end |
||||
@ -1,264 +0,0 @@
|
||||
// |
||||
// AppDelegate.swift |
||||
// ZeroTier One |
||||
// |
||||
// Created by Grant Limberg on 5/14/16. |
||||
// Copyright © 2016 ZeroTier, Inc. All rights reserved. |
||||
// |
||||
|
||||
import Cocoa |
||||
|
||||
@NSApplicationMain |
||||
class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { |
||||
|
||||
@IBOutlet weak var window: NSWindow! |
||||
|
||||
|
||||
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2.0) |
||||
|
||||
let networkListPopover = NSPopover() |
||||
let joinNetworkPopover = NSPopover() |
||||
let preferencesPopover = NSPopover() |
||||
let aboutPopover = NSPopover() |
||||
|
||||
var transientMonitor: AnyObject? = nil |
||||
|
||||
let monitor = NetworkMonitor() |
||||
|
||||
var networks = [Network]() |
||||
|
||||
var status: NodeStatus? = nil |
||||
|
||||
var pasteboard = NSPasteboard.generalPasteboard() |
||||
|
||||
func applicationDidFinishLaunching(aNotification: NSNotification) { |
||||
pasteboard.declareTypes([NSPasteboardTypeString], owner: nil) |
||||
|
||||
let defaults = NSUserDefaults.standardUserDefaults() |
||||
let defaultsDict = ["firstRun": true] |
||||
defaults.registerDefaults(defaultsDict) |
||||
|
||||
|
||||
|
||||
|
||||
let nc = NSNotificationCenter.defaultCenter() |
||||
nc.addObserver(self, selector: #selector(onNetworkListUpdated(_:)), name: NetworkUpdateKey, object: nil) |
||||
nc.addObserver(self, selector: #selector(onNodeStatusUpdated(_:)), name: StatusUpdateKey, object: nil) |
||||
|
||||
statusItem.image = NSImage(named: "MenuBarIconMac") |
||||
|
||||
buildMenu() |
||||
|
||||
joinNetworkPopover.contentViewController = JoinNetworkViewController( |
||||
nibName: "JoinNetworkViewController", bundle: nil) |
||||
joinNetworkPopover.behavior = .Transient |
||||
|
||||
let showNetworksView = ShowNetworksViewController( |
||||
nibName: "ShowNetworksViewController", bundle: nil) |
||||
showNetworksView?.netMonitor = monitor |
||||
|
||||
networkListPopover.contentViewController = showNetworksView |
||||
networkListPopover.behavior = .Transient |
||||
|
||||
let prefsView = PreferencesViewController(nibName: "PreferencesViewController", bundle: nil) |
||||
preferencesPopover.contentViewController = prefsView |
||||
preferencesPopover.behavior = .Transient |
||||
|
||||
aboutPopover.contentViewController = AboutViewController( |
||||
nibName: "AboutViewController", bundle: nil) |
||||
aboutPopover.behavior = .Transient |
||||
|
||||
let firstRun = defaults.boolForKey("firstRun") |
||||
|
||||
if firstRun { |
||||
defaults.setBool(false, forKey: "firstRun") |
||||
defaults.synchronize() |
||||
|
||||
prefsView?.setLaunchAtLoginEnabled(true) |
||||
} |
||||
|
||||
if firstRun { |
||||
NSOperationQueue.mainQueue().addOperationWithBlock() { |
||||
self.showAbout() |
||||
} |
||||
} |
||||
|
||||
monitor.updateNetworkInfo() |
||||
monitor.start() |
||||
} |
||||
|
||||
func applicationWillTerminate(aNotification: NSNotification) { |
||||
// Insert code here to tear down your application |
||||
let nc = NSNotificationCenter.defaultCenter() |
||||
nc.removeObserver(self) |
||||
} |
||||
|
||||
|
||||
func showNetworks() { |
||||
if let button = statusItem.button { |
||||
networkListPopover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY) |
||||
|
||||
if transientMonitor == nil { |
||||
transientMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask( |
||||
[.LeftMouseDownMask, .RightMouseDownMask, .OtherMouseDownMask]) { (event: NSEvent) -> Void in |
||||
|
||||
NSEvent.removeMonitor(self.transientMonitor!) |
||||
self.transientMonitor = nil |
||||
self.networkListPopover.close() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func joinNetwork() { |
||||
if let button = statusItem.button { |
||||
joinNetworkPopover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY) |
||||
|
||||
if transientMonitor == nil { |
||||
transientMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask( |
||||
[.LeftMouseDownMask, .RightMouseDownMask, .OtherMouseDownMask]) { (event: NSEvent) -> Void in |
||||
|
||||
NSEvent.removeMonitor(self.transientMonitor!) |
||||
self.transientMonitor = nil |
||||
self.joinNetworkPopover.close() |
||||
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func showPreferences() { |
||||
if let button = statusItem.button { |
||||
preferencesPopover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY) |
||||
|
||||
if transientMonitor == nil { |
||||
transientMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask( |
||||
[.LeftMouseDownMask, .RightMouseDownMask, .OtherMouseDownMask]) { (event: NSEvent) -> Void in |
||||
|
||||
NSEvent.removeMonitor(self.transientMonitor!) |
||||
self.transientMonitor = nil |
||||
self.preferencesPopover.close() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func showAbout() { |
||||
if let button = statusItem.button { |
||||
aboutPopover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY) |
||||
|
||||
if transientMonitor == nil { |
||||
transientMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask( |
||||
[.LeftMouseDownMask, .RightMouseDownMask, .OtherMouseDownMask]) { (event: NSEvent) -> Void in |
||||
|
||||
NSEvent.removeMonitor(self.transientMonitor!) |
||||
self.transientMonitor = nil |
||||
self.aboutPopover.close() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func quit() { |
||||
NSApp.performSelector(#selector(NSApp.terminate(_:)), withObject: nil, afterDelay: 0.0) |
||||
} |
||||
|
||||
func onNetworkListUpdated(note: NSNotification) { |
||||
let netList = note.userInfo!["networks"] as! [Network] |
||||
(networkListPopover.contentViewController as! ShowNetworksViewController).setNetworks(netList) |
||||
|
||||
self.networks = netList |
||||
|
||||
buildMenu() |
||||
} |
||||
|
||||
func onNodeStatusUpdated(note: NSNotification) { |
||||
let status = note.userInfo!["status"] as! NodeStatus |
||||
self.status = status |
||||
|
||||
buildMenu() |
||||
} |
||||
|
||||
func buildMenu() { |
||||
let menu = NSMenu() |
||||
menu.delegate = self |
||||
|
||||
if let s = self.status { |
||||
menu.addItem(NSMenuItem(title: "Node ID: \(s.address)", action: #selector(AppDelegate.copyNodeID), keyEquivalent: "")) |
||||
menu.addItem(NSMenuItem.separatorItem()) |
||||
} |
||||
|
||||
menu.addItem(NSMenuItem(title: "Network Details...", action: #selector(AppDelegate.showNetworks), keyEquivalent: "n")) |
||||
menu.addItem(NSMenuItem(title: "Join Network...", action: #selector(AppDelegate.joinNetwork), keyEquivalent: "j")) |
||||
menu.addItem(NSMenuItem.separatorItem()) |
||||
|
||||
if networks.count > 0 { |
||||
for net in networks { |
||||
let id = String(net.nwid, radix: 16) |
||||
var networkName = "" |
||||
if net.name.isEmpty { |
||||
networkName = "\(id)" |
||||
} |
||||
else { |
||||
networkName = "\(id) (\(net.name))" |
||||
} |
||||
|
||||
if net.allowDefault && net.connected { |
||||
networkName += " [default]" |
||||
} |
||||
let item = NSMenuItem(title: networkName, action: #selector(AppDelegate.toggleNetwork(_:)), keyEquivalent: "") |
||||
|
||||
if net.connected { |
||||
item.state = NSOnState |
||||
} |
||||
else { |
||||
item.state = NSOffState |
||||
} |
||||
|
||||
item.representedObject = net |
||||
|
||||
menu.addItem(item) |
||||
} |
||||
|
||||
menu.addItem(NSMenuItem.separatorItem()) |
||||
} |
||||
|
||||
menu.addItem(NSMenuItem(title: "About ZeroTier One...", action: #selector(AppDelegate.showAbout), keyEquivalent: "")) |
||||
menu.addItem(NSMenuItem(title: "Preferences...", action: #selector(AppDelegate.showPreferences), keyEquivalent: ",")) |
||||
|
||||
menu.addItem(NSMenuItem.separatorItem()) |
||||
|
||||
menu.addItem(NSMenuItem(title: "Quit ZeroTier One", action: #selector(AppDelegate.quit), keyEquivalent: "q")) |
||||
|
||||
statusItem.menu = menu |
||||
} |
||||
|
||||
func toggleNetwork(sender: NSMenuItem) { |
||||
NSLog("\(sender.title)") |
||||
|
||||
let network = sender.representedObject as! Network |
||||
|
||||
let id = String(network.nwid, radix: 16) |
||||
|
||||
if network.connected { |
||||
ServiceCom.sharedInstance().leaveNetwork(id) |
||||
} |
||||
else { |
||||
ServiceCom.sharedInstance().joinNetwork(id, allowManaged: true, allowGlobal: false, allowDefault: false) |
||||
} |
||||
} |
||||
|
||||
func copyNodeID() { |
||||
if let s = self.status { |
||||
pasteboard.setString(s.address, forType: NSPasteboardTypeString) |
||||
} |
||||
} |
||||
|
||||
func menuWillOpen(menu: NSMenu) { |
||||
//monitor.updateNetworkInfo() |
||||
} |
||||
|
||||
func menuDidClose(menu: NSMenu) { |
||||
} |
||||
} |
||||
|
||||
@ -1,14 +0,0 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#import "AuthtokenCopy.h" |
||||
#import "NodeStatus.h" |
||||
#import "Network.h" |
||||
#import "ServiceCom.h" |
||||
#import "AboutViewController.h" |
||||
#import "PreferencesViewController.h" |
||||
#import "NetworkMonitor.h" |
||||
#import "NetworkInfoCell.h" |
||||
#import "ShowNetworksViewController.h" |
||||
#import "JoinNetworkViewController.h" |
||||
Loading…
Reference in new issue