Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up display configuration and break up configuration code to be less monolithic #2520

Closed
waydabber opened this issue Jan 11, 2024 · 2 comments
Assignees
Labels
done All tasks are completed enhancement New feature or request released Released
Milestone

Comments

@waydabber
Copy link
Owner

Reconfiguration could be improved to be a bit more granular and quicker in response to display configuration changes. Now on every change all displays are rechecked. It's a fast process but might be even faster.

@waydabber waydabber added the enhancement New feature or request label Jan 11, 2024
@waydabber waydabber self-assigned this Jan 11, 2024
@waydabber
Copy link
Owner Author

Some code ideas provided by @Wouter01

import CoreGraphics

public enum Display {
    public static var configurationChanges: AsyncStream<(UInt32, CGDisplayChangeSummaryFlags)> {
        let (stream, continuation) = AsyncStream.makeStream(of: (UInt32, CGDisplayChangeSummaryFlags).self)
        
        let callback: CGDisplayReconfigurationCallBack = { displayID, changeFlags, pointer in
            let this = unsafeBitCast(pointer, to: AsyncStream<(UInt32, CGDisplayChangeSummaryFlags)>.Continuation.self)
            this.yield((displayID, changeFlags))
        }
        
        let context = unsafeBitCast(continuation, to: UnsafeMutableRawPointer.self)
        CGDisplayRegisterReconfigurationCallback(callback, context)
        
        continuation.onTermination = { _ in
            CGDisplayRemoveReconfigurationCallback(callback, context)
        }
        
        return stream
    }
}
extension CGDisplayChangeSummaryFlags: CaseIterable {
    public static var allCases: [CGDisplayChangeSummaryFlags] {
        [.addFlag, .beginConfigurationFlag, .desktopShapeChangedFlag, .disabledFlag, .enabledFlag, .mirrorFlag, .movedFlag, .removeFlag, .setMainFlag, .setModeFlag, .unMirrorFlag]
    }
}
extension CGDisplayChangeSummaryFlags: CustomStringConvertible {
    
    private func singleValueDescription(flag: Self) -> String {
        switch flag {
        case .addFlag: "Add"
        case .beginConfigurationFlag: "Begin Configuration"
        case .desktopShapeChangedFlag: "Desktop Shape Changed"
        case .disabledFlag: "Disabled"
        case .enabledFlag: "Enabled"
        case .mirrorFlag: "Mirror"
        case .movedFlag: "Moved"
        case .removeFlag: "Remove"
        case .setMainFlag: "Set Main"
        case .setModeFlag: "Set Mode"
        case .unMirrorFlag: "Unmirror"
        default: "Unknown"
        }
    }
    
    public var description: String {
        CGDisplayChangeSummaryFlags.allCases
            .filter { contains($0) }
            .map { singleValueDescription(flag: $0) }
            .joined(separator: ", ")
    }
}

@waydabber waydabber added in progress Implementing unreleased Not released yet in beta form labels Apr 22, 2024
@waydabber waydabber added this to the v2.3.2 milestone Apr 22, 2024
@waydabber
Copy link
Owner Author

waydabber commented Apr 22, 2024

The issue seems to be that macOS sends all kinds of flags that most of the time require almost everything to be updated anyway... Like desktopShapeChanged is almost always sent to all displays indiscriminately when one display mode changes or is rotated, while nothing is sent on changing mode to HDR etc.

@waydabber waydabber changed the title Make display reconfiguration a bit more granular to speed up processing configuration changes in the app Speed up display configuration and break up configuration code to be less monolithic Apr 22, 2024
@waydabber waydabber added done All tasks are completed and removed in progress Implementing labels Apr 23, 2024
@waydabber waydabber added released Released and removed unreleased Not released yet in beta form labels May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
done All tasks are completed enhancement New feature or request released Released
Projects
None yet
Development

No branches or pull requests

1 participant