Skip to content

Commit

Permalink
Merge pull request #4 from blabla-yy/widget
Browse files Browse the repository at this point in the history
Widget
  • Loading branch information
blabla-yy authored Nov 9, 2023
2 parents b5168bb + 8d5f867 commit 7ad9132
Show file tree
Hide file tree
Showing 23 changed files with 889 additions and 41 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@
1. macOS 13+
2. 可配置化
3. 兼容macOS 14

## 1.4.0
1. 小组件
2. 退出规则修改
216 changes: 211 additions & 5 deletions NetworkMonitor.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1500"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "75E798132AFB3CB70035B0E0"
BuildableName = "widgetExtension.appex"
BlueprintName = "widgetExtension"
ReferencedContainer = "container:NetworkMonitor.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "75C65D992351AA2500A12690"
BuildableName = "NetworkMonitor.app"
BlueprintName = "NetworkMonitor"
ReferencedContainer = "container:NetworkMonitor.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "75C65D992351AA2500A12690"
BuildableName = "NetworkMonitor.app"
BlueprintName = "NetworkMonitor"
ReferencedContainer = "container:NetworkMonitor.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "_XCWidgetKind"
value = ""
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "_XCWidgetDefaultView"
value = "timeline"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "_XCWidgetFamily"
value = "systemMedium"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "75C65D992351AA2500A12690"
BuildableName = "NetworkMonitor.app"
BlueprintName = "NetworkMonitor"
ReferencedContainer = "container:NetworkMonitor.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>widgetExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
Expand All @@ -42,6 +47,11 @@
<key>primary</key>
<true/>
</dict>
<key>75E798132AFB3CB70035B0E0</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
# MacOS NetworkMonitor

![image](https://raw.githubusercontent.com/blabla-yy/monitor/master/screenshot2.png)
![image](https://raw.githubusercontent.com/blabla-yy/monitor/master/demo.png)
![image](https://raw.githubusercontent.com/blabla-yy/monitor/master/screenshot.png)

## 功能点
- 实时网络监控
- 支持tcp、udp以及wifi、wired等筛选规则
- 支持状态栏以及小组件(macOS 14 +)

## 安装
Release中直接下载安装包,并移动到"应用程序"中。如果打开失败,"系统设置" -> "隐私与安全性" -> 下拉到"NetworkMonitor"无法打开的提示信息,点击"仍要打开"。


## Feature
- Real-time network traffic statistics
- Configurable tcp, udp and other statistical rules
- Widget(macOS 14+)


## System Requirements
Expand Down
73 changes: 66 additions & 7 deletions monitor/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,38 @@

import AppKit
import Cocoa
import WidgetKit

class AppDelegate: NSObject, NSApplicationDelegate {
var networkBar: NetworkBar?
var nettop = Nettop()
static private(set) var instance: AppDelegate! = nil

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
if nettop.statusBar {
return false
}

WidgetCenter.shared.getCurrentConfigurations({ result in
switch result {
case let .success(widgets):
// 没有开启状态栏,且没有小组件。退出应用
if widgets.isEmpty {
DispatchQueue.main.async {
print("applicationShouldTerminateAfterLastWindowClosed")
self.exit()
}
}
case let .failure(error):
Log.shared.error("get widget configuration error \(error)")
}
})
return false
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
if networkBar == nil {
AppDelegate.instance = self
if networkBar == nil && nettop.statusBar {
networkBar = NetworkBar(networkTraffic: nettop)
networkBar?.setupMenu()
}
Expand All @@ -26,25 +51,59 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
nettop.rebuildCmdAndRestart()
NotificationCenter.default.addObserver(self, selector: #selector(resetStatusBar), name: .statusBarChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(switchStatusBar), name: .statusBarSwitchNotification, object: nil)
}

@objc func switchStatusBar() {
removeStatusBar()
if nettop.statusBar {
networkBar = NetworkBar(networkTraffic: nettop)
networkBar?.setupMenu()
}
}

@objc func resetStatusBar() {
if let item = networkBar?.networkMenuItem {
NSStatusBar.system.removeStatusItem(item)
networkBar = nil
if !nettop.statusBar {
return
}
self.removeStatusBar()
networkBar = NetworkBar(networkTraffic: nettop)
networkBar?.setupMenu()
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
return true
}

func applicationWillTerminate(_ aNotification: Notification) {
networkBar?.networkTraffic.stop()
exit()
}

func applicationWillBecomeActive(_ notification: Notification) {
private func removeStatusBar() {
if let item = networkBar?.networkMenuItem {
NSStatusBar.system.removeStatusItem(item)
}
networkBar = nil
}

func stop() {
Log.shared.info("stop.")
nettop.stop()
}

func start() {
self.stop()
self.nettop.start()
}

@objc func exit() {
self.stop()
NSApplication.shared.terminate(nil)
}

static func applicationExit() {
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
appDelegate.exit()
}
}
}
6 changes: 5 additions & 1 deletion monitor/controller/NetworkBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ class NetworkBar: NSObject, NSTableViewDataSource, NSTableViewDelegate {
mainWindow.isEnabled = true
menu.addItem(mainWindow)

let quitItem = NSMenuItem(title: "quit".localized, action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")
let quitItem = NSMenuItem(title: "quit".localized, action: #selector(AppDelegate.exit), keyEquivalent: "q")
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
quitItem.target = appDelegate
}

quitItem.keyEquivalentModifierMask = [.command]
quitItem.isEnabled = true
menu.addItem(quitItem)
Expand Down
Loading

0 comments on commit 7ad9132

Please sign in to comment.