Addition of a "friendly" display name for Monitors (#89)

- Add customizable display name for monitors
This commit is contained in:
JT 2019-05-17 05:42:16 +10:00 committed by Guillaume B
parent e955d84123
commit 4c09ef1c5e
8 changed files with 121 additions and 14 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View file

@ -153,7 +153,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.displays.append(display)
let monitorMenuItem = NSMenuItem()
monitorMenuItem.title = "\(name)"
monitorMenuItem.title = "\(display.getFriendlyName())"
if asSubMenu {
monitorMenuItem.submenu = monitorSubMenu
}
@ -177,6 +177,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// subscribe KeyTap event listener
NotificationCenter.default.addObserver(self, selector: #selector(handleListenForChanged), name: NSNotification.Name(Utils.PrefKeys.listenFor.rawValue), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleShowContrastChanged), name: NSNotification.Name(Utils.PrefKeys.showContrast.rawValue), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleFriendlyNameChanged), name: NSNotification.Name(Utils.PrefKeys.friendlyName.rawValue), object: nil)
// subscribe Audio output detector (AMCoreAudio)
AMCoreAudio.NotificationCenter.defaultCenter.subscribe(self, eventType: AudioHardwareEvent.self, dispatchQueue: DispatchQueue.main)
@ -226,6 +227,10 @@ extension AppDelegate: MediaKeyTapDelegate {
self.updateDisplays()
}
@objc func handleFriendlyNameChanged() {
self.updateDisplays()
}
private func startOrRestartMediaKeyTap() {
var keys: [MediaKey]

View file

@ -137,6 +137,14 @@ class Display {
return max == 0 ? 100 : max
}
func setFriendlyName(_ value: String) {
self.prefs.set(value, forKey: "friendlyName-\(self.identifier)")
}
func getFriendlyName() -> String {
return self.prefs.string(forKey: "friendlyName-\(self.identifier)") ?? self.name
}
private func showOsd(command: DDC.Command, value: Int) {
guard let manager = OSDManager.sharedManager() as? OSDManager else {
return

View file

@ -151,6 +151,9 @@ class Utils: NSObject {
/// Change Brightness/Volume for all screens
case allScreens
/// Friendly name changed
case friendlyName
}
/// Keys for the value of listenFor option

View file

@ -79,7 +79,7 @@
<objects>
<viewController storyboardIdentifier="DisplayPrefsVC" id="NAx-6T-ZPc" customClass="DisplayPrefsViewController" customModule="MonitorControl" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="EBf-qN-KaN">
<rect key="frame" x="0.0" y="0.0" width="486" height="223"/>
<rect key="frame" x="0.0" y="0.0" width="677" height="223"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uXD-ZY-N3H">
@ -91,13 +91,13 @@
</textFieldCell>
</textField>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B5k-we-kuP">
<rect key="frame" x="20" y="20" width="446" height="100"/>
<rect key="frame" x="20" y="20" width="637" height="100"/>
<clipView key="contentView" drawsBackground="NO" id="4ot-Jo-X5O">
<rect key="frame" x="1" y="0.0" width="444" height="99"/>
<rect key="frame" x="1" y="0.0" width="635" height="99"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowSizeStyle="automatic" headerView="ckY-Px-mJn" viewBased="YES" id="dyo-uY-pMe">
<rect key="frame" x="0.0" y="0.0" width="444" height="76"/>
<rect key="frame" x="0.0" y="0.0" width="635" height="76"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -167,6 +167,42 @@
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn width="140" minWidth="40" maxWidth="1000" id="uoI-1J-RdD">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Friendly Name">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" title="Text Cell" id="afl-95-ZJl">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="aGt-d9-Qcx" customClass="FriendlyNameCellView" customModule="MonitorControl" customModuleProvider="target">
<rect key="frame" x="196" y="1" width="140" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CB1-x8-d9G">
<rect key="frame" x="0.0" y="0.0" width="140" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" title="Table View Cell" id="DGv-iu-Jg1">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<connections>
<action selector="valueChanged:" target="aGt-d9-Qcx" id="Rkl-de-KE5"/>
</connections>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="CB1-x8-d9G" id="iTj-Jy-ijH"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn width="80" minWidth="10" maxWidth="3.4028234663852886e+38" id="dgp-q7-cBK">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="ID">
<font key="font" metaFont="smallSystem"/>
@ -181,7 +217,7 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="vw4-Us-VHk">
<rect key="frame" x="196" y="1" width="80" height="17"/>
<rect key="frame" x="339" y="1" width="80" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="z5b-Gr-EmC">
@ -214,7 +250,7 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="eVa-Md-Avh">
<rect key="frame" x="279" y="1" width="80" height="17"/>
<rect key="frame" x="422" y="1" width="80" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NK1-rO-I0Z">
@ -233,7 +269,7 @@
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn width="80" minWidth="10" maxWidth="3.4028234663852886e+38" id="Nvp-hI-w4x">
<tableColumn width="128" minWidth="10" maxWidth="3.4028234663852886e+38" id="Nvp-hI-w4x">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Model">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -247,11 +283,11 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="C4F-JT-GfP">
<rect key="frame" x="362" y="1" width="80" height="17"/>
<rect key="frame" x="505" y="1" width="128" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4Vl-7d-eft">
<rect key="frame" x="0.0" y="0.0" width="80" height="17"/>
<rect key="frame" x="0.0" y="0.0" width="128" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="4or-hS-WeW">
<font key="font" metaFont="system"/>
@ -284,7 +320,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="ckY-Px-mJn">
<rect key="frame" x="0.0" y="0.0" width="444" height="23"/>
<rect key="frame" x="0.0" y="0.0" width="635" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
@ -319,7 +355,7 @@
</viewController>
<customObject id="34q-0u-YTQ" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1159" y="223.5"/>
<point key="canvasLocation" x="1254.5" y="223.5"/>
</scene>
<!--Main Prefs View Controller-->
<scene sceneID="zAg-r8-WQ5">

View file

@ -0,0 +1,33 @@
import Cocoa
import os.log
class FriendlyNameCellView: NSTableCellView {
var display: Display?
let prefs = UserDefaults.standard
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
@IBAction func valueChanged(_ sender: NSTextFieldCell) {
if let display = display {
let newValue = sender.stringValue
let originalValue = display.getFriendlyName()
if newValue.isEmpty {
self.textField?.stringValue = originalValue
return
}
if newValue != originalValue,
!newValue.isEmpty {
display.setFriendlyName(newValue)
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.friendlyName.rawValue), object: nil)
#if DEBUG
os_log("Value changed for friendly name: %{public}@", type: .info, "from `\(originalValue)` to `\(newValue)`")
#endif
}
}
}
}

View file

@ -8,6 +8,9 @@
/* Class = "NSTableColumn"; headerCell.title = "Display Name"; ObjectID = "CHc-s5-4MN"; */
"CHc-s5-4MN.headerCell.title" = "Display Name";
/* Class = "NSTableColumn"; headerCell.title = "Friendly Name"; ObjectID = "uoI-1J-RdD"; */
"uoI-1J-RdD.headerCell.title" = "Friendly Name";
/* Class = "NSTextFieldCell"; title = "Keys"; ObjectID = "Dcz-GG-1li"; */
"Dcz-GG-1li.title" = "Keys";

View file

@ -13,6 +13,7 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
enum DisplayCell: String {
case checkbox
case name
case friendlyName
case identifier
case vendor
case model
@ -96,14 +97,18 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
text = display.name
cellType = DisplayCell.name
} else if tableColumn == tableView.tableColumns[2] {
// Friendly Name
text = display.getFriendlyName()
cellType = DisplayCell.friendlyName
} else if tableColumn == tableView.tableColumns[3] {
// Identifier
text = "\(display.identifier)"
cellType = DisplayCell.identifier
} else if tableColumn == tableView.tableColumns[3] {
} else if tableColumn == tableView.tableColumns[4] {
// Vendor
text = display.identifier.vendorNumber.map { String(format: "0x%02X", $0) } ?? NSLocalizedString("unknown", comment: "unknown vendor")
cellType = DisplayCell.vendor
} else if tableColumn == tableView.tableColumns[4] {
} else if tableColumn == tableView.tableColumns[5] {
// Model
text = display.identifier.modelNumber.map { String(format: "0x%02X", $0) } ?? NSLocalizedString("unknown", comment: "unknown model")
cellType = DisplayCell.model
@ -117,6 +122,13 @@ class DisplayPrefsViewController: NSViewController, MASPreferencesViewController
}
return cell
}
} else if cellType == DisplayCell.friendlyName {
if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: nil) as? FriendlyNameCellView {
cell.display = display
cell.textField?.stringValue = text
cell.textField?.isEditable = true
return cell
}
} else {
if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: nil) as? NSTableCellView {
cell.textField?.stringValue = text