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
389 changes: 202 additions & 187 deletions LookInside.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// LKAboutWindowController.swift
// AboutWindowController.swift
// LookInside
//
// The About window: app icon, name, version, tagline and the license line
Expand All @@ -8,10 +8,9 @@

import AppKit

@objc(LKAboutWindowController)
final class LKAboutWindowController: LKWindowController {
final class AboutWindowController: WindowController {
@objc init() {
let window = LKWindow(contentRect: NSRect(x: 0, y: 0, width: 480, height: 460),
let window = AppWindow(contentRect: NSRect(x: 0, y: 0, width: 480, height: 460),
styleMask: [.titled, .closable, .fullSizeContentView],
backing: .buffered, defer: true)
window.isMovableByWindowBackground = true
Expand All @@ -22,7 +21,7 @@ final class LKAboutWindowController: LKWindowController {
window.center()

super.init(window: window)
let viewController = LKAboutViewController()
let viewController = AboutViewController()
window.contentView = viewController.view
contentViewController = viewController
}
Expand All @@ -33,14 +32,13 @@ final class LKAboutWindowController: LKWindowController {
}
}

@objc(LKAboutViewController)
final class LKAboutViewController: LKBaseViewController {
final class AboutViewController: BaseViewController {
private static let upstreamURL = "https://github.com/QMUI/LookinServer"
private static let homeURL = "https://lookinside-app.com"
private static let padding: CGFloat = 16

private var backgroundImageView: LKBaseView?
private var paperOverlayView: LKBaseView?
private var backgroundImageView: BaseView?
private var paperOverlayView: BaseView?
private var contentStackView: NSStackView?
private var legalTextView: NSTextView?

Expand All @@ -54,13 +52,13 @@ final class LKAboutViewController: LKBaseViewController {
}

override func makeContainerView() -> NSView {
let containerView = LKBaseView()
containerView.backgroundColors = LKTwoColors(
let containerView = BaseView()
containerView.backgroundColors = TwoColors(
colorInLightMode: NSColor(calibratedRed: 0.99, green: 0.97, blue: 0.93, alpha: 1),
colorInDarkMode: NSColor(calibratedWhite: 0.10, alpha: 1)
)

let backgroundImageView = LKBaseView()
let backgroundImageView = BaseView()
backgroundImageView.wantsLayer = true
backgroundImageView.layer?.contents = NSImage(named: "aboutHeroBg")
backgroundImageView.layer?.contentsGravity = .resizeAspectFill
Expand All @@ -69,8 +67,8 @@ final class LKAboutViewController: LKBaseViewController {
containerView.addSubview(backgroundImageView)
self.backgroundImageView = backgroundImageView

let paperOverlayView = LKBaseView()
paperOverlayView.backgroundColors = LKTwoColors(
let paperOverlayView = BaseView()
paperOverlayView.backgroundColors = TwoColors(
colorInLightMode: NSColor(calibratedRed: 0.99, green: 0.97, blue: 0.93, alpha: 0.55),
colorInDarkMode: NSColor(calibratedWhite: 0.10, alpha: 0.55)
)
Expand All @@ -88,31 +86,31 @@ final class LKAboutViewController: LKBaseViewController {
?? NSFont.systemFont(ofSize: 30, weight: .regular)
let footnoteFont = NSFont.preferredFont(forTextStyle: .footnote, options: [:])

let titleLabel = LKLabel()
let titleLabel = TextLabel()
titleLabel.stringValue = "LookInside"
titleLabel.textColors = LKTwoColors(colorInLightMode: NSColor(calibratedWhite: 0.12, alpha: 1),
titleLabel.textColors = TwoColors(colorInLightMode: NSColor(calibratedWhite: 0.12, alpha: 1),
colorInDarkMode: NSColor(calibratedWhite: 0.96, alpha: 1))
titleLabel.font = titleFont

let info = Bundle.main.infoDictionary
let dotVersion = info?["CFBundleShortVersionString"] as? String ?? "(null)"
let numberVersion = info?["CFBundleVersion"] as? String ?? "(null)"
let versionLabel = LKLabel()
let versionLabel = TextLabel()
versionLabel.stringValue = String(
format: NSLocalizedString("Version %1$@ (%2$@)", comment: "About window version line: marketing version, build number"),
dotVersion,
numberVersion
)
versionLabel.textColors = LKTwoColors(colorInLightMode: NSColor(calibratedWhite: 0.35, alpha: 1),
versionLabel.textColors = TwoColors(colorInLightMode: NSColor(calibratedWhite: 0.35, alpha: 1),
colorInDarkMode: NSColor(calibratedWhite: 0.78, alpha: 1))
versionLabel.font = footnoteFont

let taglineLabel = LKLabel()
let taglineLabel = TextLabel()
taglineLabel.stringValue = NSLocalizedString(
"A SwiftUI- and UIKit-aware view debugger.\nWalk every layer. Read every modifier.",
comment: "About window tagline, two lines"
)
taglineLabel.textColors = LKTwoColors(colorInLightMode: NSColor(calibratedWhite: 0.30, alpha: 1),
taglineLabel.textColors = TwoColors(colorInLightMode: NSColor(calibratedWhite: 0.30, alpha: 1),
colorInDarkMode: NSColor(calibratedWhite: 0.82, alpha: 1))
taglineLabel.font = footnoteFont
taglineLabel.alignment = .center
Expand Down
48 changes: 25 additions & 23 deletions LookInside/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//

import AppKit
import FoundationToolbox

@Loggable(subsystem: "com.lookinside.app")
@main
@objc(AppDelegate)
@MainActor
Expand All @@ -23,7 +25,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
#if DEBUG
// Before the delegate is set, so the dump observes the end of
// launching ahead of it, as its Objective-C +load did.
LKDebugE2EDump.installIfRequested()
DebugE2EDump.installIfRequested()
#endif
let delegate = AppDelegate()
NSApplication.shared.delegate = delegate
Expand All @@ -33,16 +35,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationWillFinishLaunching(_: Notification) {
LKAppMenuManager.shared.setup()
AppMenuManager.shared.setup()

appearanceObservation = LKPreferenceManager.shared.observe(\.appearanceType, options: [.initial, .new]) { manager, _ in
appearanceObservation = PreferenceManager.shared.observe(\.appearanceType, options: [.initial, .new]) { manager, _ in
MainActor.assumeIsolated {
Self.applyAppearance(manager.appearanceType)
}
}
}

private static func applyAppearance(_ type: LookinPreferredAppeanranceType) {
private static func applyAppearance(_ type: PreferredAppearanceType) {
switch type {
case .dark:
NSApp.appearance = NSAppearance(named: .darkAqua)
Expand All @@ -54,20 +56,20 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationDidFinishLaunching(_: Notification) {
_ = LKConnectionManager.shared
LKMCPBridgeServer.sharedInstance.start()
_ = ConnectionManager.shared
MCPBridgeServer.sharedInstance.start()
// Documents opened during launch (Finder double-click, Open With…)
// are registered with NSDocumentController by now, so "no documents
// ⇒ show Launch" covers both cold-start cases.
if NSDocumentController.shared.documents.isEmpty {
var allowAutoEnter = true
#if DEBUG
// The end-to-end dump (LKDebugE2EDump.swift) opens the app itself; an
// The end-to-end dump (DebugE2EDump.swift) opens the app itself; an
// activated Host's auto-enter would fetch the same hierarchy
// alongside it.
allowAutoEnter = (ProcessInfo.processInfo.environment["LOOKINSIDE_DEBUG_E2E_DUMP_DIR"] ?? "").isEmpty
#endif
LKNavigationManager.shared.showLaunch(allowingAutoEnter: allowAutoEnter)
NavigationManager.shared.showLaunch(allowingAutoEnter: allowAutoEnter)
}

installActivationStateObserver()
Expand All @@ -88,13 +90,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate {

@objc private func handleWindowWillClose(_ notification: Notification) {
guard let closingWindow = notification.object as? NSWindow,
closingWindow.windowController is LKWindowController
closingWindow.windowController is WindowController
else {
return
}
// Closing the Launch window itself shouldn't re-spawn Launch; only
// document (live / archive) windows trigger the "no docs left" reopen.
if closingWindow == LKNavigationManager.shared.launchWindowController?.window {
if closingWindow == NavigationManager.shared.launchWindowController?.window {
return
}
// Defer one tick so NSDocumentController has finished removing the doc.
Expand All @@ -107,34 +109,34 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
guard NSDocumentController.shared.documents.isEmpty else {
return
}
if LKNavigationManager.shared.launchWindowController?.window?.isVisible == true {
if NavigationManager.shared.launchWindowController?.window?.isVisible == true {
return
}
LKNavigationManager.shared.showLaunch()
NavigationManager.shared.showLaunch()
}

private func installActivationStateObserver() {
let gatekeeper = LKSwiftUISupportGatekeeper.sharedInstance()
NSLog("[LK-Activation] initial state=%ld (re-evaluated every 60s in process)", gatekeeper.activationState.rawValue)
let gatekeeper = SwiftUISupportGatekeeper.sharedInstance()
#log(.default, "[LK-Activation] initial state=\(gatekeeper.activationState.rawValue, privacy: .public) (re-evaluated every 60s in process)")

NotificationCenter.default.addObserver(
self,
selector: #selector(activationStateDidChange(_:)),
name: NSNotification.Name(LKSwiftUISupportGatekeeper.activationStateDidChangeNotificationName as String),
name: NSNotification.Name(SwiftUISupportGatekeeper.activationStateDidChangeNotificationName as String),
object: nil
)
}

@objc private func activationStateDidChange(_ notification: Notification) {
let state = notification.userInfo?["activationState"] as? NSNumber
let label: String
switch state.flatMap({ LKSwiftUISupportActivationState(rawValue: $0.intValue) }) {
switch state.flatMap({ SwiftUISupportActivationState(rawValue: $0.intValue) }) {
case .unknown: label = "unknown"
case .notActivated: label = "notActivated"
case .activated: label = "activated"
default: label = "(null)"
}
NSLog("[LK-Activation] state changed -> %@ (raw=%@)", label, state?.description ?? "(null)")
#log(.default, "[LK-Activation] state changed -> \(label, privacy: .public) (raw=\(state?.description ?? "(null)", privacy: .public))")
}

func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool {
Expand Down Expand Up @@ -176,11 +178,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationShouldTerminate(_: NSApplication) -> NSApplication.TerminateReply {
LKSwiftUISupportGatekeeper.sharedInstance().shutdownRuntime()
LKMCPBridgeServer.sharedInstance.stop()
SwiftUISupportGatekeeper.sharedInstance().shutdownRuntime()
MCPBridgeServer.sharedInstance.stop()

// 清理打开 UIImageView 的图片时创建的临时文件
for path in LKHelper.sharedInstance().tempImageFiles {
for path in AppHelper.sharedInstance().tempImageFiles {
do {
try FileManager.default.removeItem(atPath: path)
} catch {
Expand All @@ -194,13 +196,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
/// The dashboard blueprint's group, section and attribute identifiers
/// must each be unique.
private static func checkDashboardBlueprintIdentifiers() {
let groupIDs = LookinDashboardBlueprint.groupIDs().map { $0 as String }
let groupIDs = DashboardBlueprint.groupIDs()
assert(Set(groupIDs).count == groupIDs.count, "duplicate LookinAttrGroupIdentifier")

let sectionIDs = groupIDs.flatMap { LookinDashboardBlueprint.sectionIDs(forGroupID: $0).map { $0 as String } }
let sectionIDs = groupIDs.flatMap { DashboardBlueprint.sectionIDs(forGroupID: $0) ?? [] }
assert(Set(sectionIDs).count == sectionIDs.count, "duplicate LookinAttrSectionIdentifier")

let attrIDs = sectionIDs.flatMap { LookinDashboardBlueprint.attrIDs(forSectionID: $0).map { $0 as String } }
let attrIDs = sectionIDs.flatMap { DashboardBlueprint.attrIDs(forSectionID: $0) ?? [] }
assert(Set(attrIDs).count == attrIDs.count, "duplicate LookinAttrIdentifier")
}
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
//
// LKWindow.swift
// AppWindow.swift
// LookInside
//

import AppKit

/// The app's window class: dropping a file onto it opens it in the reader.
@objc(LKWindow)
class LKWindow: NSWindow {
class AppWindow: NSWindow {
override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag)
registerForDraggedTypes([.fileURL])
Expand All @@ -22,7 +21,7 @@ class LKWindow: NSWindow {
return false
}
do {
try LKNavigationManager.shared.showReader(withFilePath: path)
try NavigationManager.shared.showReader(withFilePath: path)
return true
} catch {
let nsError = error as NSError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// LKBaseControl.swift
// BaseControl.swift
// Lookin
//
// Created by Li Kai on 2018/8/28.
Expand All @@ -8,13 +8,12 @@

import AppKit

@objc(LKBaseControl)
class LKBaseControl: NSControl {
class BaseControl: NSControl {
@objc var clickAction: Selector?

@objc var adjustAlphaWhenClick = false

@objc var didChangeAppearance: ((LKBaseControl?, Bool) -> Void)? {
@objc var didChangeAppearance: ((BaseControl?, Bool) -> Void)? {
didSet {
triggerDidChangeAppearanceBlock()
}
Expand Down Expand Up @@ -66,12 +65,12 @@ class LKBaseControl: NSControl {

private func triggerDidChangeAppearanceBlock() {
if let didChangeAppearance {
didChangeAppearance(self, effectiveAppearance.lk_isDarkMode)
didChangeAppearance(self, effectiveAppearance.isDarkMode)
}
}

override func sizeToFit() {
lkLayout.size(bestSize())
frameLayout.size(bestSize())
}

/// 如果子类返回 true,则 mouseEntered: 和 mouseExited: 会被调用。默认为 false
Expand Down
Loading
Loading