diff --git a/README.md b/README.md index 242dc68..444d12b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ ## toggleMute +### note +I don't use a MacBook with Touch Bar anymore. So if there are any issues with the Touch Bar, I can't help/debug by myself + ### functions - Single tab/click on the Touch Bar or the Menubar icon will toggle between mute and unmute. - Right click on the Menubar icon will show the setting for the default unmute volume. @@ -8,8 +11,10 @@ - click on the little gear symbol will show the option to set a global _Keyboard Shortcut_, the option for _Autostart_ and a _Quit_ button ### install -- download and unpack the toggleMute.zip -- move the _toggleMute.app_ file to the Applications directory +- download or clone the repo +- unpack the toggleMute.zip and move toggleMute.app into the Applications folder +- execute (just double click) the toggleMuteDisableQuarantine.command + - if this does not work, you have to execute `xattr -cr /Applications/toggleMute.app` in a terminal - start the App the first time via right click > open and "Trust me" :wink: - the Touch Bar button is only visible in the "control strip" and can't be moved to any other place diff --git a/img/app_prev.png b/img/app_prev.png index 7c7b065..9ab9011 100644 Binary files a/img/app_prev.png and b/img/app_prev.png differ diff --git a/img/menubar_prev.png b/img/menubar_prev.png index 0878030..4ae8022 100644 Binary files a/img/menubar_prev.png and b/img/menubar_prev.png differ diff --git a/toggleMute.zip b/toggleMute.zip index 2ba44c2..b15f933 100644 Binary files a/toggleMute.zip and b/toggleMute.zip differ diff --git a/toggleMute/toggleMute.xcodeproj/project.pbxproj b/toggleMute/toggleMute.xcodeproj/project.pbxproj index e6945e6..d500665 100644 --- a/toggleMute/toggleMute.xcodeproj/project.pbxproj +++ b/toggleMute/toggleMute.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -14,7 +14,6 @@ 449F397C23172ADC008A0DBD /* Controllers.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 449F397B23172ADC008A0DBD /* Controllers.storyboard */; }; 449F398323173003008A0DBD /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 449F398223173003008A0DBD /* Preferences.swift */; }; 449F398D23173610008A0DBD /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 449F398C23173610008A0DBD /* SettingsController.swift */; }; - 449F39932317375C008A0DBD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 449F39952317375C008A0DBD /* Localizable.strings */; }; 44D551E02390830E0065505A /* SharedFileList.m in Sources */ = {isa = PBXBuildFile; fileRef = 44D551DE2390830E0065505A /* SharedFileList.m */; }; 44EB8BD923AC2ABD005A4A0B /* TouchBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44EB8BD723AC2ABD005A4A0B /* TouchBarController.swift */; }; 44EB8BDD23AC350D005A4A0B /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44EB8BDB23AC350D005A4A0B /* SettingsViewController.swift */; }; @@ -44,8 +43,6 @@ 449F397B23172ADC008A0DBD /* Controllers.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Controllers.storyboard; sourceTree = ""; }; 449F398223173003008A0DBD /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; 449F398C23173610008A0DBD /* SettingsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = ""; }; - 449F39942317375C008A0DBD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - 449F39962317375D008A0DBD /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 44D551DD2390830E0065505A /* SettingsController-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SettingsController-Bridging-Header.h"; sourceTree = ""; }; 44D551DE2390830E0065505A /* SharedFileList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SharedFileList.m; sourceTree = ""; }; 44D551DF2390830E0065505A /* SharedFileList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedFileList.h; sourceTree = ""; }; @@ -109,7 +106,6 @@ isa = PBXGroup; children = ( 44D551DC239082090065505A /* Storyboard */, - 449F399023173742008A0DBD /* Localizable */, 449F398023172AEE008A0DBD /* Assets */, 449F39702317247C008A0DBD /* Info.plist */, 449F39712317247C008A0DBD /* SettingsController.entitlements */, @@ -125,14 +121,6 @@ path = Assets; sourceTree = ""; }; - 449F399023173742008A0DBD /* Localizable */ = { - isa = PBXGroup; - children = ( - 449F39952317375C008A0DBD /* Localizable.strings */, - ); - path = Localizable; - sourceTree = ""; - }; 44D551D923907B7F0065505A /* Support */ = { isa = PBXGroup; children = ( @@ -211,6 +199,7 @@ en, fr, Base, + de, ); mainGroup = 449F395D2317247B008A0DBD; packageReferences = ( @@ -232,7 +221,6 @@ buildActionMask = 2147483647; files = ( 449F396C2317247C008A0DBD /* Assets.xcassets in Resources */, - 449F39932317375C008A0DBD /* Localizable.strings in Resources */, 449F397C23172ADC008A0DBD /* Controllers.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -277,18 +265,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - 449F39952317375C008A0DBD /* Localizable.strings */ = { - isa = PBXVariantGroup; - children = ( - 449F39942317375C008A0DBD /* en */, - 449F39962317375D008A0DBD /* fr */, - ); - name = Localizable.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 449F39722317247C008A0DBD /* Debug */ = { isa = XCBuildConfiguration; @@ -418,7 +394,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = MFTS39V3F9; ENABLE_HARDENED_RUNTIME = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -430,7 +406,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 1.4; + MARKETING_VERSION = 1.5; OTHER_LDFLAGS = ( "-framework", DFRFoundation, @@ -452,7 +428,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = MFTS39V3F9; ENABLE_HARDENED_RUNTIME = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -464,7 +440,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 1.4; + MARKETING_VERSION = 1.5; OTHER_LDFLAGS = ( "-framework", DFRFoundation, @@ -504,16 +480,16 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/sindresorhus/KeyboardShortcuts"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.4.0; + kind = exactVersion; + version = 1.17.0; }; }; BD391AE7263C3F5600848049 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/sindresorhus/LaunchAtLogin"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 4.1.0; + kind = exactVersion; + version = 5.0.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 709f1c0..e7324c7 100644 --- a/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,25 +1,23 @@ { - "object": { - "pins": [ - { - "package": "KeyboardShortcuts", - "repositoryURL": "https://github.com/sindresorhus/KeyboardShortcuts", - "state": { - "branch": null, - "revision": "9bc72c441c713362a137ecbb4104920655a9aa5e", - "version": "1.4.0" - } - }, - { - "package": "LaunchAtLogin", - "repositoryURL": "https://github.com/sindresorhus/LaunchAtLogin", - "state": { - "branch": null, - "revision": "6b16bcdf7d45a9d76a768a5c4912dde925cf0e95", - "version": "4.1.0" - } + "pins" : [ + { + "identity" : "keyboardshortcuts", + "kind" : "remoteSourceControl", + "location" : "https://github.com/sindresorhus/KeyboardShortcuts", + "state" : { + "revision" : "ac12762853126cf2e7ad63a6a58e1c9f58c6a0ee", + "version" : "1.17.0" } - ] - }, - "version": 1 + }, + { + "identity" : "launchatlogin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/sindresorhus/LaunchAtLogin", + "state" : { + "revision" : "7ad6331f9c38953eb1ce8737758e18f7607e984a", + "version" : "5.0.0" + } + } + ], + "version" : 2 } diff --git a/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcuserdata/administrator.xcuserdatad/UserInterfaceState.xcuserstate b/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcuserdata/administrator.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..9a7114c Binary files /dev/null and b/toggleMute/toggleMute.xcodeproj/project.xcworkspace/xcuserdata/administrator.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/toggleMute/toggleMute.xcodeproj/xcuserdata/c5289575.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/toggleMute/toggleMute.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist similarity index 100% rename from toggleMute/toggleMute.xcodeproj/xcuserdata/c5289575.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist rename to toggleMute/toggleMute.xcodeproj/xcuserdata/user.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist diff --git a/toggleMute/toggleMute/Bootstrap/AppDelegate.swift b/toggleMute/toggleMute/Bootstrap/AppDelegate.swift index 54b1ad0..85fc4df 100644 --- a/toggleMute/toggleMute/Bootstrap/AppDelegate.swift +++ b/toggleMute/toggleMute/Bootstrap/AppDelegate.swift @@ -1,13 +1,14 @@ // Author: Sascha Petrik import Cocoa +import LaunchAtLogin import KeyboardShortcuts @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) - + let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength) + private lazy var preferences = Preferences() private lazy var settingsController = SettingsController() private lazy var mainController = MainController() @@ -19,10 +20,15 @@ class AppDelegate: NSObject, NSApplicationDelegate { let imageUnmute = NSImage(named: NSImage.touchBarAudioInputTemplateName) let imageMute = NSImage(named: NSImage.touchBarAudioInputMuteTemplateName) + func applicationDidFinishLaunching(_ aNotification: Notification) { + + LaunchAtLogin.migrateIfNeeded() + refreshTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(runTimedCode), userInfo: nil, repeats: true) + if let button = self.statusItem.button { - button.image = imageUnmute + button.image = touchBarController.imageUnmute?.tint(color: .selectedMenuItemTextColor) button.imageScaling = .scaleProportionallyDown button.target = self button.action = #selector(statusBarButtonClicked) @@ -38,9 +44,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { defaults.set(false, forKey: "updateAvailable") defaults.set(true, forKey: "firstStart") - let getlocalVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String let stringLocalVersion = getlocalVersion! as NSString + defaults.set(stringLocalVersion, forKey: "stringLocalVersion") let localVersion = stringLocalVersion.doubleValue let url = URL(string: "https://raw.githubusercontent.com/satrik/toggleMute/main/toggleMute/toggleMute.xcodeproj/project.pbxproj")! @@ -54,14 +60,18 @@ class AppDelegate: NSObject, NSApplicationDelegate { let secondIndex = ";" let stringVersion = getString.slice(from: firstIndex, to: secondIndex) let githubVersion = Double(stringVersion!)! - + if githubVersion > localVersion { self.defaults.set(true, forKey: "updateAvailable") } + } + task.resume() + } + @objc func runTimedCode(){ mainController.getCurrentVolume() @@ -74,6 +84,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } + @objc func statusBarButtonClicked(sender: NSStatusBarButton) { let event = NSApp.currentEvent! @@ -89,9 +100,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } + @objc private func showMainController() { - guard let button = statusItem.button else { fatalError("Couldn't find status item button.") } @@ -114,10 +125,14 @@ class AppDelegate: NSObject, NSApplicationDelegate { } + func isKeyPresentInUserDefaults(key: String) -> Bool { + return UserDefaults.standard.object(forKey: key) != nil + } + func dialogOKCancel(question: String, text: String) -> Bool { let alert = NSAlert() diff --git a/toggleMute/toggleMute/Controllers/MainController.swift b/toggleMute/toggleMute/Controllers/MainController.swift index 9710f47..b46d41d 100644 --- a/toggleMute/toggleMute/Controllers/MainController.swift +++ b/toggleMute/toggleMute/Controllers/MainController.swift @@ -17,21 +17,31 @@ class MainController: NSViewController { let defaults = UserDefaults.standard var currentSetVolume = 0 + static func instantiate(with settingsController: SettingsController, and preferences: Preferences) -> MainController { + let storyboard = NSStoryboard(name: "Controllers", bundle: nil) + guard let mainController = storyboard.instantiateController(withIdentifier: "MainController") as? MainController else { fatalError("Unable to find MainController in the storyboard.") } + mainController.settingsController = settingsController mainController.preferences = preferences return mainController + } + func isKeyPresentInUserDefaults(key: String) -> Bool { + return UserDefaults.standard.object(forKey: key) != nil + } + override func viewDidLoad() { + super.viewDidLoad() setupNotifications() @@ -58,58 +68,84 @@ class MainController: NSViewController { } + private func setupNotifications() { + NotificationCenter.default.addObserver(self, selector: #selector(preferencesDidChange), name: Preferences.didChangeNotification, object: nil) + } + @objc private func preferencesDidChange() { // nothing to do currently } + @IBAction func didChangeSlider(_ sender: Any) { + guard let slider = sender as? NSSlider, let event = NSApplication.shared.currentEvent else { return } let val = slider.integerValue let label = inputValueLabel switch event.type { + case .leftMouseDown, .rightMouseDown: break // nothing to do if drag just started + case .leftMouseUp, .rightMouseUp: label?.stringValue = String(val) defaults.set(val, forKey: "defaultInputVol") self.touchBarController.setNewVolume(newValue: val) + case .leftMouseDragged, .rightMouseDragged: label?.stringValue = String(val) + default: break } + } + func getCurrentVolume() { - + let setInputVolume = "return input volume of (get volume settings)" var error: NSDictionary? + if let scriptObject = NSAppleScript(source: setInputVolume) { + if let outputString = scriptObject.executeAndReturnError(&error).stringValue { + currentSetVolume = Int(outputString)! defaults.set(currentSetVolume, forKey: "currentSetVolume") + } else if (error != nil) { + // no error handling currently as it just works always :D } + } + } + @IBAction func didTouchSettings(_ sender: Any) { + let settingsController = SettingsViewController.instantiate(with: preferences) let popoverView = NSPopover() popoverView.contentViewController = settingsController popoverView.behavior = .transient popoverView.show(relativeTo: settingsButton.bounds, of: settingsButton, preferredEdge: .maxY) + } + @IBAction func didTouchOpenGithub(_ sender: Any) { + if NSWorkspace.shared.open(repoUrl) {} + } + } diff --git a/toggleMute/toggleMute/Controllers/SettingsViewController.swift b/toggleMute/toggleMute/Controllers/SettingsViewController.swift index 7a8b9d8..20686a5 100644 --- a/toggleMute/toggleMute/Controllers/SettingsViewController.swift +++ b/toggleMute/toggleMute/Controllers/SettingsViewController.swift @@ -11,19 +11,27 @@ extension KeyboardShortcuts.Name { class SettingsViewController: NSViewController { @IBOutlet var launchAtLoginCheckBox: NSButton! - @IBOutlet var redMenuBarCheckBox: NSButton! + @IBOutlet weak var redMenuBarIconCheckBox: NSButton! + @IBOutlet weak var redMenuBarBackgroundCheckBox: NSButton! @IBOutlet var quitButton: NSButton! @IBOutlet weak var shortcutSubView: NSView! + @IBOutlet weak var versionLabel: NSTextField! private var preferences: Preferences! let defaults = UserDefaults.standard private var delegateController = NSApplication.shared.delegate as! AppDelegate + private lazy var touchBarController = TouchBarController() func isKeyPresentInUserDefaults(key: String) -> Bool { + return UserDefaults.standard.object(forKey: key) != nil + } + static func instantiate(with preferences: Preferences) -> SettingsViewController { + let storyboard = NSStoryboard(name: "Controllers", bundle: nil) + guard let settingsController = storyboard.instantiateController(withIdentifier: "SettingsController") as? SettingsViewController else { fatalError("Unable to find SettingsController in the storyboard.") } @@ -31,54 +39,103 @@ class SettingsViewController: NSViewController { settingsController.preferences = preferences return settingsController + } + override func viewDidLoad() { super.viewDidLoad() - + + if(isKeyPresentInUserDefaults(key: "stringLocalVersion")) { + let version = defaults.string(forKey: "stringLocalVersion") ?? "-" + versionLabel.stringValue = "Version: \(version)" + } + launchAtLoginCheckBox.state = preferences.launchAtLoginEnabled ? .on : .off - launchAtLoginCheckBox.title = NSLocalizedString("launchAtLogin", comment: "") + + if(isKeyPresentInUserDefaults(key: "redMenuBarBackground")) { + redMenuBarBackgroundCheckBox.state = defaults.bool(forKey: "redMenuBarBackground") ? .on : .off + } else { + redMenuBarBackgroundCheckBox.state = .off + } if(isKeyPresentInUserDefaults(key: "redMenuBarIcon")) { - redMenuBarCheckBox.state = defaults.bool(forKey: "redMenuBarIcon") ? .on : .off + redMenuBarIconCheckBox.state = defaults.bool(forKey: "redMenuBarIcon") ? .on : .off } else { - redMenuBarCheckBox.state = .off + redMenuBarIconCheckBox.state = .off } let recorder = KeyboardShortcuts.RecorderCocoa(for: .toggleMuteShortcut) - shortcutSubView.addSubview(recorder) - - quitButton.title = NSLocalizedString("quit", comment: "") + + recorder.translatesAutoresizingMaskIntoConstraints = false + recorder.widthAnchor.constraint(greaterThanOrEqualToConstant: 130).isActive = true + recorder.heightAnchor.constraint(greaterThanOrEqualToConstant: 24).isActive = true + shortcutSubView.addSubview(recorder) + } + override func viewDidDisappear() { + super.viewDidDisappear() NSApp.activate(ignoringOtherApps: true) + } @IBAction func didTouchLaunchAtLogin(_ sender: NSButton) { + preferences.launchAtLoginEnabled = sender.state == .on ? true : false LaunchAtLogin.isEnabled = preferences.launchAtLoginEnabled } + + @IBAction func didTouchRedMenuBarIcon(_ sender: NSButton) { - - let checkBoxState = sender.state == .on ? true : false + let isMuted = defaults.bool(forKey: "isMuted") - defaults.set(checkBoxState, forKey: "redMenuBarIcon") + let button = delegateController.statusItem.button - if(checkBoxState && isMuted) { - delegateController.statusItem.button?.layer?.backgroundColor = CGColor(red: 0.75, green: 0, blue: 0 , alpha: 0.75) - } else { - delegateController.statusItem.button?.layer?.backgroundColor = CGColor(red: 0, green: 0, blue: 0 , alpha: 0) + if(sender.title == "Icon") { + + let checkBoxState = sender.state == .on ? true : false + defaults.set(checkBoxState, forKey: "redMenuBarIcon") + + if(isMuted){ + if(checkBoxState) { + button?.image = touchBarController.imageMute?.tint(color: .red) + } else { + button?.image = touchBarController.imageMute?.tint(color: .selectedMenuItemTextColor) + } + } + + + + } else if (sender.title == "Background") { + + let checkBoxState = sender.state == .on ? true : false + defaults.set(checkBoxState, forKey: "redMenuBarBackground") + + if(isMuted) { + + if(checkBoxState) { + button?.layer?.backgroundColor = CGColor(red: 1.0, green: 0, blue: 0 , alpha: 1.0) + } else { + button?.layer?.backgroundColor = CGColor(red: 0, green: 0, blue: 0 , alpha: 0) + } + + } + } - - } + } + + @IBAction func didTouchClose(_ sender: Any) { + NSApplication.shared.terminate(nil) + } } diff --git a/toggleMute/toggleMute/Controllers/TouchBarController.swift b/toggleMute/toggleMute/Controllers/TouchBarController.swift index c207079..f3df669 100644 --- a/toggleMute/toggleMute/Controllers/TouchBarController.swift +++ b/toggleMute/toggleMute/Controllers/TouchBarController.swift @@ -1,12 +1,12 @@ // Author: Sascha Petrik import Cocoa -import LaunchAtLogin fileprivate extension NSTouchBarItem.Identifier { static let touchBarButtonIdentifier = NSTouchBarItem.Identifier("com.foofoo.touchbarMute") } + class TouchBarController { private var settingsController: SettingsController! @@ -15,31 +15,31 @@ class TouchBarController { let defaults = UserDefaults.standard var isMuted = true || false - var redIcon = true || false - + var redMenuBarIconBackground = true || false + var redMenuBarIcon = true || false + let imageUnmute = NSImage(named: NSImage.touchBarAudioInputTemplateName) let imageMute = NSImage(named: NSImage.touchBarAudioInputMuteTemplateName) var touchBarButton: NSButton? private lazy var item: NSCustomTouchBarItem = { + let i = NSCustomTouchBarItem(identifier: .touchBarButtonIdentifier) return i + }() static func instantiate(with settingsController: SettingsController) -> TouchBarController { + let touchBarController = TouchBarController() touchBarController.settingsController = settingsController return touchBarController + } - - func test() { - if dialogOKCancel(question: "Update available", text: "") { - let updateUrl = URL(string: "https://github.com/satrik/toggleMute")! - NSWorkspace.shared.open(updateUrl) - } - } + + func configureUI() { touchBarButton = NSButton(image: imageUnmute!, target: self, action: #selector(toggleMuteStateObj)) @@ -53,7 +53,7 @@ class TouchBarController { } else { isMuted = false } - + if(isMuted) { defaults.set(false, forKey: "isMuted") toggleMuteStateHard(setMute: true) @@ -64,18 +64,19 @@ class TouchBarController { } + func isKeyPresentInUserDefaults(key: String) -> Bool { return UserDefaults.standard.object(forKey: key) != nil } + @objc func toggleMuteStateObj() { - toggleMuteState() - } + func setNewVolume(newValue: Int) { - + let setInputAndResetOutputVolume = """ set volume input volume \(newValue) @@ -86,9 +87,10 @@ class TouchBarController { if let scriptObject = NSAppleScript(source: setInputAndResetOutputVolume) { scriptObject.executeAndReturnError(&error) } - + } + func toggleMuteState() { if(touchBarButton?.image == imageMute){ @@ -98,32 +100,68 @@ class TouchBarController { } } + func toggleMuteStateHard(setMute: Bool) { let button = delegateController.statusItem.button isMuted = defaults.bool(forKey: "isMuted") - redIcon = defaults.bool(forKey: "redMenuBarIcon") - + redMenuBarIconBackground = defaults.bool(forKey: "redMenuBarBackground") + redMenuBarIcon = defaults.bool(forKey: "redMenuBarIcon") + if(!setMute && isMuted){ + defaults.set(false, forKey: "isMuted") - button?.image = imageUnmute + + button?.image = imageUnmute?.tint(color: .alternateSelectedControlTextColor) + button?.layer?.backgroundColor = CGColor(red: 0, green: 0, blue: 0 , alpha: 0) touchBarButton?.image = imageUnmute touchBarButton?.bezelColor = NSColor.clear var unmuteVal = 80 + if(isKeyPresentInUserDefaults(key: "defaultInputVol")){ unmuteVal = defaults.integer(forKey: "defaultInputVol") } + setNewVolume(newValue: unmuteVal) + } else if(setMute && !isMuted) { + defaults.set(true, forKey: "isMuted") - button?.image = imageMute - if(redIcon){ - button?.layer?.backgroundColor = CGColor(red: 0.75, green: 0, blue: 0 , alpha: 0.75) - } + + button?.image = imageMute?.tint(color: .selectedMenuItemTextColor) + button?.layer?.backgroundColor = CGColor(red: 0, green: 0, blue: 0 , alpha: 0) + touchBarButton?.image = imageMute touchBarButton?.bezelColor = NSColor.red setNewVolume(newValue: 0) + + if(redMenuBarIcon){ + button?.image = imageMute?.tint(color: .red) + } + + if(redMenuBarIconBackground){ + button?.layer?.backgroundColor = CGColor(red: 1.0, green: 0, blue: 0 , alpha: 1.0) + } + } + } + +} + + +extension NSImage { + + func tint(color: NSColor) -> NSImage { + + return NSImage(size: size, flipped: false) { (rect) -> Bool in + color.set() + rect.fill() + self.draw(in: rect, from: NSRect(origin: .zero, size: self.size), operation: .destinationIn, fraction: 1.0) + return true + } + + } + } diff --git a/toggleMute/toggleMute/Resources/Info.plist b/toggleMute/toggleMute/Resources/Info.plist index 27a4310..7729565 100644 --- a/toggleMute/toggleMute/Resources/Info.plist +++ b/toggleMute/toggleMute/Resources/Info.plist @@ -25,7 +25,7 @@ LSUIElement NSHumanReadableCopyright - Copyright © 2022 Sascha Petrik + © 2021-2024 satrik (Sascha Petrik) NSMainStoryboardFile Controllers NSPrincipalClass diff --git a/toggleMute/toggleMute/Resources/Localizable/en.lproj/Localizable.strings b/toggleMute/toggleMute/Resources/Localizable/en.lproj/Localizable.strings deleted file mode 100644 index 3841681..0000000 --- a/toggleMute/toggleMute/Resources/Localizable/en.lproj/Localizable.strings +++ /dev/null @@ -1,3 +0,0 @@ -"quit" = "Quit"; -"launchAtLogin" = "Launch at login"; -"random" = ""; diff --git a/toggleMute/toggleMute/Resources/Localizable/fr.lproj/Localizable.strings b/toggleMute/toggleMute/Resources/Localizable/fr.lproj/Localizable.strings deleted file mode 100644 index 47b7b65..0000000 --- a/toggleMute/toggleMute/Resources/Localizable/fr.lproj/Localizable.strings +++ /dev/null @@ -1,10 +0,0 @@ -/* - Localizable.strings - NootNootBar - - Created by Arnaud Le Bourblanc on 29/08/2019. - Copyright © 2019 Arnaud Le Bourblanc. All rights reserved. -*/ -"quit" = "Quitter"; -"launchAtLogin" = "Lancer au démarrage"; -"random" = "Jouer \"NootNoot\" aléatoirement"; diff --git a/toggleMute/toggleMute/Resources/Storyboard/Controllers.storyboard b/toggleMute/toggleMute/Resources/Storyboard/Controllers.storyboard index 9647160..598109a 100644 --- a/toggleMute/toggleMute/Resources/Storyboard/Controllers.storyboard +++ b/toggleMute/toggleMute/Resources/Storyboard/Controllers.storyboard @@ -1,8 +1,8 @@ - + - + @@ -26,11 +26,11 @@ - + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + - - + + - + + + + + + - + + - + - + @@ -160,7 +215,7 @@ - + diff --git a/toggleMuteDisableQuarantine.command b/toggleMuteDisableQuarantine.command new file mode 100755 index 0000000..7343fe8 --- /dev/null +++ b/toggleMuteDisableQuarantine.command @@ -0,0 +1,30 @@ +#!/bin/bash +#title : toggleMuteDisableQuarantine.command +#description : This script will remove the quarantine from toggleMute.app +#author : sascha.petrik@cgm.com +#date : 20240219 +#version : 1.1 +#usage : double click to execute or via a terminal +#============================================================================ +APPNAME="toggleMute" +APPEXTENSTION=".app" +APPPATH="/Applications/" +APP="$APPPATH$APPNAME$APPEXTENSTION" + +if [[ -d "$APP" ]] +then + xattr -cr $APP + echo " " + echo "===" + echo "$APPNAME should work now. Remeber to open it the first time by 'Right Click > Open' and 'Trust me' :)" + echo "===" + echo " " +else + echo " " + echo "===" + echo "$APPNAME in $APPPATH not found. Make sure to unzip the app and move it in the $APPPATH folder before running this command again" + echo "===" + echo " " +fi + +exit 0 \ No newline at end of file