Skip to content

Commit 684f371

Browse files
committed
Fix items not properly hidden prior to macOS 14
1 parent 449bf10 commit 684f371

File tree

8 files changed

+149
-63
lines changed

8 files changed

+149
-63
lines changed

HeliPort.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
505EC11D2C5BD89400F4E4EA /* StatusBarIconManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC11C2C5BD89400F4E4EA /* StatusBarIconManager.swift */; };
3030
505EC11F2C5BD8ED00F4E4EA /* StatusBarIconLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC11E2C5BD8ED00F4E4EA /* StatusBarIconLegacy.swift */; };
3131
505EC1212C5BD95700F4E4EA /* StatusBarIconModern.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC1202C5BD95700F4E4EA /* StatusBarIconModern.swift */; };
32+
50680FCA2C5FDB75008AF10F /* HidableMenuItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50680FC92C5FDB75008AF10F /* HidableMenuItemView.swift */; };
33+
5068784E2C5FE16C0046150A /* HPMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5068784D2C5FE16C0046150A /* HPMenuItem.swift */; };
3234
5088F70826BEA46F009E3A15 /* KextInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5088F70726BEA46F009E3A15 /* KextInfo.swift */; };
3335
50C5F2D027C23074009E3F68 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 50C5F2CF27C23074009E3F68 /* KeychainAccess */; };
3436
50C5F2D327C230D6009E3F68 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 50C5F2D227C230D6009E3F68 /* Sparkle */; };
@@ -93,6 +95,8 @@
9395
505EC11C2C5BD89400F4E4EA /* StatusBarIconManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarIconManager.swift; sourceTree = "<group>"; };
9496
505EC11E2C5BD8ED00F4E4EA /* StatusBarIconLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarIconLegacy.swift; sourceTree = "<group>"; };
9597
505EC1202C5BD95700F4E4EA /* StatusBarIconModern.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarIconModern.swift; sourceTree = "<group>"; };
98+
50680FC92C5FDB75008AF10F /* HidableMenuItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HidableMenuItemView.swift; sourceTree = "<group>"; };
99+
5068784D2C5FE16C0046150A /* HPMenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HPMenuItem.swift; sourceTree = "<group>"; };
96100
5088F70726BEA46F009E3A15 /* KextInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KextInfo.swift; sourceTree = "<group>"; };
97101
50E7700E2C5A7CD600DB1160 /* UpdateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateManager.swift; sourceTree = "<group>"; };
98102
50F4959724BDD26D00AE4C08 /* LoginItemManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginItemManager.swift; sourceTree = "<group>"; };
@@ -159,6 +163,7 @@
159163
isa = PBXGroup;
160164
children = (
161165
5013B9052C5E1ED5002C5006 /* MenuItemView */,
166+
5068784D2C5FE16C0046150A /* HPMenuItem.swift */,
162167
5013B8FF2C5E1E00002C5006 /* StatusMenuBase.swift */,
163168
5013B9012C5E1E36002C5006 /* StatusMenuLegacy.swift */,
164169
5013B9032C5E1EA9002C5006 /* StatusMenuModern.swift */,
@@ -169,6 +174,7 @@
169174
5013B9052C5E1ED5002C5006 /* MenuItemView */ = {
170175
isa = PBXGroup;
171176
children = (
177+
50680FC92C5FDB75008AF10F /* HidableMenuItemView.swift */,
172178
5013B9062C5E1EF2002C5006 /* KeyValueMenuItemView.swift */,
173179
5013B9082C5E1FF4002C5006 /* SectionMenuItemView.swift */,
174180
5013B90A2C5E2029002C5006 /* SelectableMenuItemView.swift */,
@@ -447,6 +453,7 @@
447453
75FDF38C2481D25A00B2A601 /* Api.c in Sources */,
448454
F379276F24A0A4A50087FF2B /* CredentialsManager.swift in Sources */,
449455
F336D63C24B497B6004C98C4 /* NetworkManager+Data.swift in Sources */,
456+
5068784E2C5FE16C0046150A /* HPMenuItem.swift in Sources */,
450457
5013B9102C5E2265002C5006 /* WiFiMenuItemViewLegacy.swift in Sources */,
451458
F33A1F3F24C8347F008ED2BD /* NSLocalizedString+Extensions.swift in Sources */,
452459
F379277124A0A52E0087FF2B /* Log.swift in Sources */,
@@ -462,6 +469,7 @@
462469
5013B9002C5E1E00002C5006 /* StatusMenuBase.swift in Sources */,
463470
505EC1212C5BD95700F4E4EA /* StatusBarIconModern.swift in Sources */,
464471
BCFA32EB2424D2BE00E23603 /* AppDelegate.swift in Sources */,
472+
50680FCA2C5FDB75008AF10F /* HidableMenuItemView.swift in Sources */,
465473
5013B9072C5E1EF2002C5006 /* KeyValueMenuItemView.swift in Sources */,
466474
BCCB2AA4243708090005BB82 /* WiFiMenuItemView.swift in Sources */,
467475
1380C36124D54BFD00A448CF /* PrefsSavedNetworksView.swift in Sources */,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// HPMenuItem.swift
3+
// HeliPort
4+
//
5+
// Created by Bat.bat on 5/8/2024.
6+
// Copyright © 2024 OpenIntelWireless. All rights reserved.
7+
//
8+
9+
/*
10+
* This program and the accompanying materials are licensed and made available
11+
* under the terms and conditions of the The 3-Clause BSD License
12+
* which accompanies this distribution. The full text of the license may be found at
13+
* https://opensource.org/licenses/BSD-3-Clause
14+
*/
15+
16+
import Cocoa
17+
18+
/// Use this class instead of `NSMenuItem` when applying a custom view
19+
class HPMenuItem: NSMenuItem {
20+
21+
var highlightable: Bool = false
22+
23+
convenience init(highlightable: Bool = false) {
24+
self.init()
25+
self.highlightable = highlightable
26+
}
27+
28+
required init(coder: NSCoder) {
29+
fatalError("init(coder:) has not been implemented")
30+
}
31+
32+
override init(title string: String, action selector: Selector?, keyEquivalent charCode: String) {
33+
super.init(title: string, action: selector, keyEquivalent: charCode)
34+
}
35+
36+
override var isHidden: Bool {
37+
willSet {
38+
(self.view as? HidableMenuItemView)?.visible = !newValue
39+
}
40+
}
41+
42+
override func _canBeHighlighted() -> Bool {
43+
return highlightable || super._canBeHighlighted()
44+
}
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// HidableMenuItemView.swift
3+
// HeliPort
4+
//
5+
// Created by Bat.bat on 5/8/2024.
6+
// Copyright © 2024 OpenIntelWireless. All rights reserved.
7+
//
8+
9+
/*
10+
* This program and the accompanying materials are licensed and made available
11+
* under the terms and conditions of the The 3-Clause BSD License
12+
* which accompanies this distribution. The full text of the license may be found at
13+
* https://opensource.org/licenses/BSD-3-Clause
14+
*/
15+
16+
class HidableMenuItemView: NSView {
17+
private let height: CGFloat
18+
private var heightConstraint: NSLayoutConstraint!
19+
20+
var visible: Bool = true {
21+
willSet(visible) {
22+
// Manually adjust visibility for item views prior to macOS 14
23+
if #unavailable(macOS 14) {
24+
isHidden = !visible
25+
heightConstraint.constant = visible ? height : 0
26+
layoutSubtreeIfNeeded()
27+
}
28+
}
29+
}
30+
31+
init(height: NSMenuItem.ItemHeight) {
32+
self.height = height.rawValue
33+
super.init(frame: .zero)
34+
35+
translatesAutoresizingMaskIntoConstraints = false
36+
37+
heightConstraint = heightAnchor.constraint(equalToConstant: height.rawValue)
38+
heightConstraint.priority = NSLayoutConstraint.Priority(rawValue: 1000)
39+
heightConstraint.isActive = true
40+
}
41+
42+
required init?(coder: NSCoder) {
43+
fatalError("init(coder:) has not been implemented")
44+
}
45+
}

HeliPort/Appearance/StatusMenu/MenuItemView/KeyValueMenuItemView.swift

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import Cocoa
1717

18-
class KeyValueMenuItemView: NSView {
18+
class KeyValueMenuItemView: HidableMenuItemView {
1919

2020
enum Inset: CGFloat {
2121
case standard = 14
@@ -34,7 +34,14 @@ class KeyValueMenuItemView: NSView {
3434
valueLabel.font = NSFont.systemFont(ofSize: 12, weight: .regular)
3535
valueLabel.textColor = .secondaryLabelColor
3636

37-
super.init(frame: .zero)
37+
let height = {
38+
if #available(macOS 11, *) {
39+
return NSMenuItem.ItemHeight.textModern
40+
}
41+
return NSMenuItem.ItemHeight.textLegacy
42+
}()
43+
44+
super.init(height: height)
3845
addSubview(keyLabel)
3946
addSubview(valueLabel)
4047

@@ -45,15 +52,7 @@ class KeyValueMenuItemView: NSView {
4552
keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
4653
valueLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
4754

48-
let height = {
49-
if #available(macOS 11, *) {
50-
return NSMenuItem.ItemHeight.textModern
51-
}
52-
return NSMenuItem.ItemHeight.textLegacy
53-
}()
54-
5555
NSLayoutConstraint.activate([
56-
heightAnchor.constraint(equalToConstant: height.rawValue),
5756
keyLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
5857
keyLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: inset.rawValue),
5958
valueLabel.centerYAnchor.constraint(equalTo: centerYAnchor),

HeliPort/Appearance/StatusMenu/MenuItemView/SelectableMenuItemView.swift

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,7 @@
1515

1616
import Cocoa
1717

18-
class SelectableMenuItem: NSMenuItem {
19-
override func _canBeHighlighted() -> Bool {
20-
return true
21-
}
22-
}
23-
24-
class SelectableMenuItemView: NSView {
18+
class SelectableMenuItemView: HidableMenuItemView {
2519

2620
private class HoverView: NSView {
2721
override func draw(_ dirtyRect: NSRect) {
@@ -34,8 +28,6 @@ class SelectableMenuItemView: NSView {
3428
// MARK: Initializers
3529

3630
private var currentWindow: NSWindow?
37-
private var heightConstraint: NSLayoutConstraint!
38-
3931
private let effectView: NSView?
4032

4133
private let effectPadding: CGFloat = {
@@ -45,10 +37,7 @@ class SelectableMenuItemView: NSView {
4537
return 0
4638
}()
4739

48-
private let height: CGFloat
49-
5040
init(height: NSMenuItem.ItemHeight, hoverStyle: HoverStyle) {
51-
self.height = height.rawValue
5241
switch hoverStyle {
5342
case .none:
5443
effectView = nil
@@ -64,7 +53,7 @@ class SelectableMenuItemView: NSView {
6453
effectView = view
6554
}
6655

67-
super.init(frame: .zero)
56+
super.init(height: height)
6857
if let view = effectView { self.addSubview(view) }
6958
}
7059

@@ -74,20 +63,18 @@ class SelectableMenuItemView: NSView {
7463

7564
// MARK: Public
7665

77-
public enum HoverStyle {
66+
enum HoverStyle {
7867
case none
7968
case selection
8069
case greytint
8170
}
8271

83-
public func checkHighlight() {
72+
func checkHighlight() {
8473
if effectView != nil, let position = currentWindow?.mouseLocationOutsideOfEventStream {
8574
isMouseOver = bounds.contains(convert(position, from: nil))
8675
}
8776
}
8877

89-
// MARK: Internal
90-
9178
var isMouseOver: Bool = false {
9279
willSet(hover) {
9380
if let view = effectView as? NSVisualEffectView {
@@ -108,10 +95,6 @@ class SelectableMenuItemView: NSView {
10895
effectView?.layer?.masksToBounds = true
10996
}
11097

111-
heightConstraint = heightAnchor.constraint(equalToConstant: self.height)
112-
heightConstraint.priority = NSLayoutConstraint.Priority(rawValue: 1000)
113-
heightConstraint.isActive = true
114-
11598
effectView?.translatesAutoresizingMaskIntoConstraints = false
11699
effectView?.subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
117100
effectView?.leftAnchor.constraint(equalTo: self.leftAnchor, constant: effectPadding).isActive = true

HeliPort/Appearance/StatusMenu/StatusMenuBase.swift

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -132,47 +132,47 @@ class StatusMenuBase: NSMenu, NSMenuDelegate {
132132

133133
// - MARK: Common Menu items
134134

135-
let bsdItem = NSMenuItem(title: .interfaceName)
136-
let macItem = NSMenuItem(title: .macAddress)
137-
let itlwmVerItem = NSMenuItem(title: .itlwmVer)
135+
let bsdItem = HPMenuItem(title: .interfaceName)
136+
let macItem = HPMenuItem(title: .macAddress)
137+
let itlwmVerItem = HPMenuItem(title: .itlwmVer)
138138

139-
let enableLoggingItem = NSMenuItem(title: .enableWiFiLog)
140-
let createReportItem = NSMenuItem(title: .createReport)
141-
let diagnoseItem = NSMenuItem(title: .openDiagnostics)
139+
let enableLoggingItem = HPMenuItem(title: .enableWiFiLog)
140+
let createReportItem = HPMenuItem(title: .createReport)
141+
let diagnoseItem = HPMenuItem(title: .openDiagnostics)
142142
let hardwareInfoSeparator = NSMenuItem.separator()
143143

144144
let networkItemListSeparator = NSMenuItem.separator()
145145

146-
let aboutItem = NSMenuItem(title: .aboutHeliport)
146+
let aboutItem = HPMenuItem(title: .aboutHeliport)
147147
let checkUpdateItem = {
148-
let item = NSMenuItem(title: .checkUpdates)
148+
let item = HPMenuItem(title: .checkUpdates)
149149
item.target = UpdateManager.sharedController
150150
item.action = #selector(SPUStandardUpdaterController.checkForUpdates(_:))
151151
return item
152152
}()
153153
let quitSeparator = NSMenuItem.separator()
154-
let quitItem = NSMenuItem(title: .quitHeliport,
154+
let quitItem = HPMenuItem(title: .quitHeliport,
155155
action: #selector(clickMenuItem(_:)), keyEquivalent: "q")
156156

157-
let toggleLaunchItem = NSMenuItem(title: .launchLogin,
157+
let toggleLaunchItem = HPMenuItem(title: .launchLogin,
158158
action: #selector(clickMenuItem(_:)))
159159

160160
// MARK: - WiFi connected items
161161

162-
let currentNetworkItem = SelectableMenuItem()
163-
let ipAddresssItem = NSMenuItem(title: .ipAddr)
164-
let routerItem = NSMenuItem(title: .routerStr)
165-
let internetItem = NSMenuItem(title: .internetStr)
166-
let securityItem = NSMenuItem(title: .securityStr)
167-
let bssidItem = NSMenuItem(title: .bssidStr)
168-
let channelItem = NSMenuItem(title: .channelStr)
169-
let countryCodeItem = NSMenuItem(title: .countryCodeStr)
170-
let rssiItem = NSMenuItem(title: .rssiStr)
171-
let noiseItem = NSMenuItem(title: .noiseStr)
172-
let txRateItem = NSMenuItem(title: .txRateStr)
173-
let phyModeItem = NSMenuItem(title: .phyModeStr)
174-
let mcsIndexItem = NSMenuItem(title: .mcsStr)
175-
let nssItem = NSMenuItem(title: .nssStr)
162+
let currentNetworkItem = HPMenuItem(highlightable: true)
163+
let ipAddresssItem = HPMenuItem(title: .ipAddr)
164+
let routerItem = HPMenuItem(title: .routerStr)
165+
let internetItem = HPMenuItem(title: .internetStr)
166+
let securityItem = HPMenuItem(title: .securityStr)
167+
let bssidItem = HPMenuItem(title: .bssidStr)
168+
let channelItem = HPMenuItem(title: .channelStr)
169+
let countryCodeItem = HPMenuItem(title: .countryCodeStr)
170+
let rssiItem = HPMenuItem(title: .rssiStr)
171+
let noiseItem = HPMenuItem(title: .noiseStr)
172+
let txRateItem = HPMenuItem(title: .txRateStr)
173+
let phyModeItem = HPMenuItem(title: .phyModeStr)
174+
let mcsIndexItem = HPMenuItem(title: .mcsStr)
175+
let nssItem = HPMenuItem(title: .nssStr)
176176

177177
// - MARK: Init
178178

@@ -245,7 +245,9 @@ class StatusMenuBase: NSMenu, NSMenuDelegate {
245245
addItem(item)
246246
}
247247

248-
func addNetworkItem(_ item: NSMenuItem = SelectableMenuItem(), insertAt: Int? = nil, hidden: Bool = false,
248+
func addNetworkItem(_ item: NSMenuItem = HPMenuItem(highlightable: true),
249+
insertAt: Int? = nil,
250+
hidden: Bool = false,
249251
networkInfo: NetworkInfo = NetworkInfo(ssid: "placeholder")) -> NSMenuItem {
250252
item.isHidden = hidden
251253

HeliPort/Appearance/StatusMenu/StatusMenuLegacy.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@ final class StatusMenuLegacy: StatusMenuBase, StatusMenuItems {
198198

199199
// - MARK: Overrides
200200

201-
override func addNetworkItem(_ item: NSMenuItem = SelectableMenuItem(), insertAt: Int? = nil, hidden: Bool = false,
201+
override func addNetworkItem(_ item: NSMenuItem = HPMenuItem(highlightable: true),
202+
insertAt: Int? = nil,
203+
hidden: Bool = false,
202204
networkInfo: NetworkInfo = NetworkInfo(ssid: "placeholder")) -> NSMenuItem {
203205
item.view = WifiMenuItemViewLegacy(networkInfo: networkInfo)
204206

0 commit comments

Comments
 (0)