10

I'm writing a macOS app in which I'd like to do something with the value of the screen brightness as soon as it changes.

I can determine what the screen brightness is by iterating over IOServices with IOServiceGetMatchingServices() then using IODisplayGetFloatParameter() to obtain the kIODisplayBrightnessKey parameter of the IODisplayConnect services I found, as explained in this answer, but I don't know how to find out when the brightness has changed.

Is there a way for my app to get notified as soon as the screen brightness has changed?

I could poll, and I know how to do that, but that's not what I'm looking for. I'm looking for something like UIScreen.brightnessDidChangeNotification, but for macOS.

rid
  • 61,078
  • 31
  • 152
  • 193
  • Perhaps some nuggets in here https://alexdelorenzo.dev/programming/2018/08/16/reverse_engineering_private_apple_apis.html. – Adrian Jun 11 '21 at 01:39
  • @Adrian, unfortunately, that doesn't help much, because it only talks about obtaining a value, not listening for changes, and it's the listening that I can't figure out how to do. – rid Jun 11 '21 at 10:35
  • 1
    Here's a way that you can experiment with (not App Store safe) https://github.com/fnesveda/ExternalDisplayBrightness/blob/master/src/ExternalDisplayBrightness/BrightnessManager.swift – Tarun Tyagi Jun 13 '21 at 10:31
  • For private frameworks, try digging through CoreBrightness. – paiv Jun 16 '21 at 15:45
  • So there's no supported way at all? I thought there might be something related to `IOService`, but I didn't find anything. Then I thought I might listen for key presses, which seems to be supported and the user is asked for permission, but I can't seem to listen for the brightness keys. I'm out of ideas, and I'd rather not use private frameworks or other unsupported techniques. It's so easy on iOS, I thought there must be something equivalent on macOS and I just can't find it, but I'm starting to think I might have been wrong about that. – rid Jun 16 '21 at 17:04
  • @rid you can try your iOS code on Mac Catalyst... – paiv Jun 16 '21 at 17:46
  • Looks like [MonitorControl](https://github.com/MonitorControl/MonitorControl) is able to listen to brightness key presses, if I understand their Readme properly. Maybe you can find something in their code? It's on GitHub. // Edit: they seem to be using [MediaKeyTap](https://github.com/MonitorControl/MediaKeyTap) for listening, also on GitHub. – Eric Aya Jun 19 '21 at 17:16
  • I made an app to register for a notification using IOKit, and apparently the callback is not called at all. It seems as though the Mac IOKit display code does not implement any notification when a property is set. You can actually see this in the latest IODisplay.cpp file implementation at https://opensource.apple.com/source/IOGraphics/IOGraphics-16/IOGraphicsFamily/IODisplay.cpp.auto.html – jvarela Jun 20 '21 at 01:11
  • @jvarela, interesting, thanks for the insight. Looks like this question does not have any good answer then. Let's hope Apple makes some changes in the upcoming versions of macOS. In the mean time, I'll look into media key events to see if there's anything supported that I can use. – rid Jun 20 '21 at 20:15
  • @rid Please file an enhancement request. I also tried the NSApplicationDelegate applicationDidChangeScreenParameters but it is not called either. I tried to reverse engineer the DIsplay panel of System Preferences, but all notifications they use to update the slider and the brightness of the screen are made statically without the use of any libraries. They do use CoreDisplay routines but only to set the values of brightness. Therefore, no luck whatsoever for what you want to do. :) – jvarela Jun 21 '21 at 11:59
  • @jvarela, I wonder how they make the OSD (the sun icon with the squares underneath) appear when the brightness changes. I think I saw a private framework with OSD in its name, so I think it's likely that this is done with events and notifications, just not anything we have access to. – rid Jun 21 '21 at 12:43
  • @rid I also tried to intercept any NSDistributedNotificationCenter and NSWorkSpace notifications, but there are none, because on Big Sur you can see that when you change the brightness settings in the slider on the Displays System Pref panel, that is also reflected in the Menu Bar System Preferences immediately, and vice-versa. Alas, they do not use any notifications for that. :( Perhaps, they use an XPC service for that and that we cannot listen to. – jvarela Jun 21 '21 at 13:46
  • 1
    My suspicions were right. For the OSD they use an NSXPCConnection that most probably only allows connections with properly signed Apple software, if done right. – jvarela Jun 21 '21 at 14:28
  • @jvarela, ah, well, if they use XPC for this instead of notifications, then we're completely out of luck. Thank you for investigating this! – rid Jun 21 '21 at 20:27

0 Answers0