AppDelegate.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //
  2. // AppDelegate.swift
  3. // google_apps
  4. //
  5. // Created by Dev Mac 1 on 27/03/2026.
  6. //
  7. import Cocoa
  8. @main
  9. class AppDelegate: NSObject, NSApplicationDelegate {
  10. private var statusItem: NSStatusItem?
  11. func applicationDidFinishLaunching(_ aNotification: Notification) {
  12. applyBundledAppIcon()
  13. configureMainWindowIfNeeded()
  14. setupStatusBarItem()
  15. StatusBarAppIconsController.shared.start()
  16. }
  17. private func applyBundledAppIcon() {
  18. if let assetAppIcon = NSImage(named: "AppIcon") {
  19. NSApp.applicationIconImage = assetAppIcon
  20. return
  21. }
  22. if let icnsURL = Bundle.main.url(forResource: "AppIcon", withExtension: "icns"),
  23. let icnsIcon = NSImage(contentsOf: icnsURL) {
  24. NSApp.applicationIconImage = icnsIcon
  25. }
  26. }
  27. private func setupStatusBarItem() {
  28. let item = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
  29. statusItem = item
  30. guard let button = item.button else { return }
  31. if let menuBarIcon = NSImage(named: "menu_bar_icon") {
  32. button.image = menuBarIcon
  33. button.image?.isTemplate = false
  34. } else {
  35. button.image = NSImage(systemSymbolName: "square.grid.2x2.fill", accessibilityDescription: "My Apps")
  36. button.image?.isTemplate = true
  37. }
  38. button.imageScaling = .scaleProportionallyDown
  39. button.imagePosition = .imageOnly
  40. button.action = #selector(statusBarButtonClicked(_:))
  41. button.target = self
  42. button.sendAction(on: [.leftMouseUp, .rightMouseUp])
  43. }
  44. @objc
  45. private func statusBarButtonClicked(_ sender: Any?) {
  46. guard let event = NSApp.currentEvent else {
  47. openMainWindowFromStatusBar()
  48. return
  49. }
  50. if event.type == .rightMouseUp {
  51. presentStatusBarShortcutsMenu()
  52. } else {
  53. openMainWindowFromStatusBar()
  54. }
  55. }
  56. private func presentStatusBarShortcutsMenu() {
  57. guard let button = statusItem?.button else { return }
  58. let menu = NSMenu()
  59. let openItem = NSMenuItem(
  60. title: "Open My Apps",
  61. action: #selector(openMainWindowFromStatusBar),
  62. keyEquivalent: ""
  63. )
  64. openItem.target = self
  65. menu.addItem(openItem)
  66. menu.addItem(.separator())
  67. let quitItem = NSMenuItem(
  68. title: "Quit",
  69. action: #selector(terminateApp),
  70. keyEquivalent: "q"
  71. )
  72. quitItem.target = self
  73. menu.addItem(quitItem)
  74. let location = NSPoint(x: 0, y: button.bounds.height)
  75. menu.popUp(positioning: nil, at: location, in: button)
  76. }
  77. @objc
  78. private func terminateApp() {
  79. NSApp.terminate(nil)
  80. }
  81. @objc
  82. private func openMainWindowFromStatusBar() {
  83. configureMainWindowIfNeeded()
  84. NSApp.setActivationPolicy(.regular)
  85. NSApp.activate(ignoringOtherApps: true)
  86. if let window = NSApp.windows.first {
  87. window.makeKeyAndOrderFront(nil)
  88. }
  89. }
  90. private func configureMainWindowIfNeeded() {
  91. guard let window = NSApp.windows.first else { return }
  92. window.title = "My Apps"
  93. window.isOpaque = false
  94. window.backgroundColor = .clear
  95. window.titlebarAppearsTransparent = true
  96. window.titleVisibility = .hidden
  97. window.styleMask.insert(.fullSizeContentView)
  98. window.isMovableByWindowBackground = true
  99. window.minSize = NSSize(width: 760, height: 520)
  100. let targetContentSize = NSSize(width: 980, height: 700)
  101. if window.contentRect(forFrameRect: window.frame).size.width < targetContentSize.width ||
  102. window.contentRect(forFrameRect: window.frame).size.height < targetContentSize.height {
  103. let currentCenter = NSPoint(x: window.frame.midX, y: window.frame.midY)
  104. var targetFrame = window.frameRect(forContentRect: NSRect(origin: .zero, size: targetContentSize))
  105. targetFrame.origin = NSPoint(
  106. x: currentCenter.x - (targetFrame.width / 2),
  107. y: currentCenter.y - (targetFrame.height / 2)
  108. )
  109. window.setFrame(targetFrame, display: true)
  110. }
  111. }
  112. func applicationWillTerminate(_ aNotification: Notification) {
  113. // Insert code here to tear down your application
  114. }
  115. func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
  116. return true
  117. }
  118. }