add NetworkChangeNotifier back

This commit is contained in:
yicheng 2019-10-15 22:40:02 +08:00
parent 92a3aa5494
commit d3b11984bf
5 changed files with 117 additions and 41 deletions

View File

@ -52,6 +52,7 @@
49CF3B2820CD7465001EBF94 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 49CF3B2620CD7465001EBF94 /* Main.storyboard */; };
49CF3B5C20CE8068001EBF94 /* ClashResourceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49CF3B5B20CE8068001EBF94 /* ClashResourceManager.swift */; };
49CF3B6520CEE06C001EBF94 /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49CF3B6420CEE06C001EBF94 /* ConfigManager.swift */; };
49D176A72355FE680093DD7B /* NetworkChangeNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D176A62355FE680093DD7B /* NetworkChangeNotifier.swift */; };
F935B2F02307C52E009E4D33 /* com.west2online.ClashX.ProxyConfigHelper in Copy Files */ = {isa = PBXBuildFile; fileRef = F9A7C0692306E874007163C7 /* com.west2online.ClashX.ProxyConfigHelper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
F935B2F42307CD32009E4D33 /* ProxyConfigHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F935B2F32307CD32009E4D33 /* ProxyConfigHelper.m */; };
F935B2FA23083EE6009E4D33 /* ProxySettingTool.m in Sources */ = {isa = PBXBuildFile; fileRef = F935B2F923083EE6009E4D33 /* ProxySettingTool.m */; };
@ -178,6 +179,7 @@
49CF3B3520CD75DF001EBF94 /* ClashX-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ClashX-Bridging-Header.h"; sourceTree = "<group>"; };
49CF3B5B20CE8068001EBF94 /* ClashResourceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClashResourceManager.swift; sourceTree = "<group>"; };
49CF3B6420CEE06C001EBF94 /* ConfigManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = "<group>"; };
49D176A62355FE680093DD7B /* NetworkChangeNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkChangeNotifier.swift; sourceTree = "<group>"; };
49E07A8A20D501A000A088A3 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
5217C006C5A22A1CEA24BFC1 /* Pods-ClashX.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ClashX.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ClashX/Pods-ClashX.debug.xcconfig"; sourceTree = "<group>"; };
A1485BCE642059532D01B8BA /* Pods-ClashX.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ClashX.release.xcconfig"; path = "Pods/Target Support Files/Pods-ClashX/Pods-ClashX.release.xcconfig"; sourceTree = "<group>"; };
@ -246,6 +248,7 @@
children = (
4960A6DA2136529200B940C9 /* JSBridgeHandler.swift */,
493AEAE2221AE3420016FE98 /* AppVersionUtil.swift */,
49D176A62355FE680093DD7B /* NetworkChangeNotifier.swift */,
);
path = Utils;
sourceTree = "<group>";
@ -670,6 +673,7 @@
49CF3B2120CD7463001EBF94 /* AppDelegate.swift in Sources */,
496BDEE021196F1E00C5207F /* Logger.swift in Sources */,
49722FEF211F338B00650A41 /* FileEvent.swift in Sources */,
49D176A72355FE680093DD7B /* NetworkChangeNotifier.swift in Sources */,
4913C82321157D0200F6B87C /* Notification.swift in Sources */,
499A485C22ED793C00F6C675 /* NSView+Nib.swift in Sources */,
492C4871210EF62E004554A0 /* ClashConfig.swift in Sources */,

View File

@ -52,7 +52,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
signal(SIGPIPE, SIG_IGN)
checkOnlyOneClashX()
// setup menu item first
statusItem = NSStatusBar.system.statusItem(withLength:statusItemLengthWithSpeed)
statusItem.menu = statusMenu
@ -88,6 +90,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
andSelector: #selector(handleURL(event:reply:)),
forEventClass: AEEventClass(kInternetEventClass),
andEventID: AEEventID(kAEGetURL))
setupNetworkNotifier()
}
@ -122,15 +127,21 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.statusItemView.updateStatusItemView()
}.disposed(by: disposeBag)
ConfigManager.shared
.proxyPortAutoSetObservable
.distinctUntilChanged()
.bind{ [weak self]
en in
Observable
.merge([ConfigManager.shared.proxyPortAutoSetObservable,
ConfigManager.shared.isProxySetByOtherVariable.asObservable()])
.map { _ -> NSControl.StateValue in
if ConfigManager.shared.isProxySetByOtherVariable.value && ConfigManager.shared.proxyPortAutoSet{
return .mixed
}
return ConfigManager.shared.proxyPortAutoSet ? .on : .off
}.distinctUntilChanged()
.bind { [weak self] status in
guard let self = self else {return}
let enable = en ?? false
self.proxySettingMenuItem.state = enable ? .on : .off
}.disposed(by: disposeBag)
self.proxySettingMenuItem.state = status
self.statusItemView.updateViewStatus(enableProxy: status == .on)
}.disposed(by: disposeBag)
let configObservable = ConfigManager.shared
.currentConfigVariable
@ -181,8 +192,33 @@ class AppDelegate: NSObject, NSApplicationDelegate {
guard let self = self else {return}
self.autoStartMenuItem.state = enable ? .on : .off
}).disposed(by: disposeBag)
}
func checkOnlyOneClashX() {
if NSRunningApplication.runningApplications(withBundleIdentifier: Bundle.main.bundleIdentifier ?? "").count > 1 {
assertionFailure()
NSApp.terminate(nil)
}
}
func setupNetworkNotifier() {
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
NetworkChangeNotifier.start()
}
NotificationCenter
.default
.rx
.notification(kSystemNetworkStatusDidChange)
.observeOn(MainScheduler.instance)
.bind{ _ in
guard let (http,https,socks) = NetworkChangeNotifier.currentSystemProxySetting(),
let currentPort = ConfigManager.shared.currentConfig?.port,
let currentSocks = ConfigManager.shared.currentConfig?.socketPort else {return}
let proxySetted = http == currentPort && https == currentPort && socks == currentSocks
ConfigManager.shared.isProxySetByOtherVariable.accept(!proxySetted)
}.disposed(by: disposeBag)
}
@ -345,7 +381,11 @@ extension AppDelegate {
}
@IBAction func actionSetSystemProxy(_ sender: Any) {
ConfigManager.shared.proxyPortAutoSet = !ConfigManager.shared.proxyPortAutoSet
if ConfigManager.shared.isProxySetByOtherVariable.value && ConfigManager.shared.proxyPortAutoSet {
// should reset proxy to clashx
} else {
ConfigManager.shared.proxyPortAutoSet = !ConfigManager.shared.proxyPortAutoSet
}
let port = ConfigManager.shared.currentConfig?.port ?? 0
let socketPort = ConfigManager.shared.currentConfig?.socketPort ?? 0
@ -355,7 +395,6 @@ extension AppDelegate {
} else {
SystemProxyManager.shared.disableProxy(port: port, socksPort: socketPort)
}
}
@IBAction func actionCopyExportCommand(_ sender: Any) {

View File

@ -71,7 +71,9 @@ class ConfigManager {
UserDefaults.standard.set(newValue, forKey: "proxyPortAutoSet")
}
}
let proxyPortAutoSetObservable = UserDefaults.standard.rx.observe(Bool.self, "proxyPortAutoSet")
let proxyPortAutoSetObservable = UserDefaults.standard.rx.observe(Bool.self, "proxyPortAutoSet").map({$0 ?? false})
var isProxySetByOtherVariable = BehaviorRelay<Bool>(value: false)
var showNetSpeedIndicator:Bool {
get{

View File

@ -0,0 +1,39 @@
//
// NetworkChangeNotifier.swift
// ClashX
//
// Created by yicheng on 2019/10/15.
// Copyright © 2019 west2online. All rights reserved.
//
import Cocoa
import SystemConfiguration
class NetworkChangeNotifier {
static func start() {
let changed: SCDynamicStoreCallBack = { dynamicStore, _, _ in
NotificationCenter.default.post(name: kSystemNetworkStatusDidChange, object: nil)
}
var dynamicContext = SCDynamicStoreContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let dcAddress = withUnsafeMutablePointer(to: &dynamicContext, {UnsafeMutablePointer<SCDynamicStoreContext>($0)})
if let dynamicStore = SCDynamicStoreCreate(kCFAllocatorDefault, "com.clashx.networknotification" as CFString, changed, dcAddress) {
let keysArray = ["State:/Network/Global/Proxies" as CFString] as CFArray
SCDynamicStoreSetNotificationKeys(dynamicStore, nil, keysArray)
let loop = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, dynamicStore, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), loop, .defaultMode)
CFRunLoopRun()
}
}
static func currentSystemProxySetting() -> (UInt,UInt,UInt)? {
let proxiesSetting = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as! [String:AnyObject]
guard let httpProxy = proxiesSetting[kCFNetworkProxiesHTTPPort as String] as? UInt,
let socksProxy = proxiesSetting[kCFNetworkProxiesSOCKSPort as String]as? UInt,
let httpsProxy = proxiesSetting[kCFNetworkProxiesHTTPSPort as String]as? UInt else {return nil}
return (httpProxy,httpsProxy,socksProxy)
}
}

View File

@ -21,7 +21,11 @@ class StatusItemView: NSView {
var updating = false
weak var statusItem:NSStatusItem?
var disposeBag = DisposeBag()
lazy var menuImage: NSImage = {
let customImagePath = (NSHomeDirectory() as NSString).appendingPathComponent("/.config/clash/menuImage.png")
return NSImage(contentsOfFile: customImagePath) ?? NSImage(named: "menu_icon")!
}()
static func create(statusItem:NSStatusItem?)->StatusItemView{
@ -36,33 +40,6 @@ class StatusItemView: NSView {
}
func setupView() {
let proxySetObservable = ConfigManager.shared.proxyPortAutoSetObservable.map { $0 as AnyObject }
proxySetObservable
.bind { [weak self] _ in
guard let self = self else {return}
let enableProxy = ConfigManager.shared.proxyPortAutoSet;
let customImagePath = (NSHomeDirectory() as NSString).appendingPathComponent("/.config/clash/menuImage.png")
let selectedColor = NSColor.red
let unselectedColor: NSColor
if #available(OSX 10.14, *) {
unselectedColor = selectedColor.withSystemEffect(.disabled)
} else {
unselectedColor = selectedColor.withAlphaComponent(0.5)
}
let image = NSImage(contentsOfFile: customImagePath) ??
NSImage(named: "menu_icon")!.tint(color: enableProxy ? selectedColor : unselectedColor)
self.imageView.image = image
self.uploadSpeedLabel.textColor = NSColor.black
self.downloadSpeedLabel.textColor = self.uploadSpeedLabel.textColor
self.updateStatusItemView()
}.disposed(by: disposeBag)
if #available(OSX 10.11, *) {
let font = NSFont.systemFont(ofSize: 9, weight: .regular)
uploadSpeedLabel.font = font
@ -71,6 +48,21 @@ class StatusItemView: NSView {
}
func updateViewStatus(enableProxy: Bool) {
let selectedColor = NSColor.red
let unselectedColor: NSColor
if #available(OSX 10.14, *) {
unselectedColor = selectedColor.withSystemEffect(.disabled)
} else {
unselectedColor = selectedColor.withAlphaComponent(0.5)
}
imageView.image = menuImage.tint(color: enableProxy ? selectedColor : unselectedColor)
uploadSpeedLabel.textColor = NSColor.black
downloadSpeedLabel.textColor = uploadSpeedLabel.textColor
updateStatusItemView()
}
func updateSpeedLabel(up:Int,down:Int) {
guard !self.speedContainerView.isHidden else {return}