├── media ├── screenshot.png └── widgets_demo.gif ├── WidgetToggler ├── .DS_Store ├── WidgetToggler │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── appicon-128.png │ │ │ ├── appicon-16.png │ │ │ ├── appicon-256.png │ │ │ ├── appicon-32.png │ │ │ ├── appicon-512.png │ │ │ ├── appicon-64.png │ │ │ ├── appicon-1024.png │ │ │ └── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── WidgetToggler.entitlements │ ├── Bundle.swift │ ├── Info.plist │ ├── SettingsScreen.swift │ ├── Shared │ │ ├── UserDefaults.swift │ │ └── WidgetsPrefs.swift │ ├── WidgetTogglerApp.swift │ ├── FocusFilters.swift │ └── ShortcutHelpers.swift └── WidgetToggler.xcodeproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── sierenmusic.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved │ ├── xcuserdata │ └── sierenmusic.xcuserdatad │ │ ├── xcschemes │ │ └── xcschememanagement.plist │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── project.pbxproj ├── AppIcons └── macOS │ └── AppIcon.appiconset │ ├── appicon-16.png │ ├── appicon-32.png │ ├── appicon-64.png │ ├── appicon-1024.png │ ├── appicon-128.png │ ├── appicon-256.png │ ├── appicon-512.png │ └── Contents.json ├── LICENSE └── README.md /media/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/media/screenshot.png -------------------------------------------------------------------------------- /WidgetToggler/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/.DS_Store -------------------------------------------------------------------------------- /media/widgets_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/media/widgets_demo.gif -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-16.png -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-32.png -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-64.png -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-1024.png -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-128.png -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-256.png -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/appicon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/AppIcons/macOS/AppIcon.appiconset/appicon-512.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-128.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-16.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-256.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-32.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-512.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-64.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/appicon-1024.png -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/WidgetToggler.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/project.xcworkspace/xcuserdata/sierenmusic.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sieren/WidgetToggler/HEAD/WidgetToggler/WidgetToggler.xcodeproj/project.xcworkspace/xcuserdata/sierenmusic.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Bundle.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import Foundation 4 | 5 | extension Bundle { 6 | var releaseVersionNumber: String? { 7 | return infoDictionary?["CFBundleShortVersionString"] as? String 8 | } 9 | var buildVersionNumber: String? { 10 | return infoDictionary?["CFBundleVersion"] as? String 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | INIntentsSupported 6 | 7 | FocusFilters 8 | WidgetTogglerIntentsExtension 9 | WidgetTogglerIntentsExtensionExtension 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/SettingsScreen.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import Foundation 4 | import SwiftUI 5 | 6 | import KeyboardShortcuts 7 | 8 | struct SettingsScreen: View { 9 | @Environment(\.dismiss) var dismiss 10 | 11 | var body: some View { 12 | VStack(alignment: .leading) { 13 | Spacer() 14 | Text("Set a global HotKey to toggle Widgets.") 15 | Form { 16 | KeyboardShortcuts.Recorder("HotKey:", name: .toggleWidgetMode) 17 | } 18 | Text("Requires restarting WidgetToggler to show in the UI.") 19 | Spacer() 20 | } 21 | .frame(minWidth: 200) 22 | .padding(50) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/xcuserdata/sierenmusic.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WidgetToggler.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | WidgetTogglerIntentsExtension.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "keyboardshortcuts", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/sindresorhus/KeyboardShortcuts", 7 | "state" : { 8 | "revision" : "ac302e21da5883f4bd0490cbd0cb710b08740500", 9 | "version" : "1.15.0" 10 | } 11 | }, 12 | { 13 | "identity" : "launchatlogin-modern", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/sindresorhus/LaunchAtLogin-Modern", 16 | "state" : { 17 | "branch" : "main", 18 | "revision" : "9c41991631605c8ccfe0347bbcb5c659169f2ec5" 19 | } 20 | } 21 | ], 22 | "version" : 2 23 | } 24 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/xcuserdata/sierenmusic.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Matt Sieren 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Shared/UserDefaults.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import Foundation 4 | 5 | extension UserDefaults { 6 | 7 | public static let kWindowManagerPlistKey = "com.apple.WindowManager.plist" 8 | public static let kStageManagerEnabledKey = "GloballyEnabled" 9 | public static let kStageManageHideWidgets = "StageManagerHideWidgets" 10 | public static let kStandardHideWidgets = "StandardHideWidgets" 11 | 12 | @objc var stageManagerEnabled: Bool { 13 | get { 14 | return integer(forKey: UserDefaults.kStageManagerEnabledKey) == 1 15 | } 16 | set { 17 | set(newValue ? 1 : 0, forKey: UserDefaults.kStageManagerEnabledKey) 18 | } 19 | } 20 | 21 | @objc var hideStageManagerWidgets: Bool { 22 | get { 23 | return integer(forKey: UserDefaults.kStageManageHideWidgets) == 1 24 | } 25 | set { 26 | set(newValue ? 1 : 0, forKey: UserDefaults.kStageManageHideWidgets) 27 | } 28 | } 29 | 30 | @objc var hideDesktopWidgets: Bool { 31 | get { 32 | return integer(forKey: UserDefaults.kStandardHideWidgets) == 1 33 | } 34 | set { 35 | set(newValue ? 1 : 0, forKey: UserDefaults.kStandardHideWidgets) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## WidgetToggler 2 | 3 | WidgetToggler is a light-weight tray-bar application for macOS Sonoma that allows users to quickly hide all widgets, for example when screen-sharing. 4 | **Update:** When sharing screens in meetings, macOS Sonoma+ will automatically not share the Widgets, even though you as a user can still see them. 5 | 6 | ![alt text](https://raw.githubusercontent.com/sieren/widgettoggler/master/media/widgets_demo.gif "WidgetToggler" ) 7 | 8 | ## Features 9 | - Individual toggles Widgets for Desktop and Stage Manager ✅ 10 | - Toggle widgets via global shortcut ⌘⌃w ✅ 11 | - Use macOS Focus Filters to determine when to show widgets ✅ 12 | - Launch at Login ✅ 13 | 14 | ## Requirements 15 | 16 | - macOS 14.0+ 17 | - Xcode 15.0+ 18 | 19 | ## Installation 20 | 21 | Download WidgetToggler from [Releases](https://github.com/sieren/widgettoggler/releases), unzip and drag to Applications. 22 | 23 | ## Toggling Widgets from CLI 24 | 25 | In order to manually toggle widgets from the command line, the following 26 | defaults will toggle widgets shown on desktop. 0 is being used to show widgets, 27 | 1 is being used to hide them. 28 | 29 | ### Desktop 30 | `defaults write com.apple.WindowManager StandardHideWidgets -int 1` 31 | 32 | ### Stage Manager 33 | 34 | `defaults write com.apple.WindowManager StageManagerHideWidgets -int 1` 35 | 36 | ## License 37 | 38 | WidgetToggler is available under the Apache 2.0 license. See the LICENSE file for more info. 39 | 40 | -------------------------------------------------------------------------------- /AppIcons/macOS/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "appicon-16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "appicon-32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "appicon-32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "appicon-64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "appicon-128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "appicon-256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "appicon-256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "appicon-512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "appicon-512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "appicon-1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "appicon-16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "appicon-32.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "appicon-32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "appicon-64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "appicon-128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "appicon-256.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "appicon-256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "appicon-512.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "appicon-512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "appicon-1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/WidgetTogglerApp.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import SwiftUI 4 | 5 | import KeyboardShortcuts 6 | import LaunchAtLogin 7 | 8 | @main 9 | struct WidgetTogglerApp: App { 10 | @State var widgetsPrefs: WidgetPreferences 11 | 12 | public init() { 13 | widgetsPrefs = WidgetPreferences.shared 14 | KeyboardShortcuts.onKeyUp(for: .toggleWidgetMode) { [self] in 15 | widgetsPrefs.toggleWidgets() 16 | } 17 | } 18 | 19 | var body: some Scene { 20 | Settings { 21 | SettingsScreen() 22 | } 23 | MenuBarExtra( 24 | "WidgetToggler", 25 | systemImage: widgetsPrefs.hideWidgets ? "rectangle.on.rectangle.slash" : "rectangle.inset.filled.on.rectangle" 26 | ) { 27 | Button( 28 | action: { 29 | widgetsPrefs.toggleWidgets() 30 | }, 31 | label: { 32 | HStack { 33 | Text(widgetsPrefs.hideWidgets ? "Show Widgets" : "Hide Widgets") 34 | } 35 | } 36 | ).keyboardShortcut(.toggleWidgetMode) 37 | Divider() 38 | SettingsLink(label: { 39 | Text("Settings") 40 | }) 41 | LaunchAtLogin.Toggle() 42 | Divider() 43 | Button( 44 | action: { 45 | if let url = URL(string: "https://github.com/sieren/WidgetToggler") { 46 | NSWorkspace.shared.open(url) 47 | } 48 | }, 49 | label: { 50 | Text("WidgetToggler " + (Bundle.main.releaseVersionNumber ?? "")) 51 | } 52 | ) 53 | Button( 54 | action: { 55 | NSApplication.shared.terminate(nil) 56 | }, 57 | label: { 58 | Text("Quit") 59 | } 60 | ) 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/FocusFilters.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import OSLog 4 | import Foundation 5 | import AppIntents 6 | 7 | struct HideWidgetsFocusFilter: SetFocusFilterIntent, Sendable { 8 | 9 | static public var title: LocalizedStringResource = "Set to automatically hide all widgets." 10 | 11 | static public var description: IntentDescription? = """ 12 | Set to hide all widgets when focus mode changes. 13 | """ 14 | 15 | public var displayRepresentation: DisplayRepresentation 16 | { 17 | DisplayRepresentation( 18 | title: "\(primaryText)" 19 | ) 20 | } 21 | 22 | private var primaryText: LocalizedStringResource { 23 | return hideWidgets ? "Hide Widgets" : "Show Widgets" 24 | } 25 | 26 | private var secondaryText: LocalizedStringResource { 27 | let status = hideWidgets ? "Enabled" : "Disabled" 28 | return "Status: \(status)" 29 | } 30 | 31 | /// Providing a default value ensures setting this required Boolean value. 32 | @Parameter(title: "Hide Widgets", default: false) 33 | var hideWidgets: Bool 34 | 35 | static func suggestedFocusFilters(for context: FocusFilterSuggestionContext) async -> [HideWidgetsFocusFilter] { 36 | let defaultFilter = HideWidgetsFocusFilter() 37 | defaultFilter.hideWidgets = true 38 | 39 | return [defaultFilter] 40 | } 41 | 42 | func perform() async throws -> some IntentResult { 43 | WidgetPreferences.shared.showHideWidgets(hide: self.hideWidgets) 44 | return .result() 45 | } 46 | } 47 | 48 | extension HideWidgetsFocusFilter { 49 | var logger: Logger { 50 | let subsystem = Bundle.main.bundleIdentifier! 51 | return Logger(subsystem: subsystem, category: "WidgetTogglerFocus") 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/Shared/WidgetsPrefs.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import Combine 4 | import Foundation 5 | import Observation 6 | import SwiftUI 7 | 8 | @Observable 9 | public final class WidgetPreferences : Sendable { 10 | public var hideWidgets: Bool = false 11 | 12 | @ObservationIgnored private var smActive: Bool = false 13 | @ObservationIgnored private var defaults: UserDefaults? 14 | var subscriptions = Set() 15 | var smObserverTimer: Timer? 16 | 17 | static let shared = WidgetPreferences() 18 | 19 | public init() { 20 | defaults = UserDefaults.init(suiteName: UserDefaults.kWindowManagerPlistKey) 21 | let defaultsWg = UserDefaults.standard 22 | defaultsWg.addSuite(named: UserDefaults.kWindowManagerPlistKey) 23 | defaults? 24 | .publisher(for: \.hideStageManagerWidgets) 25 | .handleEvents(receiveOutput: { hideStageManagerWidgets in 26 | guard let defaults = self.defaults else { return } 27 | self.hideWidgets = defaults.stageManagerEnabled ? hideStageManagerWidgets : defaults.hideDesktopWidgets 28 | }) 29 | .sink { _ in } 30 | .store(in: &subscriptions) 31 | defaults? 32 | .publisher(for: \.hideDesktopWidgets) 33 | .handleEvents(receiveOutput: { hideDesktopWidgets in 34 | guard let defaults = self.defaults else { return } 35 | self.hideWidgets = defaults.stageManagerEnabled ? defaults.hideStageManagerWidgets : hideDesktopWidgets 36 | }) 37 | .sink { _ in } 38 | .store(in: &subscriptions) 39 | smObserverTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { _ in 40 | self.checkIfSMActive() 41 | }) 42 | } 43 | 44 | // Workaround for now since KVO on SM doesn't fire 45 | func checkIfSMActive() { 46 | if smActive != defaults?.stageManagerEnabled { 47 | guard let defaults = defaults else { return } 48 | self.hideWidgets = defaults.stageManagerEnabled ? defaults.hideStageManagerWidgets : defaults.hideDesktopWidgets 49 | smActive = defaults.stageManagerEnabled 50 | } 51 | } 52 | 53 | func toggleWidgets() { 54 | guard let defaults = defaults else { return } 55 | if defaults.stageManagerEnabled { 56 | defaults.hideStageManagerWidgets = !defaults.hideStageManagerWidgets 57 | } else { 58 | defaults.hideDesktopWidgets = !defaults.hideDesktopWidgets 59 | } 60 | } 61 | 62 | func showHideWidgets(hide: Bool) { 63 | guard let defaults = defaults else { exit(0) } 64 | defaults.hideStageManagerWidgets = hide 65 | defaults.hideDesktopWidgets = hide 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler/ShortcutHelpers.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Matthias Frick. All rights reserved. 2 | 3 | import Carbon 4 | import Foundation 5 | import SwiftUI 6 | 7 | import KeyboardShortcuts 8 | 9 | extension KeyboardShortcuts.Name { 10 | static let toggleWidgetMode = Self( 11 | "ToggleWidgetMode", 12 | default: .init( 13 | .w, 14 | modifiers: [.command, .control] 15 | ) 16 | ) 17 | } 18 | 19 | extension View { 20 | public func keyboardShortcut(_ shortcut: KeyboardShortcuts.Name) -> some View { 21 | if let shortcut = shortcut.shortcut { 22 | if let keyEquivalent = shortcut.toKeyEquivalent() { 23 | return AnyView(self.keyboardShortcut(keyEquivalent, modifiers: shortcut.toEventModifiers())) 24 | } 25 | } 26 | 27 | return AnyView(self) 28 | } 29 | } 30 | 31 | extension KeyboardShortcuts.Shortcut { 32 | 33 | func toKeyEquivalent() -> KeyEquivalent? { 34 | let carbonKeyCode = UInt16(self.carbonKeyCode) 35 | let maxNameLength = 4 36 | var nameBuffer = [UniChar](repeating: 0, count : maxNameLength) 37 | var nameLength = 0 38 | 39 | let modifierKeys = UInt32(alphaLock >> 8) & 0xFF // Caps Lock 40 | var deadKeys: UInt32 = 0 41 | let keyboardType = UInt32(LMGetKbdType()) 42 | 43 | let source = TISCopyCurrentKeyboardLayoutInputSource().takeRetainedValue() 44 | guard let ptr = TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData) else { 45 | NSLog("Could not get keyboard layout data") 46 | return nil 47 | } 48 | let layoutData = Unmanaged.fromOpaque(ptr).takeUnretainedValue() as Data 49 | let osStatus = layoutData.withUnsafeBytes { 50 | UCKeyTranslate($0.bindMemory(to: UCKeyboardLayout.self).baseAddress, carbonKeyCode, UInt16(kUCKeyActionDown), 51 | modifierKeys, keyboardType, UInt32(kUCKeyTranslateNoDeadKeysMask), 52 | &deadKeys, maxNameLength, &nameLength, &nameBuffer) 53 | } 54 | guard osStatus == noErr else { 55 | NSLog("Code: 0x%04X Status: %+i", carbonKeyCode, osStatus); 56 | return nil 57 | } 58 | 59 | return KeyEquivalent(Character(String(utf16CodeUnits: nameBuffer, count: nameLength))) 60 | } 61 | 62 | func toEventModifiers() -> SwiftUI.EventModifiers { 63 | var modifiers: SwiftUI.EventModifiers = [] 64 | 65 | if self.modifiers.contains(NSEvent.ModifierFlags.command) { 66 | modifiers.update(with: EventModifiers.command) 67 | } 68 | 69 | if self.modifiers.contains(NSEvent.ModifierFlags.control) { 70 | modifiers.update(with: EventModifiers.control) 71 | } 72 | 73 | if self.modifiers.contains(NSEvent.ModifierFlags.option) { 74 | modifiers.update(with: EventModifiers.option) 75 | } 76 | 77 | if self.modifiers.contains(NSEvent.ModifierFlags.shift) { 78 | modifiers.update(with: EventModifiers.shift) 79 | } 80 | 81 | if self.modifiers.contains(NSEvent.ModifierFlags.capsLock) { 82 | modifiers.update(with: EventModifiers.capsLock) 83 | } 84 | 85 | if self.modifiers.contains(NSEvent.ModifierFlags.numericPad) { 86 | modifiers.update(with: EventModifiers.numericPad) 87 | } 88 | 89 | return modifiers 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /WidgetToggler/WidgetToggler.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 691985502ACFEE87007E88A9 /* KeyboardShortcuts in Frameworks */ = {isa = PBXBuildFile; productRef = 6919854F2ACFEE87007E88A9 /* KeyboardShortcuts */; }; 11 | 691985522ACFEEA5007E88A9 /* ShortcutHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 691985512ACFEEA5007E88A9 /* ShortcutHelpers.swift */; }; 12 | 691985542ACFEF23007E88A9 /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 691985532ACFEF23007E88A9 /* SettingsScreen.swift */; }; 13 | 693C9D072ABEFDB400A2DB62 /* FocusFilters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693C9CB42ABEEC3500A2DB62 /* FocusFilters.swift */; }; 14 | 69A392FB2AAE152B007B9101 /* WidgetTogglerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69A392FA2AAE152B007B9101 /* WidgetTogglerApp.swift */; }; 15 | 69A392FF2AAE152C007B9101 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69A392FE2AAE152C007B9101 /* Assets.xcassets */; }; 16 | 69A393022AAE152C007B9101 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69A393012AAE152C007B9101 /* Preview Assets.xcassets */; }; 17 | 69A3930A2AAE1A80007B9101 /* WidgetsPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69A393092AAE1A80007B9101 /* WidgetsPrefs.swift */; }; 18 | 69B7C75D2AAEFFD800804939 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B7C75C2AAEFFD800804939 /* UserDefaults.swift */; }; 19 | 69ED90242AAF752600137DA5 /* LaunchAtLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 69ED90232AAF752600137DA5 /* LaunchAtLogin */; }; 20 | 69ED90262AAF788A00137DA5 /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69ED90252AAF788A00137DA5 /* Bundle.swift */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXCopyFilesBuildPhase section */ 24 | 693C9CC92ABEECF800A2DB62 /* Embed Foundation Extensions */ = { 25 | isa = PBXCopyFilesBuildPhase; 26 | buildActionMask = 2147483647; 27 | dstPath = ""; 28 | dstSubfolderSpec = 13; 29 | files = ( 30 | ); 31 | name = "Embed Foundation Extensions"; 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | 693C9CDC2ABEED0B00A2DB62 /* Embed ExtensionKit Extensions */ = { 35 | isa = PBXCopyFilesBuildPhase; 36 | buildActionMask = 2147483647; 37 | dstPath = "$(EXTENSIONS_FOLDER_PATH)"; 38 | dstSubfolderSpec = 16; 39 | files = ( 40 | ); 41 | name = "Embed ExtensionKit Extensions"; 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXCopyFilesBuildPhase section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 691985512ACFEEA5007E88A9 /* ShortcutHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutHelpers.swift; sourceTree = ""; }; 48 | 691985532ACFEF23007E88A9 /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = ""; }; 49 | 693C9CB42ABEEC3500A2DB62 /* FocusFilters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusFilters.swift; sourceTree = ""; }; 50 | 693C9CBC2ABEECF800A2DB62 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; }; 51 | 693C9D062ABEFCE400A2DB62 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 52 | 69A392F72AAE152B007B9101 /* WidgetToggler.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WidgetToggler.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 69A392FA2AAE152B007B9101 /* WidgetTogglerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetTogglerApp.swift; sourceTree = ""; }; 54 | 69A392FE2AAE152C007B9101 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55 | 69A393012AAE152C007B9101 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 56 | 69A393032AAE152C007B9101 /* WidgetToggler.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetToggler.entitlements; sourceTree = ""; }; 57 | 69A393092AAE1A80007B9101 /* WidgetsPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetsPrefs.swift; sourceTree = ""; }; 58 | 69B7C75C2AAEFFD800804939 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = ""; }; 59 | 69ED90252AAF788A00137DA5 /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 69A392F42AAE152B007B9101 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 69ED90242AAF752600137DA5 /* LaunchAtLogin in Frameworks */, 68 | 691985502ACFEE87007E88A9 /* KeyboardShortcuts in Frameworks */, 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 693C9CBB2ABEECF800A2DB62 /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 693C9CBC2ABEECF800A2DB62 /* Intents.framework */, 79 | ); 80 | name = Frameworks; 81 | sourceTree = ""; 82 | }; 83 | 693C9CF02ABEF0C000A2DB62 /* Shared */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 69A393092AAE1A80007B9101 /* WidgetsPrefs.swift */, 87 | 69B7C75C2AAEFFD800804939 /* UserDefaults.swift */, 88 | ); 89 | path = Shared; 90 | sourceTree = ""; 91 | }; 92 | 69A392EE2AAE152B007B9101 = { 93 | isa = PBXGroup; 94 | children = ( 95 | 69A392F92AAE152B007B9101 /* WidgetToggler */, 96 | 693C9CBB2ABEECF800A2DB62 /* Frameworks */, 97 | 69A392F82AAE152B007B9101 /* Products */, 98 | ); 99 | sourceTree = ""; 100 | }; 101 | 69A392F82AAE152B007B9101 /* Products */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 69A392F72AAE152B007B9101 /* WidgetToggler.app */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 69A392F92AAE152B007B9101 /* WidgetToggler */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 693C9D062ABEFCE400A2DB62 /* Info.plist */, 113 | 693C9CF02ABEF0C000A2DB62 /* Shared */, 114 | 69A392FA2AAE152B007B9101 /* WidgetTogglerApp.swift */, 115 | 691985532ACFEF23007E88A9 /* SettingsScreen.swift */, 116 | 691985512ACFEEA5007E88A9 /* ShortcutHelpers.swift */, 117 | 693C9CB42ABEEC3500A2DB62 /* FocusFilters.swift */, 118 | 69ED90252AAF788A00137DA5 /* Bundle.swift */, 119 | 69A392FE2AAE152C007B9101 /* Assets.xcassets */, 120 | 69A393032AAE152C007B9101 /* WidgetToggler.entitlements */, 121 | 69A393002AAE152C007B9101 /* Preview Content */, 122 | ); 123 | path = WidgetToggler; 124 | sourceTree = ""; 125 | }; 126 | 69A393002AAE152C007B9101 /* Preview Content */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 69A393012AAE152C007B9101 /* Preview Assets.xcassets */, 130 | ); 131 | path = "Preview Content"; 132 | sourceTree = ""; 133 | }; 134 | /* End PBXGroup section */ 135 | 136 | /* Begin PBXNativeTarget section */ 137 | 69A392F62AAE152B007B9101 /* WidgetToggler */ = { 138 | isa = PBXNativeTarget; 139 | buildConfigurationList = 69A393062AAE152C007B9101 /* Build configuration list for PBXNativeTarget "WidgetToggler" */; 140 | buildPhases = ( 141 | 69A392F32AAE152B007B9101 /* Sources */, 142 | 69A392F42AAE152B007B9101 /* Frameworks */, 143 | 69A392F52AAE152B007B9101 /* Resources */, 144 | 693C9CC92ABEECF800A2DB62 /* Embed Foundation Extensions */, 145 | 693C9CDC2ABEED0B00A2DB62 /* Embed ExtensionKit Extensions */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | ); 151 | name = WidgetToggler; 152 | packageProductDependencies = ( 153 | 69ED90232AAF752600137DA5 /* LaunchAtLogin */, 154 | 6919854F2ACFEE87007E88A9 /* KeyboardShortcuts */, 155 | ); 156 | productName = WidgetToggler; 157 | productReference = 69A392F72AAE152B007B9101 /* WidgetToggler.app */; 158 | productType = "com.apple.product-type.application"; 159 | }; 160 | /* End PBXNativeTarget section */ 161 | 162 | /* Begin PBXProject section */ 163 | 69A392EF2AAE152B007B9101 /* Project object */ = { 164 | isa = PBXProject; 165 | attributes = { 166 | BuildIndependentTargetsInParallel = 1; 167 | LastSwiftUpdateCheck = 1500; 168 | LastUpgradeCheck = 1500; 169 | TargetAttributes = { 170 | 69A392F62AAE152B007B9101 = { 171 | CreatedOnToolsVersion = 15.0; 172 | }; 173 | }; 174 | }; 175 | buildConfigurationList = 69A392F22AAE152B007B9101 /* Build configuration list for PBXProject "WidgetToggler" */; 176 | compatibilityVersion = "Xcode 14.0"; 177 | developmentRegion = en; 178 | hasScannedForEncodings = 0; 179 | knownRegions = ( 180 | en, 181 | Base, 182 | ); 183 | mainGroup = 69A392EE2AAE152B007B9101; 184 | packageReferences = ( 185 | 69ED90222AAF752600137DA5 /* XCRemoteSwiftPackageReference "LaunchAtLogin-Modern" */, 186 | 6919854E2ACFEE87007E88A9 /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */, 187 | ); 188 | productRefGroup = 69A392F82AAE152B007B9101 /* Products */; 189 | projectDirPath = ""; 190 | projectRoot = ""; 191 | targets = ( 192 | 69A392F62AAE152B007B9101 /* WidgetToggler */, 193 | ); 194 | }; 195 | /* End PBXProject section */ 196 | 197 | /* Begin PBXResourcesBuildPhase section */ 198 | 69A392F52AAE152B007B9101 /* Resources */ = { 199 | isa = PBXResourcesBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | 69A393022AAE152C007B9101 /* Preview Assets.xcassets in Resources */, 203 | 69A392FF2AAE152C007B9101 /* Assets.xcassets in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXSourcesBuildPhase section */ 210 | 69A392F32AAE152B007B9101 /* Sources */ = { 211 | isa = PBXSourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | 69B7C75D2AAEFFD800804939 /* UserDefaults.swift in Sources */, 215 | 691985542ACFEF23007E88A9 /* SettingsScreen.swift in Sources */, 216 | 69ED90262AAF788A00137DA5 /* Bundle.swift in Sources */, 217 | 69A3930A2AAE1A80007B9101 /* WidgetsPrefs.swift in Sources */, 218 | 693C9D072ABEFDB400A2DB62 /* FocusFilters.swift in Sources */, 219 | 69A392FB2AAE152B007B9101 /* WidgetTogglerApp.swift in Sources */, 220 | 691985522ACFEEA5007E88A9 /* ShortcutHelpers.swift in Sources */, 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | }; 224 | /* End PBXSourcesBuildPhase section */ 225 | 226 | /* Begin XCBuildConfiguration section */ 227 | 69A393042AAE152C007B9101 /* Debug */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | ALWAYS_SEARCH_USER_PATHS = NO; 231 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 232 | CLANG_ANALYZER_NONNULL = YES; 233 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 234 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 235 | CLANG_ENABLE_MODULES = YES; 236 | CLANG_ENABLE_OBJC_ARC = YES; 237 | CLANG_ENABLE_OBJC_WEAK = YES; 238 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 239 | CLANG_WARN_BOOL_CONVERSION = YES; 240 | CLANG_WARN_COMMA = YES; 241 | CLANG_WARN_CONSTANT_CONVERSION = YES; 242 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 243 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 244 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 245 | CLANG_WARN_EMPTY_BODY = YES; 246 | CLANG_WARN_ENUM_CONVERSION = YES; 247 | CLANG_WARN_INFINITE_RECURSION = YES; 248 | CLANG_WARN_INT_CONVERSION = YES; 249 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 250 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 251 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 252 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 253 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 254 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 255 | CLANG_WARN_STRICT_PROTOTYPES = YES; 256 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 257 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 258 | CLANG_WARN_UNREACHABLE_CODE = YES; 259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 260 | COPY_PHASE_STRIP = NO; 261 | DEBUG_INFORMATION_FORMAT = dwarf; 262 | ENABLE_STRICT_OBJC_MSGSEND = YES; 263 | ENABLE_TESTABILITY = YES; 264 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 265 | GCC_C_LANGUAGE_STANDARD = gnu17; 266 | GCC_DYNAMIC_NO_PIC = NO; 267 | GCC_NO_COMMON_BLOCKS = YES; 268 | GCC_OPTIMIZATION_LEVEL = 0; 269 | GCC_PREPROCESSOR_DEFINITIONS = ( 270 | "DEBUG=1", 271 | "$(inherited)", 272 | ); 273 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 274 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 275 | GCC_WARN_UNDECLARED_SELECTOR = YES; 276 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 277 | GCC_WARN_UNUSED_FUNCTION = YES; 278 | GCC_WARN_UNUSED_VARIABLE = YES; 279 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 280 | MACOSX_DEPLOYMENT_TARGET = 14.0; 281 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 282 | MTL_FAST_MATH = YES; 283 | ONLY_ACTIVE_ARCH = YES; 284 | SDKROOT = macosx; 285 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 286 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 287 | }; 288 | name = Debug; 289 | }; 290 | 69A393052AAE152C007B9101 /* Release */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | ALWAYS_SEARCH_USER_PATHS = NO; 294 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 295 | CLANG_ANALYZER_NONNULL = YES; 296 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 297 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 298 | CLANG_ENABLE_MODULES = YES; 299 | CLANG_ENABLE_OBJC_ARC = YES; 300 | CLANG_ENABLE_OBJC_WEAK = YES; 301 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 302 | CLANG_WARN_BOOL_CONVERSION = YES; 303 | CLANG_WARN_COMMA = YES; 304 | CLANG_WARN_CONSTANT_CONVERSION = YES; 305 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 306 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 307 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 308 | CLANG_WARN_EMPTY_BODY = YES; 309 | CLANG_WARN_ENUM_CONVERSION = YES; 310 | CLANG_WARN_INFINITE_RECURSION = YES; 311 | CLANG_WARN_INT_CONVERSION = YES; 312 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 313 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 314 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 315 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 316 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 317 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 318 | CLANG_WARN_STRICT_PROTOTYPES = YES; 319 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 320 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 321 | CLANG_WARN_UNREACHABLE_CODE = YES; 322 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 323 | COPY_PHASE_STRIP = NO; 324 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 325 | ENABLE_NS_ASSERTIONS = NO; 326 | ENABLE_STRICT_OBJC_MSGSEND = YES; 327 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 328 | GCC_C_LANGUAGE_STANDARD = gnu17; 329 | GCC_NO_COMMON_BLOCKS = YES; 330 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 331 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 332 | GCC_WARN_UNDECLARED_SELECTOR = YES; 333 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 334 | GCC_WARN_UNUSED_FUNCTION = YES; 335 | GCC_WARN_UNUSED_VARIABLE = YES; 336 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 337 | MACOSX_DEPLOYMENT_TARGET = 14.0; 338 | MTL_ENABLE_DEBUG_INFO = NO; 339 | MTL_FAST_MATH = YES; 340 | SDKROOT = macosx; 341 | SWIFT_COMPILATION_MODE = wholemodule; 342 | }; 343 | name = Release; 344 | }; 345 | 69A393072AAE152C007B9101 /* Debug */ = { 346 | isa = XCBuildConfiguration; 347 | buildSettings = { 348 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 349 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 350 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 351 | CODE_SIGN_ENTITLEMENTS = WidgetToggler/WidgetToggler.entitlements; 352 | CODE_SIGN_STYLE = Automatic; 353 | COMBINE_HIDPI_IMAGES = YES; 354 | CURRENT_PROJECT_VERSION = 3; 355 | DEVELOPMENT_ASSET_PATHS = "\"WidgetToggler/Preview Content\""; 356 | DEVELOPMENT_TEAM = VEESE9857L; 357 | ENABLE_HARDENED_RUNTIME = YES; 358 | ENABLE_PREVIEWS = YES; 359 | GENERATE_INFOPLIST_FILE = YES; 360 | INFOPLIST_FILE = WidgetToggler/Info.plist; 361 | INFOPLIST_KEY_CFBundleDisplayName = "Widget Toggler"; 362 | INFOPLIST_KEY_LSUIElement = YES; 363 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 364 | LD_RUNPATH_SEARCH_PATHS = ( 365 | "$(inherited)", 366 | "@executable_path/../Frameworks", 367 | ); 368 | MARKETING_VERSION = 1.2; 369 | PRODUCT_BUNDLE_IDENTIFIER = com.sieren.WidgetToggler; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | SWIFT_EMIT_LOC_STRINGS = YES; 372 | SWIFT_VERSION = 5.0; 373 | }; 374 | name = Debug; 375 | }; 376 | 69A393082AAE152C007B9101 /* Release */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 380 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 381 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 382 | CODE_SIGN_ENTITLEMENTS = WidgetToggler/WidgetToggler.entitlements; 383 | CODE_SIGN_STYLE = Automatic; 384 | COMBINE_HIDPI_IMAGES = YES; 385 | CURRENT_PROJECT_VERSION = 3; 386 | DEVELOPMENT_ASSET_PATHS = "\"WidgetToggler/Preview Content\""; 387 | DEVELOPMENT_TEAM = VEESE9857L; 388 | ENABLE_HARDENED_RUNTIME = YES; 389 | ENABLE_PREVIEWS = YES; 390 | GENERATE_INFOPLIST_FILE = YES; 391 | INFOPLIST_FILE = WidgetToggler/Info.plist; 392 | INFOPLIST_KEY_CFBundleDisplayName = "Widget Toggler"; 393 | INFOPLIST_KEY_LSUIElement = YES; 394 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 395 | LD_RUNPATH_SEARCH_PATHS = ( 396 | "$(inherited)", 397 | "@executable_path/../Frameworks", 398 | ); 399 | MARKETING_VERSION = 1.2; 400 | PRODUCT_BUNDLE_IDENTIFIER = com.sieren.WidgetToggler; 401 | PRODUCT_NAME = "$(TARGET_NAME)"; 402 | SWIFT_EMIT_LOC_STRINGS = YES; 403 | SWIFT_VERSION = 5.0; 404 | }; 405 | name = Release; 406 | }; 407 | /* End XCBuildConfiguration section */ 408 | 409 | /* Begin XCConfigurationList section */ 410 | 69A392F22AAE152B007B9101 /* Build configuration list for PBXProject "WidgetToggler" */ = { 411 | isa = XCConfigurationList; 412 | buildConfigurations = ( 413 | 69A393042AAE152C007B9101 /* Debug */, 414 | 69A393052AAE152C007B9101 /* Release */, 415 | ); 416 | defaultConfigurationIsVisible = 0; 417 | defaultConfigurationName = Release; 418 | }; 419 | 69A393062AAE152C007B9101 /* Build configuration list for PBXNativeTarget "WidgetToggler" */ = { 420 | isa = XCConfigurationList; 421 | buildConfigurations = ( 422 | 69A393072AAE152C007B9101 /* Debug */, 423 | 69A393082AAE152C007B9101 /* Release */, 424 | ); 425 | defaultConfigurationIsVisible = 0; 426 | defaultConfigurationName = Release; 427 | }; 428 | /* End XCConfigurationList section */ 429 | 430 | /* Begin XCRemoteSwiftPackageReference section */ 431 | 6919854E2ACFEE87007E88A9 /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */ = { 432 | isa = XCRemoteSwiftPackageReference; 433 | repositoryURL = "https://github.com/sindresorhus/KeyboardShortcuts"; 434 | requirement = { 435 | kind = upToNextMajorVersion; 436 | minimumVersion = 1.15.0; 437 | }; 438 | }; 439 | 69ED90222AAF752600137DA5 /* XCRemoteSwiftPackageReference "LaunchAtLogin-Modern" */ = { 440 | isa = XCRemoteSwiftPackageReference; 441 | repositoryURL = "https://github.com/sindresorhus/LaunchAtLogin-Modern"; 442 | requirement = { 443 | branch = main; 444 | kind = branch; 445 | }; 446 | }; 447 | /* End XCRemoteSwiftPackageReference section */ 448 | 449 | /* Begin XCSwiftPackageProductDependency section */ 450 | 6919854F2ACFEE87007E88A9 /* KeyboardShortcuts */ = { 451 | isa = XCSwiftPackageProductDependency; 452 | package = 6919854E2ACFEE87007E88A9 /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */; 453 | productName = KeyboardShortcuts; 454 | }; 455 | 69ED90232AAF752600137DA5 /* LaunchAtLogin */ = { 456 | isa = XCSwiftPackageProductDependency; 457 | package = 69ED90222AAF752600137DA5 /* XCRemoteSwiftPackageReference "LaunchAtLogin-Modern" */; 458 | productName = LaunchAtLogin; 459 | }; 460 | /* End XCSwiftPackageProductDependency section */ 461 | }; 462 | rootObject = 69A392EF2AAE152B007B9101 /* Project object */; 463 | } 464 | --------------------------------------------------------------------------------