Today it’s been 15 months of slow development. I’ve been busy with other things, mostly life and family, so I couldn’t get much work done. Mojave was released last month and so I upgraded my Mac. I had tested previously beta 3 but found most applications to consume greater amounts of memory than with High Sierra. The situation hasn’t changed with final release, and I suspect it’s either an incompatibility with some installed software or Activity Monitor is reporting memory usage differently than previous macOS versions. I’m currently running 10.14.1 beta and nothing’s changed so far.

I’m trying to keep up with development though. As soon as Mojave was released, I recompiled “The Application” with the latest SDK and found out some views’ appearances were really odd. The problem was there were some NSVisualEffectView overriding common behavior and some labels and boxes looked out of place. I removed those NSVisualEffectView as they weren’t necessary anyway, and all was good. As Mojave adopted semantic colors, I also had to adapt some custom views’ colors. The following screenshot shows how the app looks now in the new dark mode, which I love by the way.

Screen Shot 2018 10 05 at 18 00

One thing to notice is the integrated progress bar in the status bar. Very similar to Xcode or Safari’s one. Unlike them, I couldn’t get the progress bar color to look the same. In High Sierra I used NSColor.systemBlue to give it a bright blue. In Mojave, for some reason it looks way dimmed:

Status bar screenshot

I had to switch depending on macOS version to use systemBlue or the control accent color (available in Mojave). This is the code that draws the progress bar:

import Cocoa

 

@IBDesignable

open class StatusBar: NSTextField {

    // MARK: – Properties

    

    @IBInspectable public dynamic var progress: Double = 0.0 {

        didSet {

            // Autoreset to minValue if autoreset is enabled

            if progress >= maxValue && progressAutoResets {

                progress = minValue

            } else if progress < minValue {

                progress = minValue

            } else if progress > maxValue {

                progress = maxValue

            }

 

            needsDisplay = true

        }

    }

    

    @IBInspectable public var minValue: Double = 0.0 {

        didSet {

            if minValue > progress {

                progress = minValue

            }

            needsDisplay = true

        }

    }

 

    @IBInspectable public var maxValue: Double = 100.0 {

        didSet {

            if maxValue < progress {

                progress = maxValue

            }

            needsDisplay = true

        }

    }

    

    @IBInspectable public var progressAutoResets: Bool = true

    

    @IBInspectable public var progressColor: NSColor = _progressColor() {

        didSet {

            needsDisplay = true

        }

    }

 

    override open var isFlipped: Bool {

        return false

    }

 

    // MARK: – Function Overrides

 

    public override init(frame frameRect: NSRect) {

        super.init(frame: frameRect)

        

        configure()

    }

    

    public required init?(coder: NSCoder) {

        super.init(coder: coder)

 

        configure()

    }

 

    override open func draw(_ dirtyRect: NSRect) {

        super.draw(dirtyRect)

        

        // Drawing code here.

        drawProgressBar()

    }

    

    override open func animation(forKey key: NSAnimatablePropertyKey) -> Any? {

        switch key {

        case #keyPath(progress):

            return CABasicAnimation(keyPath: #keyPath(progress))

        default:

            return super.animation(forKey: key)

        }

    }

 

    // MARK: – Public API

    

    open func increment(by delta: Double) {

        animator().progress += delta

    }

    

    open func animateProgress(total: Double) {

        animator().progress = total

    }

 

    // MARK: – Private Functions

    

    private func drawProgressBar() {

        guard progress > minValue else { return }

        

        let barWidth = progress * Double(bounds.width) / maxValue

        let progressRect = NSMakeRect(0, 0, CGFloat(barWidth), 4)

        progressColor.set()

        progressRect.fill(using: .sourceIn)

    }

    

    private func configure() {

        isEditable = false

        isSelectable = false

        focusRingType = .none

        wantsLayer = true

    }

    

    private static func _progressColor() -> NSColor {

        if #available(OSX 10.14, *) {

            return NSColor.controlAccentColor

        } else {

            return NSColor.systemBlue

        }

    }

}

 

I suspect there’s some alpha value messing with blending, so now there’s one more thing to fix before I reach version 1.0.

Update: switching to an NSButton instead of NSTextField solves the problem.

Progress Update #3
Tagged on:         
Do NOT follow this link or you will be banned from the site!