diff --git a/MewNotch.xcodeproj/project.pbxproj b/MewNotch.xcodeproj/project.pbxproj index 94cddf2..32625ab 100644 --- a/MewNotch.xcodeproj/project.pbxproj +++ b/MewNotch.xcodeproj/project.pbxproj @@ -275,7 +275,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 0.1; + MARKETING_VERSION = 0.2; PRODUCT_BUNDLE_IDENTIFIER = com.monuk7735.mew.notch; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -306,7 +306,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 0.1; + MARKETING_VERSION = 0.2; PRODUCT_BUNDLE_IDENTIFIER = com.monuk7735.mew.notch; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/MewNotch/DB/MewDefaultsManager.swift b/MewNotch/DB/MewDefaultsManager.swift index 7ae809a..dc99a39 100644 --- a/MewNotch/DB/MewDefaultsManager.swift +++ b/MewNotch/DB/MewDefaultsManager.swift @@ -10,25 +10,20 @@ import SwiftUI class MewDefaultsManager: ObservableObject { @propertyWrapper - public struct RawEnumUserDefault where T: RawRepresentable { + public struct CodableUserDefault where T: Codable { let key: String let defaultValue: T let suiteName: String? - let initializer: (T.RawValue) -> T? - public init( _ key: String, defaultValue: T, - suiteName: String? = nil, - initializer: @escaping (T.RawValue) -> T? + suiteName: String? = nil ) { self.key = key self.defaultValue = defaultValue self.suiteName = suiteName - - self.initializer = initializer } public var wrappedValue: T { @@ -37,10 +32,12 @@ class MewDefaultsManager: ObservableObject { suiteName: suiteName! ): UserDefaults.standard - return self.initializer( - defaults?.object( - forKey: key - ) as? T.RawValue ?? defaultValue.rawValue + guard let data = defaults?.data(forKey: key) else { + return defaultValue + } + + return ( + try? JSONDecoder().decode(T.self, from: data) ) ?? defaultValue } set { @@ -48,10 +45,9 @@ class MewDefaultsManager: ObservableObject { suiteName: suiteName! ): UserDefaults.standard - defaults?.set( - newValue.rawValue, - forKey: key - ) + let encoded = try? JSONEncoder().encode(newValue) + + defaults?.set(encoded, forKey: key) } } } @@ -93,14 +89,44 @@ class MewDefaultsManager: ObservableObject { private let userDefaults: UserDefaults = .standard - // MARK: Variables + // MARK: Enums + public enum NotchHeightMode: String, CaseIterable, Identifiable, Codable { + var id: String { rawValue } + + case Match_Notch + case Match_Menu_Bar + case Manual + } - enum HUDStyle: String, CaseIterable, Identifiable, Codable { + public enum HUDStyle: String, CaseIterable, Identifiable, Codable { var id: String { rawValue } - case minimal - case progress - case notched + case Minimal + case Progress + case Notched + } + + + // MARK: Variables + + @UserDefault( + "NotchForceEnabled", + defaultValue: false + ) + var notchForceEnabled: Bool { + didSet { + self.objectWillChange.send() + } + } + + @CodableUserDefault( + "NotchHeightMode", + defaultValue: NotchHeightMode.Match_Notch + ) + var notchHeightMode: NotchHeightMode { + didSet { + self.objectWillChange.send() + } } @UserDefault( @@ -113,14 +139,9 @@ class MewDefaultsManager: ObservableObject { } } - @RawEnumUserDefault( + @CodableUserDefault( "HUDStyle", - defaultValue: HUDStyle.minimal, - initializer: { - return HUDStyle.init( - rawValue: $0 - ) - } + defaultValue: HUDStyle.Minimal ) var hudStyle: HUDStyle { didSet { diff --git a/MewNotch/MewAppDelegate.swift b/MewNotch/MewAppDelegate.swift index 9e4fbba..2c25f5b 100644 --- a/MewNotch/MewAppDelegate.swift +++ b/MewNotch/MewAppDelegate.swift @@ -47,29 +47,35 @@ class MewAppDelegate: NSObject, NSApplicationDelegate { guard let screen = NSScreen.main else { return } - let view: NSView = NSHostingView( - rootView: NotchView() - ) - - let panel = MewPanel( - contentRect: .zero, - styleMask: [ - .borderless, - .nonactivatingPanel - ], - backing: .buffered, - defer: true - ) - - panel.contentView = view - panel.orderFrontRegardless() + var panel: NSWindow! = windows[screen] - panel.setFrame( - screen.frame, - display: true - ) - - NotchSpaceManager.shared.notchSpace.windows.insert(panel) + if panel == nil { + let view: NSView = NSHostingView( + rootView: NotchView() + ) + + panel = MewPanel( + contentRect: .zero, + styleMask: [ + .borderless, + .nonactivatingPanel + ], + backing: .buffered, + defer: true + ) + + panel.contentView = view + + panel.orderFrontRegardless() + + panel.setFrame( + screen.frame, + display: true + ) + + self.windows[screen] = panel + NotchSpaceManager.shared.notchSpace.windows.insert(panel) + } // self.createStatusItem() } diff --git a/MewNotch/Utils/NotchUtils.swift b/MewNotch/Utils/NotchUtils.swift index 63bf2b5..81704bf 100644 --- a/MewNotch/Utils/NotchUtils.swift +++ b/MewNotch/Utils/NotchUtils.swift @@ -55,6 +55,10 @@ class NotchUtils { } notchHeight = screen.safeAreaInsets.top + + if MewDefaultsManager.shared.notchHeightMode == .Match_Menu_Bar { + notchHeight = screen.frame.maxY - screen.visibleFrame.maxY + } return .init( width: notchWidth, diff --git a/MewNotch/View/Notch/Collapsed/CollapsedNotchView.swift b/MewNotch/View/Notch/Collapsed/CollapsedNotchView.swift index e19fea6..2898be8 100644 --- a/MewNotch/View/Notch/Collapsed/CollapsedNotchView.swift +++ b/MewNotch/View/Notch/Collapsed/CollapsedNotchView.swift @@ -22,7 +22,7 @@ struct CollapsedNotchView: View { HStack( spacing: 0 ) { - if defaultsManager.hudStyle == .minimal { + if defaultsManager.hudStyle == .Minimal { if let hudIcon = notchViewModel.hudIcon { Text( "000 %" @@ -59,7 +59,7 @@ struct CollapsedNotchView: View { notchSize: notchViewModel.notchSize ) - if defaultsManager.hudStyle == .minimal { + if defaultsManager.hudStyle == .Minimal { if let hudValue = notchViewModel.hudValue { Text( "000%" @@ -99,11 +99,11 @@ struct CollapsedNotchView: View { } } - if defaultsManager.hudStyle == .progress { + if defaultsManager.hudStyle == .Progress { ProgressHUDView( notchViewModel: notchViewModel ) - } else if defaultsManager.hudStyle == .notched { + } else if defaultsManager.hudStyle == .Notched { NotchedHUDView( notchViewModel: notchViewModel ) @@ -136,6 +136,8 @@ struct CollapsedNotchView: View { } else { OSDUIManager.shared.start() } + + notchViewModel.refreshNotchSize() } .onAppear { if defaultsManager.hudEnabled { diff --git a/MewNotch/View/Settings/MewSettingsView.swift b/MewNotch/View/Settings/MewSettingsView.swift index 3e11bed..4283a2b 100644 --- a/MewNotch/View/Settings/MewSettingsView.swift +++ b/MewNotch/View/Settings/MewSettingsView.swift @@ -63,6 +63,19 @@ struct MewSettingsView: View { GeneraSettingsView() } ) + .task { + guard let window = NSApp.windows.first( + where: { + $0.identifier?.rawValue == "com_apple_SwiftUI_Settings_window" + } + ) else { + return + } + + window.toolbarStyle = .unified + window.level = .mainMenu + window.styleMask.insert(.resizable) + } } } diff --git a/MewNotch/View/Settings/Pages/GeneraSettingsView.swift b/MewNotch/View/Settings/Pages/GeneraSettingsView.swift index 26621d6..c71ae6e 100644 --- a/MewNotch/View/Settings/Pages/GeneraSettingsView.swift +++ b/MewNotch/View/Settings/Pages/GeneraSettingsView.swift @@ -16,12 +16,73 @@ struct GeneraSettingsView: View { Section( content: { Toggle( - "Enabled", + isOn: $defaultsManager.notchForceEnabled + ) { + VStack( + alignment: .leading + ) { + Text("Force Enable") + + Text("Enable Notch on Non-notched Displays") + .font(.footnote) + } + } + + Picker( + selection: $defaultsManager.notchHeightMode, + content: { + Text( + MewDefaultsManager.NotchHeightMode.Match_Notch.rawValue.replacingOccurrences( + of: "_", + with: " " + ) + ) + .tag( + MewDefaultsManager.NotchHeightMode.Match_Notch + ) + + Text( + MewDefaultsManager.NotchHeightMode.Match_Menu_Bar.rawValue.replacingOccurrences( + of: "_", + with: " " + ) + ) + .tag( + MewDefaultsManager.NotchHeightMode.Match_Menu_Bar + ) + } + ) { + VStack( + alignment: .leading + ) { + Text("Height") + +// Text("Design to be used for HUD") +// .font(.footnote) + } + } + }, + header: { + Text("Notch") + } + ) + + Section( + content: { + Toggle( isOn: $defaultsManager.hudEnabled - ) + ) { + VStack( + alignment: .leading + ) { + Text("Enabled") + + Text("Show Volume and Brightness changes on Notch and turn off system HUD") + .font(.footnote) + } + } Picker( - "Style", selection: $defaultsManager.hudStyle, content: { ForEach( @@ -31,7 +92,16 @@ struct GeneraSettingsView: View { .tag(style) } } - ) + ) { + VStack( + alignment: .leading + ) { + Text("Style") + + Text("Design to be used for HUD") + .font(.footnote) + } + } .disabled(!defaultsManager.hudEnabled) }, header: { diff --git a/MewNotch/ViewModel/CollapsedNotchViewModel.swift b/MewNotch/ViewModel/CollapsedNotchViewModel.swift index 780d3f4..7fe425c 100644 --- a/MewNotch/ViewModel/CollapsedNotchViewModel.swift +++ b/MewNotch/ViewModel/CollapsedNotchViewModel.swift @@ -23,7 +23,7 @@ class CollapsedNotchViewModel: ObservableObject { init() { self.notchSize = NotchUtils.shared.notchSize( screen: NSScreen.main, - force: true + force: MewDefaultsManager.shared.notchForceEnabled ) withAnimation { @@ -34,6 +34,18 @@ class CollapsedNotchViewModel: ObservableObject { self.startListeners() } + func refreshNotchSize() { + self.notchSize = NotchUtils.shared.notchSize( + screen: NSScreen.main, + force: MewDefaultsManager.shared.notchForceEnabled + ) + + withAnimation { + notchSize.width += extraNotchPadSize.width + notchSize.height += extraNotchPadSize.height + } + } + func startListeners() { self.startListeningForVolumeChanges() self.startListeningForBrightnessChanges()