Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions SecVF.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
THBT002THBT002THBT002002 /* TacticalHoverButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = THBT001THBT001THBT001001 /* TacticalHoverButton.swift */; };
TTRV002TTRV002TTRV002002 /* TacticalTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = TTRV001TTRV001TTRV001001 /* TacticalTableRowView.swift */; };
TESV002TESV002TESV002002 /* TacticalEmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = TESV001TESV001TESV001001 /* TacticalEmptyStateView.swift */; };
ICMW002ICMW002ICMW002002 /* ISOCacheManagerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = ICMW001ICMW001ICMW001001 /* ISOCacheManagerWindow.swift */; };
SSWC002SSWC002SSWC002002 /* SwitchStatisticsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = SSWC001SSWC001SSWC001001 /* SwitchStatisticsWindowController.swift */; };
TSSC002TSSC002TSSC002002 /* TacticalSidebarSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = TSSC001TSSC001TSSC001001 /* TacticalSidebarSection.swift */; };
TTHC002TTHC002TTHC002002 /* TacticalTableHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = TTHC001TTHC001TTHC001001 /* TacticalTableHeaderCell.swift */; };
PCPR002PCPR002PCPR002002 /* PacketCaptureProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = PCPR001PCPR001PCPR001001 /* PacketCaptureProtocol.swift */; };
Expand Down Expand Up @@ -167,6 +169,8 @@
THBT001THBT001THBT001001 /* TacticalHoverButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalHoverButton.swift; sourceTree = "<group>"; };
TTRV001TTRV001TTRV001001 /* TacticalTableRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalTableRowView.swift; sourceTree = "<group>"; };
TESV001TESV001TESV001001 /* TacticalEmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalEmptyStateView.swift; sourceTree = "<group>"; };
ICMW001ICMW001ICMW001001 /* ISOCacheManagerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ISOCacheManagerWindow.swift; sourceTree = "<group>"; };
SSWC001SSWC001SSWC001001 /* SwitchStatisticsWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchStatisticsWindowController.swift; sourceTree = "<group>"; };
TSSC001TSSC001TSSC001001 /* TacticalSidebarSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalSidebarSection.swift; sourceTree = "<group>"; };
TTHC001TTHC001TTHC001001 /* TacticalTableHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalTableHeaderCell.swift; sourceTree = "<group>"; };
PCPR001PCPR001PCPR001001 /* PacketCaptureProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketCaptureProtocol.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -246,6 +250,8 @@
THBT001THBT001THBT001001 /* TacticalHoverButton.swift */,
TTRV001TTRV001TTRV001001 /* TacticalTableRowView.swift */,
TESV001TESV001TESV001001 /* TacticalEmptyStateView.swift */,
ICMW001ICMW001ICMW001001 /* ISOCacheManagerWindow.swift */,
SSWC001SSWC001SSWC001001 /* SwitchStatisticsWindowController.swift */,
TSSC001TSSC001TSSC001001 /* TacticalSidebarSection.swift */,
TTHC001TTHC001TTHC001001 /* TacticalTableHeaderCell.swift */,
NTNM001NTNM001NTNM001001 /* NotificationNames.swift */,
Expand Down Expand Up @@ -469,6 +475,8 @@
THBT002THBT002THBT002002 /* TacticalHoverButton.swift in Sources */,
TTRV002TTRV002TTRV002002 /* TacticalTableRowView.swift in Sources */,
TESV002TESV002TESV002002 /* TacticalEmptyStateView.swift in Sources */,
ICMW002ICMW002ICMW002002 /* ISOCacheManagerWindow.swift in Sources */,
SSWC002SSWC002SSWC002002 /* SwitchStatisticsWindowController.swift in Sources */,
TSSC002TSSC002TSSC002002 /* TacticalSidebarSection.swift in Sources */,
TTHC002TTHC002TTHC002002 /* TacticalTableHeaderCell.swift in Sources */,
NTNM002NTNM002NTNM002002 /* NotificationNames.swift in Sources */,
Expand Down
51 changes: 20 additions & 31 deletions SecVF/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, VZVirtualMachineDelegate, NS
private var attachScriptsUSBFlags: [UUID: Bool] = [:]

// Switch statistics window (retained to prevent deallocation)
// TODO: Uncomment when SwitchStatisticsWindowController.swift is added to Xcode project
// private var switchStatisticsWindow: SwitchStatisticsWindowController?
private var switchStatisticsWindow: SwitchStatisticsWindowController?

// Packet Analysis window (retained to prevent deallocation)
private var packetAnalysisWindow: PacketAnalysisWindowController?

// ISO Cache Manager window (retained to prevent deallocation)
// TODO: Add ISOCacheManagerWindow.swift to Xcode project
// private var isoCacheManagerWindow: ISOCacheManagerWindow?
private var isoCacheManagerWindow: ISOCacheManagerWindow?

// Splash screen (retained while showing)
private var splashScreen: SplashScreenWindow?
Expand Down Expand Up @@ -1681,36 +1679,27 @@ class AppDelegate: NSObject, NSApplicationDelegate, VZVirtualMachineDelegate, NS
}

@objc private func showISOCacheManager() {
// ISOCacheManagerWindow.swift exists in the repo but is not yet
// added to the Xcode project target. The menu item was previously
// a silent NSLog — surface an honest alert instead so the user
// isn't left wondering why nothing happened.
// TODO(pre-launch): wire ISOCacheManagerWindow into the Xcode
// project target and replace this alert with the real call site.
let alert = NSAlert()
alert.messageText = "ISO Cache Manager — coming soon"
alert.informativeText = "This feature is in development and not yet enabled in this build. For now, manage cached ISOs directly under ~/.avf/ISOCache/."
alert.alertStyle = .informational
alert.addButton(withTitle: "OK")
alert.runModal()
// ISOCacheManagerWindow is the proper UI for the on-disk
// ~/.avf/ISOCache/ contents: per-image checksum status,
// verify-all, clear-all, last-used dates. Lazy-instantiate +
// retain so the window survives across closes.
if isoCacheManagerWindow == nil || isoCacheManagerWindow?.window == nil {
isoCacheManagerWindow = ISOCacheManagerWindow()
}
isoCacheManagerWindow?.showWindow(nil)
isoCacheManagerWindow?.window?.makeKeyAndOrderFront(nil)
}

@objc private func showSwitchStatistics() {
// SwitchStatisticsWindowController.swift exists in the repo but
// is not yet added to the Xcode project target. Previously this
// dumped to stdout (invisible). Surface an honest alert + offer
// to print to Console as a fallback.
// TODO(pre-launch): wire SwitchStatisticsWindowController and
// replace this alert with the real call site.
let alert = NSAlert()
alert.messageText = "Switch Statistics window — coming soon"
alert.informativeText = "The in-app statistics window is in development. For now, current stats have been printed to the system log (Console.app, subsystem com.DaxxSec.SecVF)."
alert.alertStyle = .informational
alert.addButton(withTitle: "OK")
alert.runModal()

// Still emit to OSLog for users who know to look for it.
VirtualNetworkSwitch.shared.printStatistics()
// SwitchStatisticsWindowController owns the in-window view of
// VirtualNetworkSwitch.getStatistics() — per-port packet/byte
// counts plus the global running/MAC-learned/forwarded counters.
// Auto-refreshes every 2s while open.
if switchStatisticsWindow == nil || switchStatisticsWindow?.window == nil {
switchStatisticsWindow = SwitchStatisticsWindowController()
}
switchStatisticsWindow?.showWindow(nil)
switchStatisticsWindow?.window?.makeKeyAndOrderFront(nil)
}

// MARK: - Tools Menu Handlers
Expand Down
8 changes: 7 additions & 1 deletion SecVF/SwitchStatisticsWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ class SwitchStatisticsWindowController: NSWindowController {
}

deinit {
stopAutoRefresh()
// Tear down the refresh timer directly — `stopAutoRefresh` is
// main-actor isolated and can't be called from a nonisolated
// deinit. The Timer + nil-out are both safe from any thread
// (Timer.invalidate is documented thread-safe; the optional
// assignment doesn't touch UI state).
refreshTimer?.invalidate()
refreshTimer = nil
}

// MARK: - UI Setup
Expand Down
Loading