This commit is contained in:
Alin
2024-09-30 15:00:29 -06:00
parent dbcf0ba655
commit fbcd12d35f
6 changed files with 107 additions and 111 deletions
+4 -4
View File
@@ -533,8 +533,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUILD = 61; APP_BUILD = 62;
APP_VERSION = 3.8.7; APP_VERSION = 3.9.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -603,8 +603,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUILD = 61; APP_BUILD = 62;
APP_VERSION = 3.8.7; APP_VERSION = 3.9.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+6 -41
View File
@@ -7,27 +7,27 @@
import SwiftUI import SwiftUI
import AlinFoundation import AlinFoundation
import Combine
class WindowSettings: ObservableObject { class WindowSettings: ObservableObject {
static let shared = WindowSettings() static let shared = WindowSettings()
let menubarEnabled = UserDefaults.standard.bool(forKey: "settings.menubar.enabled")
private let windowWidthKey = "windowWidthKey" private let windowWidthKey = "windowWidthKey"
private let windowHeightKey = "windowHeightKey" private let windowHeightKey = "windowHeightKey"
private let windowXKey = "windowXKey" private let windowXKey = "windowXKey"
private let windowYKey = "windowYKey" private let windowYKey = "windowYKey"
var windows: [NSWindow] = []
var windowRef: NSWindow? var windowRef: NSWindow?
init() { init() {
trackMainWindow()
registerDefaultWindowSettings() registerDefaultWindowSettings()
} }
func trackMainWindow() { func trackMainWindow() {
if let mainWindow = NSApplication.shared.windows.first(where: { $0.title == "Pearcleaner" }) { if let mainWindow = NSApplication.shared.windows.first(where: { $0.title == "Pearcleaner" }) {
windowRef = mainWindow windowRef = mainWindow
print("Main window detected and tracked: \(mainWindow.title)") // print("Main window detected and tracked")
} else {
print("No main Pearcleaner window detected")
} }
} }
@@ -35,7 +35,7 @@ class WindowSettings: ObservableObject {
func newWindow<V: View>(mini: Bool, withView view: @escaping () -> V) { func newWindow<V: View>(mini: Bool, withView view: @escaping () -> V) {
let frame = self.resetWindowSettings(mini: mini) let frame = self.resetWindowSettings(mini: mini)
if windowRef == nil { if menubarEnabled {
windowRef = NSWindow( windowRef = NSWindow(
contentRect: .zero, contentRect: .zero,
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
@@ -51,41 +51,6 @@ class WindowSettings: ObservableObject {
windowRef?.titleVisibility = .hidden windowRef?.titleVisibility = .hidden
windowRef?.makeKeyAndOrderFront(nil) windowRef?.makeKeyAndOrderFront(nil)
windowRef?.isReleasedWhenClosed = false windowRef?.isReleasedWhenClosed = false
// if let curWindow = windowRef {
// print("Window exists, reopening...")
// let frame = self.resetWindowSettings(mini: mini)
// curWindow.contentView = NSHostingView(rootView: view())
// curWindow.setFrame(frame, display: true, animate: true)
// curWindow.titlebarAppearsTransparent = true
// curWindow.isMovableByWindowBackground = true
// curWindow.title = "Pearcleaner"
// curWindow.isRestorable = false
// curWindow.titleVisibility = .hidden
// curWindow.makeKeyAndOrderFront(nil)
// curWindow.isReleasedWhenClosed = false
// return
// }
// print("Window doesn't exist, creating...")
//
// // Close existing window
// findAndHideWindows(named: ["Pearcleaner"])
// // Create new window using defaults
// let frame = self.resetWindowSettings(mini: mini)
// let newWindow = NSWindow(
// contentRect: .zero,
// styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
// backing: .buffered, defer: false)
// newWindow.contentView = NSHostingView(rootView: view())
// newWindow.setFrame(frame, display: true, animate: true)
// newWindow.titlebarAppearsTransparent = true
// newWindow.isMovableByWindowBackground = true
// newWindow.title = "Pearcleaner"
// newWindow.isRestorable = false
//// self.windows.append(newWindow)
// newWindow.titleVisibility = .hidden
// newWindow.makeKeyAndOrderFront(nil)
// newWindow.isReleasedWhenClosed = false
// windowRef = newWindow
} }
// Register default sizes if the AppStorage keys are invalid // Register default sizes if the AppStorage keys are invalid
+3 -15
View File
@@ -104,6 +104,9 @@ struct PearcleanerApp: App {
appState.currentView = .empty appState.currentView = .empty
} }
// Track main window within windowSettings class
windowSettings.trackMainWindow()
// Disable tabbing // Disable tabbing
NSWindow.allowsAutomaticWindowTabbing = false NSWindow.allowsAutomaticWindowTabbing = false
@@ -128,16 +131,6 @@ struct PearcleanerApp: App {
} }
#if !DEBUG
Task {
// Make sure App Support folder exists in the future if needed for storage
// ensureApplicationSupportFolderExists(appState: appState)
}
#endif
} }
} }
.windowStyle(.hiddenTitleBar) .windowStyle(.hiddenTitleBar)
@@ -189,11 +182,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
themeManager.setupAppearance() themeManager.setupAppearance()
// if menubarEnabled {
// findAndHideWindows(named: ["Pearcleaner"])
// NSApplication.shared.setActivationPolicy(.accessory)
// }
windowFrameObserver = NotificationCenter.default.addObserver(forName: nil, object: nil, queue: nil) { notification in windowFrameObserver = NotificationCenter.default.addObserver(forName: nil, object: nil, queue: nil) { notification in
if let window = notification.object as? NSWindow, window.title == "Pearcleaner" { if let window = notification.object as? NSWindow, window.title == "Pearcleaner" {
if notification.name == NSWindow.didEndLiveResizeNotification || notification.name == NSWindow.didMoveNotification { if notification.name == NSWindow.didEndLiveResizeNotification || notification.name == NSWindow.didMoveNotification {
+91 -49
View File
@@ -16,23 +16,48 @@ struct AboutSettingsTab: View {
var body: some View { var body: some View {
let sponsors = Sponsor.sponsors let sponsors = Sponsor.sponsors
let credits = Credit.credits // let credits = Credit.credits
VStack(alignment: .center) { VStack(alignment: .center) {
Image(nsImage: NSApp.applicationIconImage)
Text(Bundle.main.name)
.font(.title)
.bold()
HStack { HStack {
Text("Version \(Bundle.main.version)") Spacer()
Text("(Build \(Bundle.main.buildVersion))").font(.footnote) Button(action: {
NSWorkspace.shared.open(URL(string: "https://github.com/sponsors/alienator88")!)
}, label: {
HStack(alignment: .center, spacing: 8) {
Image(systemName: "heart")
.resizable()
.scaledToFit()
.frame(width: 16, height: 16)
.foregroundStyle(.pink)
Text("Sponsor")
.font(.body)
.bold()
}
.padding(5)
})
} }
Text("Made with ❤️ by Alin Lupascu").font(.footnote) VStack(spacing: 10) {
Image(nsImage: NSApp.applicationIconImage)
Text(Bundle.main.name)
.font(.title)
.bold()
HStack {
Text("Version \(Bundle.main.version)")
Text("(Build \(Bundle.main.buildVersion))").font(.footnote)
}
Text("Made with ❤️ by Alin Lupascu").font(.footnote)
}
.padding(.vertical, 50)
VStack(spacing: 20) { VStack(spacing: 20) {
// GitHub // GitHub
PearGroupBox(header: { Text("GitHub Issues").font(.title2) }, content: { PearGroupBox(header: { Text("Support").font(.title2) }, content: {
HStack{ HStack{
Image(systemName: "star") Image(systemName: "star")
.resizable() .resizable()
@@ -41,7 +66,7 @@ struct AboutSettingsTab: View {
.padding(.trailing) .padding(.trailing)
VStack(alignment: .leading){ VStack(alignment: .leading){
Text("Submit a bug or feature request via the repo") Text("Submit a bug or feature request")
.font(.callout) .font(.callout)
.foregroundStyle(.primary) .foregroundStyle(.primary)
@@ -50,7 +75,7 @@ struct AboutSettingsTab: View {
Button(""){ Button(""){
NSWorkspace.shared.open(URL(string: "https://github.com/alienator88/Pearcleaner/issues/new/choose")!) NSWorkspace.shared.open(URL(string: "https://github.com/alienator88/Pearcleaner/issues/new/choose")!)
} }
.buttonStyle(SimpleButtonStyle(icon: "link", help: "View")) .buttonStyle(SimpleButtonStyle(icon: "paperplane", help: "View"))
} }
@@ -84,50 +109,67 @@ struct AboutSettingsTab: View {
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
} }
.frame(height: 100) .frame(height: 45)
.padding(5) .padding(5)
}) })
// Button(action: {
// NSWorkspace.shared.open(URL(string: "https://github.com/sponsors/alienator88")!)
// }, label: {
// HStack(alignment: .center, spacing: 8) {
// Image(systemName: "heart")
// .resizable()
// .scaledToFit()
// .frame(width: 20, height: 20)
// .foregroundStyle(.pink)
//
// Text("Sponsor")
// .font(.title3)
// .bold()
// }
// .padding(5)
// })
} }
}) })
// Credits // Credits
PearGroupBox(header: { Text("Credits").font(.title2) }, content: { // PearGroupBox(header: { Text("Credits").font(.title2) }, content: {
HStack{ // HStack{
Image(systemName: "info.circle") // Image(systemName: "info.circle")
.resizable() // .resizable()
.scaledToFit() // .scaledToFit()
.frame(width: 20, height: 20) // .frame(width: 20, height: 20)
.padding(.trailing) // .padding(.trailing)
//
Text("View project resources") // Text("View project resources")
//
DisclosureGroup("", isExpanded: $discloseCredits, content: { // DisclosureGroup("", isExpanded: $discloseCredits, content: {
VStack(alignment: .leading) { // VStack(alignment: .leading) {
//
ForEach(credits) { credit in // ForEach(credits) { credit in
HStack{ // HStack{
VStack(alignment: .leading){ // VStack(alignment: .leading){
Text(credit.name) // Text(credit.name)
Text(credit.description) // Text(credit.description)
.font(.callout) // .font(.callout)
.foregroundStyle(.primary.opacity(0.5)) // .foregroundStyle(.primary.opacity(0.5))
//
} // }
Spacer() // Spacer()
Button(""){ // Button(""){
NSWorkspace.shared.open(credit.url) // NSWorkspace.shared.open(credit.url)
} // }
.buttonStyle(SimpleButtonStyle(icon: "link", help: "View")) // .buttonStyle(SimpleButtonStyle(icon: "link", help: "View"))
.padding(.trailing) // .padding(.trailing)
//
} // }
} // }
} // }
.padding(5) // .padding(5)
}) // })
} // }
//
}) // })
} }
+2 -2
View File
@@ -43,7 +43,7 @@ struct GeneralSettingsTab: View {
Text("Homebrew cleanup after uninstall") Text("Homebrew cleanup after uninstall")
.font(.callout) .font(.callout)
.foregroundStyle(.primary.opacity(1)) .foregroundStyle(.primary.opacity(1))
InfoButton(text: "When homebrew cleanup is enabled, Pearcleaner will check if the app you are removing was installed via homebrew and launch Terminal.app to execute a brew uninstall and cleanup command to let homebrew know that the app is removed. This way your homebrew list will be synced up correctly and caching will be removed. Terminal.app is required since some apps need sudo permissions to remove services and files placed in system folders. Since other terminal apps don't support applescript and/or the 'do script' command, I opted to use the default macOS Terminal app for this.\n\nNOTE: If you undo the file delete with CMD+Z, the files will be put back but homebrew will not be aware of it. To get the homebrew list back in sync you'd need to run:\n brew install APPNAME --force") InfoButton(text: "When homebrew cleanup is enabled, Pearcleaner will check if the app you are removing was installed via homebrew and launch Terminal.app to execute a brew uninstall and cleanup command to let homebrew know that the app is removed. This way your homebrew list will be synced up correctly and caching will be removed. Terminal.app is required since some apps need sudo permissions to remove services and files placed in system folders. Since other terminal apps don't support applescript and/or the 'do script' command, I opted to use the default macOS Terminal app for this.\n\nNOTE: If you undo the file delete with CMD+Z, the files will be put back but homebrew will not be aware of it. To get the homebrew list back in sync you'd need to run:\n\n> brew install APPNAME --force")
} }
} }
@@ -96,7 +96,7 @@ struct GeneralSettingsTab: View {
.foregroundStyle(.primary) .foregroundStyle(.primary)
} }
InfoButton(text: "When this mode is enabled, clicking the Uninstall button to remove an app will also close Pearcleaner right after.\n This only affects Pearcleaner when it is opened via external means, like Sentinel Trash Monitor, Finder extension or a Deep Link.\nThis allows for single use of the app for a quick uninstall. When Pearcleaner is opened normally, this setting is ignored and will work as usual.") InfoButton(text: "When this mode is enabled, clicking the Uninstall button to remove an app will also close Pearcleaner right after.\nThis only affects Pearcleaner when it is opened via external means, like Sentinel Trash Monitor, Finder extension or a Deep Link.\nThis allows for single use of the app for a quick uninstall. When Pearcleaner is opened normally, this setting is ignored and will work as usual.")
Spacer() Spacer()
Toggle(isOn: $oneShotMode, label: { Toggle(isOn: $oneShotMode, label: {
@@ -42,6 +42,7 @@ struct SettingsView: View {
Divider() Divider()
.padding(.bottom, 8) .padding(.bottom, 8)
.padding(.horizontal, 9)
SidebarItemView(title: "General", systemImage: "gear", isSelected: selectedTab == .general) { SidebarItemView(title: "General", systemImage: "gear", isSelected: selectedTab == .general) {
selectedTab = .general selectedTab = .general