feat: add back the preferences for the new layout algo
This commit is contained in:
1 parent
89977d78ee
commit
d52eb6d074
6 files changed
+72
-47
No files matched your search
@@ -40,8 +40,8 @@ func keyboardHandler(proxy: CGEventTapProxy, type: CGEventType, event_: CGEvent,
|
||||
if type == .keyDown || type == .keyUp || type == .flagsChanged {
|
||||
if let event = NSEvent(cgEvent: event_) {
|
||||
let isTab = event.keyCode == Preferences.tabKeyCode
|
||||
let isMetaChanged = Preferences.metaKeyCodes!.contains(event.keyCode)
|
||||
let isMetaDown = event.modifierFlags.contains(Preferences.metaModifierFlag!)
|
||||
let isMetaChanged = Preferences.metaKeyCodes.contains(event.keyCode)
|
||||
let isMetaDown = event.modifierFlags.contains(Preferences.metaModifierFlag)
|
||||
let isRightArrow = event.keyCode == kVK_RightArrow
|
||||
let isLeftArrow = event.keyCode == kVK_LeftArrow
|
||||
let isEscape = event.keyCode == kVK_Escape
|
||||
|
||||
@@ -5,18 +5,11 @@ import Carbon.HIToolbox.Events
|
||||
class Preferences {
|
||||
// the following constant are not exposed as preferences but may be in the future, probably through macro preferences
|
||||
static let windowMaterial = NSVisualEffectView.Material.dark
|
||||
static let iconSize = CGFloat(32)
|
||||
static let fontColor = NSColor.white
|
||||
static let fontHeight = CGFloat(15)
|
||||
static let font = NSFont.systemFont(ofSize: fontHeight)
|
||||
static let windowPadding = CGFloat(23)
|
||||
static let interCellPadding = CGFloat(5)
|
||||
static let intraCellPadding = CGFloat(5)
|
||||
static let fontIconSize = CGFloat(20)
|
||||
static let maxScreenUsage = CGFloat(0.8)
|
||||
static let minCellsPerRow = CGFloat(5)
|
||||
static let maxCellsPerRow = minCellsPerRow * 2
|
||||
static let nCellsRows = CGFloat(3)
|
||||
|
||||
static let themeMacro = MacroPreferenceHelper<(CGFloat, CGFloat, CGFloat, NSColor, NSColor)>([
|
||||
MacroPreference(" macOS", (0, 5, 20, .clear, NSColor(red: 0, green: 0, blue: 0, alpha: 0.4))),
|
||||
@@ -33,6 +26,12 @@ class Preferences {
|
||||
])
|
||||
|
||||
static var defaults: [String: String] = [
|
||||
"maxScreenUsage": "80",
|
||||
"minCellsPerRow": "5",
|
||||
"maxCellsPerRow": "10",
|
||||
"minRows": "3",
|
||||
"iconSize": "32",
|
||||
"fontHeight": "15",
|
||||
"tabKeyCode": String(kVK_Tab),
|
||||
"metaKey": metaKeyMacro.macros[0].label,
|
||||
"windowDisplayDelay": "0",
|
||||
@@ -42,17 +41,24 @@ class Preferences {
|
||||
]
|
||||
static var rawValues = [String: String]()
|
||||
|
||||
static var cellBorderWidth: CGFloat?
|
||||
static var cellCornerRadius: CGFloat?
|
||||
static var tabKeyCode: UInt16?
|
||||
static var highlightBorderColor: NSColor?
|
||||
static var highlightBackgroundColor: NSColor?
|
||||
static var metaKeyCodes: [UInt16]?
|
||||
static var metaModifierFlag: NSEvent.ModifierFlags?
|
||||
static var windowDisplayDelay: DispatchTimeInterval?
|
||||
static var windowCornerRadius: CGFloat?
|
||||
static var showOnScreen: ShowOnScreenPreference?
|
||||
static var hideSpaceNumberLabels: Bool?
|
||||
static var cellBorderWidth: CGFloat!
|
||||
static var cellCornerRadius: CGFloat!
|
||||
static var tabKeyCode: UInt16!
|
||||
static var highlightBorderColor: NSColor!
|
||||
static var highlightBackgroundColor: NSColor!
|
||||
static var metaKeyCodes: [UInt16]!
|
||||
static var metaModifierFlag: NSEvent.ModifierFlags!
|
||||
static var windowDisplayDelay: DispatchTimeInterval!
|
||||
static var windowCornerRadius: CGFloat!
|
||||
static var showOnScreen: ShowOnScreenPreference!
|
||||
static var hideSpaceNumberLabels: Bool!
|
||||
static var maxScreenUsage: CGFloat!
|
||||
static var iconSize: CGFloat!
|
||||
static var fontHeight: CGFloat!
|
||||
static var font: NSFont!
|
||||
static var minCellsPerRow: CGFloat!
|
||||
static var maxCellsPerRow: CGFloat!
|
||||
static var minRows: CGFloat!
|
||||
|
||||
private static let defaultsFile = fileFromPreferencesFolder("alt-tab-macos-defaults.json")
|
||||
private static let userFile = fileFromPreferencesFolder("alt-tab-macos.json")
|
||||
@@ -84,6 +90,19 @@ class Preferences {
|
||||
|
||||
static func updateAndValidateFromString(_ valueName: String, _ value: String) throws {
|
||||
switch valueName {
|
||||
case "maxScreenUsage":
|
||||
maxScreenUsage = try CGFloat(CGFloat(value).orThrow() / 100)
|
||||
case "minCellsPerRow":
|
||||
minCellsPerRow = try CGFloat(value).orThrow()
|
||||
case "maxCellsPerRow":
|
||||
maxCellsPerRow = try CGFloat(value).orThrow()
|
||||
case "minRows":
|
||||
minRows = try CGFloat(value).orThrow()
|
||||
case "iconSize":
|
||||
iconSize = try CGFloat(value).orThrow()
|
||||
case "fontHeight":
|
||||
fontHeight = try CGFloat(value).orThrow()
|
||||
font = NSFont.systemFont(ofSize: fontHeight)
|
||||
case "tabKeyCode":
|
||||
tabKeyCode = try UInt16(value).orThrow()
|
||||
case "metaKey":
|
||||
|
||||
@@ -92,7 +92,7 @@ class App: NSApplication, NSApplicationDelegate, NSWindowDelegate {
|
||||
Windows.refreshAllThumbnails()
|
||||
Windows.focusedWindowIndex = 0
|
||||
Windows.cycleFocusedWindowIndex(step)
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Preferences.windowDisplayDelay!, execute: {
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Preferences.windowDisplayDelay, execute: {
|
||||
self.refreshOpenUi()
|
||||
if self.uiWorkShouldBeDone { self.thumbnailsPanel?.show() }
|
||||
})
|
||||
|
||||
@@ -34,8 +34,8 @@ class Cell: NSCollectionViewItem {
|
||||
|
||||
override var isSelected: Bool {
|
||||
didSet {
|
||||
view.layer!.backgroundColor = isSelected ? Preferences.highlightBackgroundColor!.cgColor : .clear
|
||||
view.layer!.borderColor = isSelected ? Preferences.highlightBorderColor!.cgColor : .clear
|
||||
view.layer!.backgroundColor = isSelected ? Preferences.highlightBackgroundColor.cgColor : .clear
|
||||
view.layer!.borderColor = isSelected ? Preferences.highlightBorderColor.cgColor : .clear
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class Cell: NSCollectionViewItem {
|
||||
label.font = Preferences.font
|
||||
hiddenIcon.isHidden = !window!.isHidden
|
||||
minimizedIcon.isHidden = !window!.isMinimized
|
||||
spaceIcon.isHidden = element.spaceIndex == nil || Spaces.isSingleSpace || Preferences.hideSpaceNumberLabels!
|
||||
spaceIcon.isHidden = element.spaceIndex == nil || Spaces.isSingleSpace || Preferences.hideSpaceNumberLabels
|
||||
if !spaceIcon.isHidden {
|
||||
if element.isOnAllSpaces {
|
||||
spaceIcon.setStar()
|
||||
@@ -93,8 +93,8 @@ class Cell: NSCollectionViewItem {
|
||||
let vStackView = NSStackView()
|
||||
vStackView.wantsLayer = true
|
||||
vStackView.layer!.backgroundColor = .clear
|
||||
vStackView.layer!.cornerRadius = Preferences.cellCornerRadius!
|
||||
vStackView.layer!.borderWidth = Preferences.cellBorderWidth!
|
||||
vStackView.layer!.cornerRadius = Preferences.cellCornerRadius
|
||||
vStackView.layer!.borderWidth = Preferences.cellBorderWidth
|
||||
vStackView.layer!.borderColor = .clear
|
||||
vStackView.edgeInsets = NSEdgeInsets(top: Preferences.intraCellPadding, left: Preferences.intraCellPadding, bottom: Preferences.intraCellPadding, right: Preferences.intraCellPadding)
|
||||
vStackView.orientation = .vertical
|
||||
@@ -104,7 +104,7 @@ class Cell: NSCollectionViewItem {
|
||||
}
|
||||
|
||||
static func downscaleFactor() -> CGFloat {
|
||||
let nCellsBeforePotentialOverflow = Preferences.nCellsRows * Preferences.minCellsPerRow
|
||||
let nCellsBeforePotentialOverflow = Preferences.minRows * Preferences.minCellsPerRow
|
||||
guard CGFloat(Windows.list.count) > nCellsBeforePotentialOverflow else { return 1 }
|
||||
// TODO: replace this buggy heuristic with a correct implementation of downscaling
|
||||
return nCellsBeforePotentialOverflow / (nCellsBeforePotentialOverflow + (sqrt(CGFloat(Windows.list.count) - nCellsBeforePotentialOverflow) * 2))
|
||||
@@ -119,7 +119,7 @@ class Cell: NSCollectionViewItem {
|
||||
}
|
||||
|
||||
static func height(_ screen: NSScreen) -> CGFloat {
|
||||
return (ThumbnailsPanel.heightMax(screen) / Preferences.nCellsRows - Preferences.interCellPadding) * Cell.downscaleFactor()
|
||||
return (ThumbnailsPanel.heightMax(screen) / Preferences.minRows - Preferences.interCellPadding) * Cell.downscaleFactor()
|
||||
}
|
||||
|
||||
static func width(_ image: NSImage?, _ screen: NSScreen) -> CGFloat {
|
||||
|
||||
@@ -78,14 +78,20 @@ class PreferencesWindow: NSWindow, NSWindowDelegate {
|
||||
}
|
||||
|
||||
return [
|
||||
makeLabelWithDropdown("Alt key", rawName: "metaKey", values: Preferences.metaKeyMacro.labels),
|
||||
makeLabelWithInput("Tab key", rawName: "tabKeyCode", width: 33, suffixText: "KeyCodes Reference", suffixUrl: "https://eastmanreference.com/complete-list-of-applescript-key-codes", validator: tabKeyCodeValidator),
|
||||
makeLabelWithDropdown("Alt key", "metaKey", Preferences.metaKeyMacro.labels),
|
||||
makeLabelWithInput("Tab key", "tabKeyCode", 33, "KeyCodes Reference", "https://eastmanreference.com/complete-list-of-applescript-key-codes", tabKeyCodeValidator),
|
||||
makeHorizontalSeparator(),
|
||||
makeLabelWithDropdown("Theme", rawName: "theme", values: Preferences.themeMacro.labels),
|
||||
makeLabelWithCheckbox("Hide space number labels", rawName: "hideSpaceNumberLabels"),
|
||||
makeLabelWithDropdown("Theme", "theme", Preferences.themeMacro.labels),
|
||||
makeLabelWithSlider("Max size on screen", "maxScreenUsage", 10, 100, 10, true, "%"),
|
||||
makeLabelWithSlider("Min windows per row", "minCellsPerRow", 1, 20, 20, true),
|
||||
makeLabelWithSlider("Max windows per row", "maxCellsPerRow", 1, 40, 20, true),
|
||||
makeLabelWithSlider("Min rows of windows", "minRows", 1, 20, 20, true),
|
||||
makeLabelWithSlider("Window app icon size", "iconSize", 0, 64, 11, false, "px"),
|
||||
makeLabelWithSlider("Window title font size", "fontHeight", 0, 64, 11, false, "px"),
|
||||
makeLabelWithCheckbox("Hide space number labels", "hideSpaceNumberLabels"),
|
||||
makeHorizontalSeparator(),
|
||||
makeLabelWithSlider("Window apparition delay", rawName: "windowDisplayDelay", minValue: 0, maxValue: 2000, numberOfTickMarks: 0, unitText: "ms"),
|
||||
makeLabelWithDropdown("Show on", rawName: "showOnScreen", values: Preferences.showOnScreenMacro.labels)
|
||||
makeLabelWithSlider("Apparition delay", "windowDisplayDelay", 0, 2000, 11, false, "ms"),
|
||||
makeLabelWithDropdown("Show on", "showOnScreen", Preferences.showOnScreenMacro.labels)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -96,7 +102,7 @@ class PreferencesWindow: NSWindow, NSWindowDelegate {
|
||||
return view
|
||||
}
|
||||
|
||||
private func makeLabelWithInput(_ labelText: String, rawName: String, width: CGFloat? = nil, suffixText: String? = nil, suffixUrl: String? = nil, validator: ((String) -> Bool)? = nil) -> NSStackView {
|
||||
private func makeLabelWithInput(_ labelText: String, _ rawName: String, _ width: CGFloat? = nil, _ suffixText: String? = nil, _ suffixUrl: String? = nil, _ validator: ((String) -> Bool)? = nil) -> NSStackView {
|
||||
let input = TextField(Preferences.rawValues[rawName]!)
|
||||
input.validationHandler = validator
|
||||
input.delegate = input
|
||||
@@ -105,24 +111,24 @@ class PreferencesWindow: NSWindow, NSWindowDelegate {
|
||||
input.widthAnchor.constraint(equalToConstant: width!).isActive = true
|
||||
}
|
||||
|
||||
return makeLabelWithProvidedControl(labelText, rawName: rawName, control: input, suffixText: suffixText, suffixUrl: suffixUrl)
|
||||
return makeLabelWithProvidedControl(labelText, rawName, input, suffixText, nil, suffixUrl)
|
||||
}
|
||||
|
||||
private func makeLabelWithCheckbox(_ labelText: String, rawName: String) -> NSStackView {
|
||||
private func makeLabelWithCheckbox(_ labelText: String, _ rawName: String) -> NSStackView {
|
||||
let checkbox = NSButton.init(checkboxWithTitle: "", target: nil, action: nil)
|
||||
setControlValue(checkbox, Preferences.rawValues[rawName]!)
|
||||
return makeLabelWithProvidedControl(labelText, rawName: rawName, control: checkbox)
|
||||
return makeLabelWithProvidedControl(labelText, rawName, checkbox)
|
||||
}
|
||||
|
||||
private func makeLabelWithDropdown(_ labelText: String, rawName: String, values: [String], suffixText: String? = nil) -> NSStackView {
|
||||
private func makeLabelWithDropdown(_ labelText: String, _ rawName: String, _ values: [String], _ suffixText: String? = nil) -> NSStackView {
|
||||
let popUp = NSPopUpButton()
|
||||
popUp.addItems(withTitles: values)
|
||||
popUp.selectItem(withTitle: Preferences.rawValues[rawName]!)
|
||||
|
||||
return makeLabelWithProvidedControl(labelText, rawName: rawName, control: popUp, suffixText: suffixText)
|
||||
return makeLabelWithProvidedControl(labelText, rawName, popUp, suffixText)
|
||||
}
|
||||
|
||||
private func makeLabelWithSlider(_ labelText: String, rawName: String, minValue: Double, maxValue: Double, numberOfTickMarks: Int, unitText: String = "") -> NSStackView {
|
||||
private func makeLabelWithSlider(_ labelText: String, _ rawName: String, _ minValue: Double, _ maxValue: Double, _ numberOfTickMarks: Int, _ allowsTickMarkValuesOnly: Bool, _ unitText: String = "") -> NSStackView {
|
||||
let value = Preferences.rawValues[rawName]!
|
||||
let suffixText = value + unitText
|
||||
let slider = NSSlider()
|
||||
@@ -130,14 +136,14 @@ class PreferencesWindow: NSWindow, NSWindowDelegate {
|
||||
slider.maxValue = maxValue
|
||||
slider.stringValue = value
|
||||
slider.numberOfTickMarks = numberOfTickMarks
|
||||
slider.allowsTickMarkValuesOnly = numberOfTickMarks > 1
|
||||
slider.allowsTickMarkValuesOnly = allowsTickMarkValuesOnly
|
||||
slider.tickMarkPosition = .below
|
||||
slider.isContinuous = true
|
||||
|
||||
return makeLabelWithProvidedControl(labelText, rawName: rawName, control: slider, suffixText: suffixText, suffixWidth: 60)
|
||||
return makeLabelWithProvidedControl(labelText, rawName, slider, suffixText, 60)
|
||||
}
|
||||
|
||||
private func makeLabelWithProvidedControl(_ labelText: String?, rawName: String, control: NSControl, suffixText: String? = nil, suffixWidth: CGFloat? = nil, suffixUrl: String? = nil) -> NSStackView {
|
||||
private func makeLabelWithProvidedControl(_ labelText: String?, _ rawName: String, _ control: NSControl, _ suffixText: String? = nil, _ suffixWidth: CGFloat? = nil, _ suffixUrl: String? = nil) -> NSStackView {
|
||||
let label = NSTextField(wrappingLabelWithString: (labelText != nil ? labelText! + ": " : ""))
|
||||
label.alignment = .right
|
||||
label.widthAnchor.constraint(equalToConstant: labelWidth).isActive = true
|
||||
@@ -150,14 +156,14 @@ class PreferencesWindow: NSWindow, NSWindowDelegate {
|
||||
let containerView = NSStackView(views: [label, control])
|
||||
|
||||
if suffixText != nil {
|
||||
let suffix = makeSuffix(controlName: rawName, text: suffixText!, width: suffixWidth, url: suffixUrl)
|
||||
let suffix = makeSuffix(rawName, suffixText!, suffixWidth, suffixUrl)
|
||||
containerView.addView(suffix, in: .leading)
|
||||
}
|
||||
|
||||
return containerView
|
||||
}
|
||||
|
||||
private func makeSuffix(controlName: String, text: String, width: CGFloat? = nil, url: String? = nil) -> NSTextField {
|
||||
private func makeSuffix(_ controlName: String, _ text: String, _ width: CGFloat? = nil, _ url: String? = nil) -> NSTextField {
|
||||
let suffix: NSTextField
|
||||
if url == nil {
|
||||
suffix = NSTextField(labelWithString: text)
|
||||
|
||||
@@ -41,7 +41,7 @@ class ThumbnailsPanel: NSPanel, NSCollectionViewDataSource, NSCollectionViewDele
|
||||
backgroundView.material = Preferences.windowMaterial
|
||||
backgroundView.state = .active
|
||||
backgroundView.wantsLayer = true
|
||||
backgroundView.layer!.cornerRadius = Preferences.windowCornerRadius!
|
||||
backgroundView.layer!.cornerRadius = Preferences.windowCornerRadius
|
||||
return backgroundView
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user