diff --git a/V2rayU/AppDelegate.swift b/V2rayU/AppDelegate.swift
index e34a016..6e46ea5 100644
--- a/V2rayU/AppDelegate.swift
+++ b/V2rayU/AppDelegate.swift
@@ -18,8 +18,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
- NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
-
// Insert code here to initialize your application
let startedAtLogin = NSWorkspace.shared.runningApplications.contains {
$0.bundleIdentifier == launcherAppIdentifier
@@ -40,6 +38,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// check version
V2rayUpdater.checkForUpdatesInBackground()
}
+
+ // wake and sleep
+ NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(onWakeNote(note:)), name: NSWorkspace.willSleepNotification, object: nil)
+ NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(onSleepNote(note:)), name: NSWorkspace.didWakeNotification, object: nil)
+ // url scheme
+ NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
func checkDefault() {
@@ -69,8 +73,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
let appleEventURL = URL(string: appleEventURLString)
+ // todo
+ }
- print("Received Apple Event URL: \(appleEventURL)")
+ @objc func onWakeNote(note: NSNotification) {
+ if UserDefaults.getBool(forKey: .v2rayTurnOn) {
+ V2rayLaunch.Start()
+ }
+ }
+
+ @objc func onSleepNote(note: NSNotification) {
+ V2rayLaunch.Stop()
}
func applicationWillTerminate(_ aNotification: Notification) {
diff --git a/V2rayU/Base.lproj/ConfigWindow.xib b/V2rayU/Base.lproj/ConfigWindow.xib
index 683d483..aed9425 100644
--- a/V2rayU/Base.lproj/ConfigWindow.xib
+++ b/V2rayU/Base.lproj/ConfigWindow.xib
@@ -80,7 +80,6 @@
-
@@ -175,7 +174,7 @@ Gw
-
+
@@ -267,20 +266,11 @@ Gw
-
-
-
-
-
-
-
-
-
-
+
@@ -1582,6 +1572,15 @@ Gw
+
+
+
+
+
+
+
+
+
diff --git a/V2rayU/Base.lproj/QrcodeWindow.xib b/V2rayU/Base.lproj/QrcodeWindow.xib
index feac95e..07499e2 100644
--- a/V2rayU/Base.lproj/QrcodeWindow.xib
+++ b/V2rayU/Base.lproj/QrcodeWindow.xib
@@ -16,8 +16,7 @@
-
-
+
diff --git a/V2rayU/ConfigWindow.swift b/V2rayU/ConfigWindow.swift
index 595e745..b7b3b0d 100644
--- a/V2rayU/ConfigWindow.swift
+++ b/V2rayU/ConfigWindow.swift
@@ -417,6 +417,8 @@ class ConfigWindowController: NSWindowController, NSWindowDelegate, NSTabViewDel
func loadJsonData(rowIndex: Int) {
defer {
self.bindDataToView()
+ // replace current
+ self.switchToImportView()
}
// reset
@@ -447,9 +449,18 @@ class ConfigWindowController: NSWindowController, NSWindowDelegate, NSTabViewDel
// save
let errMsg = V2rayServer.save(idx: self.serversTableView.selectedRow, isValid: self.v2rayConfig.isValid, jsonData: text)
- self.errTip.stringValue = errMsg
-
- self.refreshServerList(ok: errMsg.count == 0)
+ if errMsg.count == 0 {
+ if self.errTip.stringValue == "" {
+ self.errTip.stringValue = "save success"
+ DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
+ // your code here
+ self.errTip.stringValue = ""
+ }
+ }
+ self.refreshServerList(ok: errMsg.count == 0)
+ } else {
+ self.errTip.stringValue = errMsg
+ }
}
func refreshServerList(ok: Bool = true) {
@@ -482,6 +493,8 @@ class ConfigWindowController: NSWindowController, NSWindowDelegate, NSTabViewDel
@IBAction func setV2rayLogLevel(_ sender: NSPopUpButton) {
if let item = logLevel.selectedItem {
UserDefaults.set(forKey: .v2rayLogLevel, value: item.title)
+ // replace current
+ self.switchToImportView()
// restart service
menuController.startV2rayCore()
}
diff --git a/V2rayU/MainMenu.swift b/V2rayU/MainMenu.swift
index 7f10212..1b96556 100644
--- a/V2rayU/MainMenu.swift
+++ b/V2rayU/MainMenu.swift
@@ -17,7 +17,6 @@ let preferencesWindowController = PreferencesWindowController(
PreferenceGeneralViewController(),
]
)
-var configWindow = ConfigWindowController()
var qrcodeWindow = QrcodeWindowController()
// menu controller
@@ -25,6 +24,7 @@ class MenuController: NSObject, NSMenuDelegate {
var closedByConfigWindow: Bool = false
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
var statusItemClicked: (() -> Void)?
+ var configWindow: ConfigWindowController!
@IBOutlet weak var v2rayRulesMode: NSMenuItem!
@IBOutlet weak var globalMode: NSMenuItem!
@@ -112,12 +112,12 @@ class MenuController: NSObject, NSMenuDelegate {
NSLog("start v2ray-core begin")
guard let v2ray = V2rayServer.loadSelectedItem() else {
- self.notice(title: "start v2ray fail", subtitle: "", informativeText: "v2ray config not found")
+ noticeTip(title: "start v2ray fail", subtitle: "", informativeText: "v2ray config not found")
return
}
if !v2ray.isValid {
- self.notice(title: "start v2ray fail", subtitle: "", informativeText: "invalid v2ray config")
+ noticeTip(title: "start v2ray fail", subtitle: "", informativeText: "invalid v2ray config")
return
}
@@ -153,14 +153,6 @@ class MenuController: NSObject, NSMenuDelegate {
NSApplication.shared.terminate(self)
}
- @IBAction func generateQRCode(_ sender: NSMenuItem) {
- NSLog("GenerateQRCode")
- }
-
- @IBAction func scanQRCode(_ sender: NSMenuItem) {
- NSLog("ScanQRCode")
- }
-
@IBAction func openPreference(_ sender: NSMenuItem) {
preferencesWindowController.showWindow()
}
@@ -188,14 +180,21 @@ class MenuController: NSObject, NSMenuDelegate {
// open config window
@IBAction func openConfig(_ sender: NSMenuItem) {
- // close before
- configWindow.close()
- // renew
- configWindow = ConfigWindowController()
+ if configWindow != nil {
+ // close before
+ if closedByConfigWindow {
+ configWindow.close()
+ // renew
+ configWindow = ConfigWindowController()
+ }
+ } else {
+ // renew
+ configWindow = ConfigWindowController()
+ }
+
// show window
- configWindow.showWindow(self)
- // center
- configWindow.window?.center()
+ configWindow.showWindow(nil)
+ configWindow.window?.makeKeyAndOrderFront(self)
// show dock icon
NSApp.setActivationPolicy(.regular)
// bring to front
@@ -308,14 +307,14 @@ class MenuController: NSObject, NSMenuDelegate {
@IBAction func generateQrcode(_ sender: NSMenuItem) {
guard let v2ray = V2rayServer.loadSelectedItem() else {
NSLog("v2ray config not found")
- self.notice(title: "generate Qrcode fail", subtitle: "", informativeText: "no available servers")
+ noticeTip(title: "generate Qrcode fail", subtitle: "", informativeText: "no available servers")
return
}
let share = ShareUri()
share.qrcode(item: v2ray)
if share.error.count > 0 {
- self.notice(title: "generate Qrcode fail", subtitle: "", informativeText: share.error)
+ noticeTip(title: "generate Qrcode fail", subtitle: "", informativeText: share.error)
return
}
@@ -338,7 +337,7 @@ class MenuController: NSObject, NSMenuDelegate {
if uri.count > 0 {
self.importUri(url: uri)
} else {
- self.notice(title: "import server fail", subtitle: "", informativeText: "no found qrcode")
+ noticeTip(title: "import server fail", subtitle: "", informativeText: "no found qrcode")
}
}
@@ -346,7 +345,7 @@ class MenuController: NSObject, NSMenuDelegate {
if let uri = NSPasteboard.general.string(forType: .string), uri.count > 0 {
self.importUri(url: uri)
} else {
- self.notice(title: "import server fail", subtitle: "", informativeText: "no found ss:// or vmess:// from Pasteboard")
+ noticeTip(title: "import server fail", subtitle: "", informativeText: "no found ss:// or vmess:// from Pasteboard")
}
}
@@ -354,12 +353,12 @@ class MenuController: NSObject, NSMenuDelegate {
let uri = url.trimmingCharacters(in: .whitespaces)
if uri.count == 0 {
- self.notice(title: "import server fail", subtitle: "", informativeText: "import error: uri not found")
+ noticeTip(title: "import server fail", subtitle: "", informativeText: "import error: uri not found")
return
}
if URL(string: uri) == nil {
- self.notice(title: "import server fail", subtitle: "", informativeText: "no found ss:// or vmess://")
+ noticeTip(title: "import server fail", subtitle: "", informativeText: "no found ss:// or vmess://")
return
}
@@ -377,18 +376,7 @@ class MenuController: NSObject, NSMenuDelegate {
return
}
- self.notice(title: "import server fail", subtitle: "", informativeText: "no found ss:// or vmess://")
- }
-
- func notice(title: String = "", subtitle: String = "", informativeText: String = "") {
- // 定义NSUserNotification
- let userNotification = NSUserNotification()
- userNotification.title = title
- userNotification.subtitle = subtitle
- userNotification.informativeText = informativeText
- // 使用NSUserNotificationCenter发送NSUserNotification
- let userNotificationCenter = NSUserNotificationCenter.default
- userNotificationCenter.scheduleNotification(userNotification)
+ noticeTip(title: "import server fail", subtitle: "", informativeText: "no found ss:// or vmess://")
}
func saveServer(importUri: ImportUri) {
@@ -398,10 +386,20 @@ class MenuController: NSObject, NSMenuDelegate {
// refresh server
self.showServers()
- self.notice(title: "import server success", subtitle: "", informativeText: importUri.remark)
+ noticeTip(title: "import server success", subtitle: "", informativeText: importUri.remark)
} else {
- self.notice(title: "import server fail", subtitle: "", informativeText: importUri.error)
+ noticeTip(title: "import server fail", subtitle: "", informativeText: importUri.error)
}
}
+ func noticeTip(title: String = "", subtitle: String = "", informativeText: String = "") {
+ // 定义NSUserNotification
+ let userNotification = NSUserNotification()
+ userNotification.title = title
+ userNotification.subtitle = subtitle
+ userNotification.informativeText = informativeText
+ // 使用NSUserNotificationCenter发送NSUserNotification
+ let userNotificationCenter = NSUserNotificationCenter.default
+ userNotificationCenter.scheduleNotification(userNotification)
+ }
}
diff --git a/V2rayU/v2ray/V2rayConfig.swift b/V2rayU/v2ray/V2rayConfig.swift
index bd2bcaa..26a8d46 100644
--- a/V2rayU/v2ray/V2rayConfig.swift
+++ b/V2rayU/v2ray/V2rayConfig.swift
@@ -138,7 +138,7 @@ class V2rayConfig: NSObject {
func combineManualData() {
// base
- self.v2ray.log.loglevel = V2rayLog.logLevel(rawValue: self.logLevel)!
+ self.v2ray.log.loglevel = V2rayLog.logLevel(rawValue: UserDefaults.get(forKey: .v2rayLogLevel) ?? "info")!
self.v2ray.dns.servers = self.dns.components(separatedBy: ",")
// ------------------------------------- inbound start ---------------------------------------------
var inHttp = V2rayInbound()
@@ -1126,8 +1126,8 @@ class V2rayConfig: NSObject {
kcpSettings.readBufferSize = steamJson["kcpSettings"]["readBufferSize"].intValue
kcpSettings.writeBufferSize = steamJson["kcpSettings"]["writeBufferSize"].intValue
// "none"
- if KcpSettingsHeaderType.firstIndex(of: steamJson["kcpSettings"]["type"].stringValue) != nil {
- kcpSettings.header.type = steamJson["kcpSettings"]["type"].stringValue
+ if KcpSettingsHeaderType.firstIndex(of: steamJson["kcpSettings"]["header"]["type"].stringValue) != nil {
+ kcpSettings.header.type = steamJson["kcpSettings"]["header"]["type"].stringValue
}
stream.kcpSettings = kcpSettings
}