mirror of
https://github.com/MonitorControl/MonitorControl.git
synced 2026-05-21 06:46:18 -06:00
Stability and functionality improvements
- Displays with screens that are shadowed by a mirror are now controlled along with the mirror master. - Fixed OSD when a display is shadowed by an uncontrollable master (first potent shadowed will provide OSD) - Fixed scenario of constant screen configuration changes (like when user closes and opens lid or plugs/unplugs displays rapidly)
This commit is contained in:
parent
5333f2c1cd
commit
19ef0efa11
17 changed files with 86 additions and 84 deletions
|
|
@ -17,8 +17,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
var keyRepeatTimers: [MediaKey: Timer] = [:]
|
var keyRepeatTimers: [MediaKey: Timer] = [:]
|
||||||
let coreAudio = SimplyCoreAudio()
|
let coreAudio = SimplyCoreAudio()
|
||||||
var accessibilityObserver: NSObjectProtocol!
|
var accessibilityObserver: NSObjectProtocol!
|
||||||
var willReconfigureDisplay: Bool = false // A reconfigure display command is already dispatched
|
var reconfigureID: Int = 0 // dispatched reconfigure command ID
|
||||||
var displaySleep: Int = 0 // Don't reconfigure display as the system or display is sleeping or wake just recently.
|
var sleepID: Int = 0 // Don't reconfigure display as the system or display is sleeping or wake just recently.
|
||||||
lazy var preferencesWindowController: PreferencesWindowController = {
|
lazy var preferencesWindowController: PreferencesWindowController = {
|
||||||
let storyboard = NSStoryboard(name: "Main", bundle: Bundle.main)
|
let storyboard = NSStoryboard(name: "Main", bundle: Bundle.main)
|
||||||
let mainPrefsVc = storyboard.instantiateController(withIdentifier: "MainPrefsVC") as? MainPrefsViewController
|
let mainPrefsVc = storyboard.instantiateController(withIdentifier: "MainPrefsVC") as? MainPrefsViewController
|
||||||
|
|
@ -108,7 +108,13 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
|
||||||
func getDisplayName(displayID: CGDirectDisplayID) -> String {
|
func getDisplayName(displayID: CGDirectDisplayID) -> String {
|
||||||
let defaultName: String = NSLocalizedString("Unknown", comment: "Unknown display name") // + String(CGDisplaySerialNumber(displayID))
|
let defaultName: String = NSLocalizedString("Unknown", comment: "Unknown display name") // + String(CGDisplaySerialNumber(displayID))
|
||||||
if let dictionary = ((CoreDisplay_DisplayCreateInfoDictionary(displayID))?.takeRetainedValue() as NSDictionary?), let nameList = dictionary["DisplayProductName"] as? [String: String], let name = nameList[Locale.current.identifier] ?? nameList["en_US"] ?? nameList.first?.value {
|
if let dictionary = ((CoreDisplay_DisplayCreateInfoDictionary(displayID))?.takeRetainedValue() as NSDictionary?), let nameList = dictionary["DisplayProductName"] as? [String: String], var name = nameList[Locale.current.identifier] ?? nameList["en_US"] ?? nameList.first?.value {
|
||||||
|
if CGDisplayIsInHWMirrorSet(displayID) != 0 || CGDisplayIsInMirrorSet(displayID) != 0 {
|
||||||
|
let mirroredDisplayID = CGDisplayMirrorsDisplay(displayID)
|
||||||
|
if mirroredDisplayID != 0, let dictionary = ((CoreDisplay_DisplayCreateInfoDictionary(mirroredDisplayID))?.takeRetainedValue() as NSDictionary?), let nameList = dictionary["DisplayProductName"] as? [String: String], let mirroredName = nameList[Locale.current.identifier] ?? nameList["en_US"] ?? nameList.first?.value {
|
||||||
|
name.append("~" + mirroredName)
|
||||||
|
}
|
||||||
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
if let screen = NSScreen.getByDisplayID(displayID: displayID) {
|
if let screen = NSScreen.getByDisplayID(displayID: displayID) {
|
||||||
|
|
@ -118,16 +124,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
return screen.displayName ?? defaultName
|
return screen.displayName ?? defaultName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if CGDisplayIsInHWMirrorSet(displayID) != 0 || CGDisplayIsInMirrorSet(displayID) != 0 {
|
|
||||||
if let mirroredScreen = NSScreen.getByDisplayID(displayID: CGDisplayMirrorsDisplay(displayID)) {
|
|
||||||
let name = NSLocalizedString("Mirror of", comment: "Shown in case a display mirrors an other display - like 'Mirror of DisplayName")
|
|
||||||
if #available(OSX 10.15, *) {
|
|
||||||
return "" + name + " " + String(mirroredScreen.localizedName)
|
|
||||||
} else {
|
|
||||||
return "" + name + " " + String(mirroredScreen.displayName ?? defaultName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultName
|
return defaultName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,21 +151,22 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func displayReconfigured() {
|
func displayReconfigured() {
|
||||||
if !self.willReconfigureDisplay, self.displaySleep == 0 {
|
if self.sleepID == 0 {
|
||||||
self.willReconfigureDisplay = true
|
self.reconfigureID += 1
|
||||||
os_log("Display to be reconfigured via updateDisplay in 2 seconds", type: .info)
|
let dispatchedReconfigureID = self.reconfigureID
|
||||||
|
os_log("Display to be reconfigured with reconfigureID %{public}@", type: .info, String(dispatchedReconfigureID))
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
|
||||||
self.updateDisplays()
|
self.updateDisplays(dispatchedReconfigureID: dispatchedReconfigureID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateDisplays() {
|
func updateDisplays(dispatchedReconfigureID: Int = 0) {
|
||||||
guard self.displaySleep == 0 else {
|
guard self.sleepID == 0, dispatchedReconfigureID == self.reconfigureID else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
os_log("Request for updateDisplay", type: .info)
|
os_log("Request for updateDisplay with reconfigreID %{public}@", type: .info, String(dispatchedReconfigureID))
|
||||||
self.willReconfigureDisplay = false
|
self.reconfigureID = 0
|
||||||
self.clearDisplays()
|
self.clearDisplays()
|
||||||
var onlineDisplayIDs = [CGDirectDisplayID](repeating: 0, count: 10)
|
var onlineDisplayIDs = [CGDirectDisplayID](repeating: 0, count: 10)
|
||||||
var displayCount: UInt32 = 0
|
var displayCount: UInt32 = 0
|
||||||
|
|
@ -286,24 +283,24 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func sleepNotification() {
|
@objc private func sleepNotification() {
|
||||||
self.displaySleep += 1
|
self.sleepID += 1
|
||||||
os_log("Sleeping with sleep %{public}@", type: .info, String(self.displaySleep))
|
os_log("Sleeping with sleep %{public}@", type: .info, String(self.sleepID))
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func wakeNotofication() {
|
@objc private func wakeNotofication() {
|
||||||
if self.displaySleep != 0 {
|
if self.sleepID != 0 {
|
||||||
os_log("Waking up from sleep %{public}@", type: .info, String(self.displaySleep))
|
os_log("Waking up from sleep %{public}@", type: .info, String(self.sleepID))
|
||||||
let sleepID = self.displaySleep
|
let dispatchedSleepID = self.sleepID
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) { // Some displays take time to recover...
|
DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) { // Some displays take time to recover...
|
||||||
self.soberNow(sleepID: sleepID)
|
self.soberNow(dispatchedSleepID: dispatchedSleepID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func soberNow(sleepID: Int) {
|
private func soberNow(dispatchedSleepID: Int) {
|
||||||
if self.displaySleep == sleepID {
|
if self.sleepID == dispatchedSleepID {
|
||||||
os_log("Sober from sleep %{public}@", type: .info, String(self.displaySleep))
|
os_log("Sober from sleep %{public}@", type: .info, String(self.sleepID))
|
||||||
self.displaySleep = 0
|
self.sleepID = 0
|
||||||
self.updateDisplays()
|
self.updateDisplays()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -345,7 +342,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
|
||||||
extension AppDelegate: MediaKeyTapDelegate {
|
extension AppDelegate: MediaKeyTapDelegate {
|
||||||
func handle(mediaKey: MediaKey, event: KeyEvent?, modifiers: NSEvent.ModifierFlags?) {
|
func handle(mediaKey: MediaKey, event: KeyEvent?, modifiers: NSEvent.ModifierFlags?) {
|
||||||
guard self.displaySleep == 0 && !self.willReconfigureDisplay else {
|
guard self.sleepID == 0, self.reconfigureID == 0 else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if self.handleOpenPrefPane(mediaKey: mediaKey, event: event, modifiers: modifiers) {
|
if self.handleOpenPrefPane(mediaKey: mediaKey, event: event, modifiers: modifiers) {
|
||||||
|
|
@ -375,20 +372,37 @@ extension AppDelegate: MediaKeyTapDelegate {
|
||||||
self.sendDisplayCommand(mediaKey: mediaKey, isRepeat: isRepeat, isSmallIncrement: isSmallIncrement)
|
self.sendDisplayCommand(mediaKey: mediaKey, isRepeat: isRepeat, isSmallIncrement: isSmallIncrement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getAffectedDisplays() -> [Display]? {
|
||||||
|
var affectedDisplays: [Display]
|
||||||
|
let allDisplays = DisplayManager.shared.getAllDisplays()
|
||||||
|
guard let currentDisplay = DisplayManager.shared.getCurrentDisplay() else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// let allDisplays = prefs.bool(forKey: Utils.PrefKeys.allScreens.rawValue) ? displays : [currentDisplay]
|
||||||
|
if prefs.bool(forKey: Utils.PrefKeys.allScreens.rawValue) {
|
||||||
|
affectedDisplays = allDisplays
|
||||||
|
} else {
|
||||||
|
affectedDisplays = [currentDisplay]
|
||||||
|
if CGDisplayIsInHWMirrorSet(currentDisplay.identifier) != 0 || CGDisplayIsInMirrorSet(currentDisplay.identifier) != 0, CGDisplayMirrorsDisplay(currentDisplay.identifier) == 0 {
|
||||||
|
for display in allDisplays where CGDisplayMirrorsDisplay(display.identifier) == currentDisplay.identifier {
|
||||||
|
affectedDisplays.append(display)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return affectedDisplays
|
||||||
|
}
|
||||||
|
|
||||||
private func sendDisplayCommand(mediaKey: MediaKey, isRepeat: Bool, isSmallIncrement: Bool) {
|
private func sendDisplayCommand(mediaKey: MediaKey, isRepeat: Bool, isSmallIncrement: Bool) {
|
||||||
guard self.displaySleep == 0, !self.willReconfigureDisplay else {
|
guard self.sleepID == 0, self.reconfigureID == 0, let affectedDisplays = self.getAffectedDisplays() else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let displays = DisplayManager.shared.getAllDisplays()
|
|
||||||
guard let currentDisplay = DisplayManager.shared.getCurrentDisplay() else { return }
|
|
||||||
let allDisplays = prefs.bool(forKey: Utils.PrefKeys.allScreens.rawValue) ? displays : [currentDisplay]
|
|
||||||
let delay = isRepeat ? 0.05 : 0 // Introduce a small delay to handle the media key being held down
|
let delay = isRepeat ? 0.05 : 0 // Introduce a small delay to handle the media key being held down
|
||||||
var isAnyDisplayInContrastAfterBrightnessMode: Bool = false
|
var isAnyDisplayInContrastAfterBrightnessMode: Bool = false
|
||||||
for display in allDisplays where (display as? ExternalDisplay)?.isContrastAfterBrightnessMode ?? false {
|
for display in affectedDisplays where (display as? ExternalDisplay)?.isContrastAfterBrightnessMode ?? false {
|
||||||
isAnyDisplayInContrastAfterBrightnessMode = true
|
isAnyDisplayInContrastAfterBrightnessMode = true
|
||||||
}
|
}
|
||||||
self.keyRepeatTimers[mediaKey] = Timer.scheduledTimer(withTimeInterval: delay, repeats: false, block: { _ in
|
self.keyRepeatTimers[mediaKey] = Timer.scheduledTimer(withTimeInterval: delay, repeats: false, block: { _ in
|
||||||
for display in allDisplays where display.isEnabled && !display.isVirtual {
|
for display in affectedDisplays where display.isEnabled && !display.isVirtual {
|
||||||
switch mediaKey {
|
switch mediaKey {
|
||||||
case .brightnessUp:
|
case .brightnessUp:
|
||||||
if !(isAnyDisplayInContrastAfterBrightnessMode && !((display as? ExternalDisplay)?.isContrastAfterBrightnessMode ?? false)) {
|
if !(isAnyDisplayInContrastAfterBrightnessMode && !((display as? ExternalDisplay)?.isContrastAfterBrightnessMode ?? false)) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1686</string>
|
<string>1722</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.utilities</string>
|
<string>public.app-category.utilities</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ class DisplayManager {
|
||||||
self.displays = displays
|
self.displays = displays
|
||||||
}
|
}
|
||||||
|
|
||||||
// cell.button.state = ((display as? ExternalDisplay)?.arm64ddc ?? false) ? .on : .off
|
|
||||||
|
|
||||||
func getExternalDisplays() -> [ExternalDisplay] {
|
func getExternalDisplays() -> [ExternalDisplay] {
|
||||||
return self.displays.compactMap { $0 as? ExternalDisplay }
|
return self.displays.compactMap { $0 as? ExternalDisplay }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,23 @@ class Display {
|
||||||
return self.prefs.string(forKey: "friendlyName-\(self.identifier)") ?? self.name
|
return self.prefs.string(forKey: "friendlyName-\(self.identifier)") ?? self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getShowOsdDisplayId() -> CGDirectDisplayID {
|
||||||
|
if CGDisplayIsInHWMirrorSet(self.identifier) != 0 || CGDisplayIsInMirrorSet(self.identifier) != 0, CGDisplayMirrorsDisplay(self.identifier) != 0 {
|
||||||
|
for mirrorMaestro in DisplayManager.shared.getAllDisplays() where CGDisplayMirrorsDisplay(self.identifier) == mirrorMaestro.identifier {
|
||||||
|
if let externalMirrorMaestro = mirrorMaestro as? ExternalDisplay, !externalMirrorMaestro.arm64ddc, externalMirrorMaestro.ddc == nil {
|
||||||
|
var thereAreOthers = false
|
||||||
|
for mirrorMember in DisplayManager.shared.getAllDisplays() where CGDisplayMirrorsDisplay(mirrorMember.identifier) == CGDisplayMirrorsDisplay(self.identifier) && mirrorMember.identifier != self.identifier {
|
||||||
|
thereAreOthers = true
|
||||||
|
}
|
||||||
|
if !thereAreOthers {
|
||||||
|
return externalMirrorMaestro.identifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self.identifier
|
||||||
|
}
|
||||||
|
|
||||||
func showOsd(command: DDC.Command, value: Int, maxValue: Int = 100, roundChiclet: Bool = false) {
|
func showOsd(command: DDC.Command, value: Int, maxValue: Int = 100, roundChiclet: Bool = false) {
|
||||||
guard let manager = OSDManager.sharedManager() as? OSDManager else {
|
guard let manager = OSDManager.sharedManager() as? OSDManager else {
|
||||||
return
|
return
|
||||||
|
|
@ -80,7 +97,7 @@ class Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.showImage(osdImage.rawValue,
|
manager.showImage(osdImage.rawValue,
|
||||||
onDisplayID: self.identifier,
|
onDisplayID: self.getShowOsdDisplayId(),
|
||||||
priority: 0x1F4,
|
priority: 0x1F4,
|
||||||
msecUntilFade: 1000,
|
msecUntilFade: 1000,
|
||||||
filledChiclets: UInt32(filledChiclets),
|
filledChiclets: UInt32(filledChiclets),
|
||||||
|
|
|
||||||
|
|
@ -187,13 +187,11 @@ class ExternalDisplay: Display {
|
||||||
}
|
}
|
||||||
if !self.isContrastAfterBrightnessMode {
|
if !self.isContrastAfterBrightnessMode {
|
||||||
let ddcValue = UInt16(osdValue)
|
let ddcValue = UInt16(osdValue)
|
||||||
if !isAlreadySet {
|
guard self.writeDDCValues(command: .brightness, value: ddcValue) == true else {
|
||||||
guard self.writeDDCValues(command: .brightness, value: ddcValue) == true else {
|
return
|
||||||
return
|
}
|
||||||
}
|
if let slider = brightnessSliderHandler?.slider {
|
||||||
if let slider = brightnessSliderHandler?.slider {
|
slider.intValue = Int32(ddcValue)
|
||||||
slider.intValue = Int32(ddcValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.showOsd(command: .brightness, value: osdValue, roundChiclet: !isSmallIncrement)
|
self.showOsd(command: .brightness, value: osdValue, roundChiclet: !isSmallIncrement)
|
||||||
self.saveValue(osdValue, for: .brightness)
|
self.saveValue(osdValue, for: .brightness)
|
||||||
|
|
@ -201,6 +199,9 @@ class ExternalDisplay: Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func writeDDCValues(command: DDC.Command, value: UInt16, errorRecoveryWaitTime _: UInt32? = nil) -> Bool? {
|
public func writeDDCValues(command: DDC.Command, value: UInt16, errorRecoveryWaitTime _: UInt32? = nil) -> Bool? {
|
||||||
|
guard app.sleepID == 0, app.reconfigureID == 0 else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if Arm64DDCUtils.isArm64 {
|
if Arm64DDCUtils.isArm64 {
|
||||||
guard self.arm64ddc else {
|
guard self.arm64ddc else {
|
||||||
return false
|
return false
|
||||||
|
|
@ -219,6 +220,9 @@ class ExternalDisplay: Display {
|
||||||
|
|
||||||
func readDDCValues(for command: DDC.Command, tries: UInt, minReplyDelay delay: UInt64?) -> (current: UInt16, max: UInt16)? {
|
func readDDCValues(for command: DDC.Command, tries: UInt, minReplyDelay delay: UInt64?) -> (current: UInt16, max: UInt16)? {
|
||||||
var values: (UInt16, UInt16)?
|
var values: (UInt16, UInt16)?
|
||||||
|
guard app.sleepID == 0, app.reconfigureID == 0 else {
|
||||||
|
return values
|
||||||
|
}
|
||||||
if Arm64DDCUtils.isArm64 {
|
if Arm64DDCUtils.isArm64 {
|
||||||
guard self.arm64ddc else {
|
guard self.arm64ddc else {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Allgemein";
|
"General" = "Allgemein";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "General";
|
"General" = "General";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Général";
|
"General" = "Général";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Általános";
|
"General" = "Általános";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Tükrözött";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "Nem";
|
"No" = "Nem";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Generale";
|
"General" = "Generale";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "一般";
|
"General" = "一般";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Ogólne";
|
"General" = "Ogólne";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "Nie";
|
"No" = "Nie";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Основные";
|
"General" = "Основные";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "Загальні";
|
"General" = "Загальні";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
/* Shown in the main prefs window */
|
/* Shown in the main prefs window */
|
||||||
"General" = "通用";
|
"General" = "通用";
|
||||||
|
|
||||||
/* Shown in case a display mirrors an other display - like 'Mirror of DisplayName */
|
|
||||||
"Mirror of" = "Mirror of";
|
|
||||||
|
|
||||||
/* Shown in the alert dialog */
|
/* Shown in the alert dialog */
|
||||||
"No" = "No";
|
"No" = "No";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ class SliderHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func valueChanged(slider: NSSlider) {
|
@objc func valueChanged(slider: NSSlider) {
|
||||||
|
guard app.sleepID == 0, app.reconfigureID == 0 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
let snapInterval = 25
|
let snapInterval = 25
|
||||||
let snapThreshold = 3
|
let snapThreshold = 3
|
||||||
|
|
||||||
|
|
@ -37,10 +40,6 @@ class SliderHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard app.displaySleep == 0, !app.willReconfigureDisplay else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = self.display.writeDDCValues(command: self.cmd, value: UInt16(value))
|
_ = self.display.writeDDCValues(command: self.cmd, value: UInt16(value))
|
||||||
self.display.saveValue(value, for: self.cmd)
|
self.display.saveValue(value, for: self.cmd)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1686</string>
|
<string>1722</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.utilities</string>
|
<string>public.app-category.utilities</string>
|
||||||
<key>LSBackgroundOnly</key>
|
<key>LSBackgroundOnly</key>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue