Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

Keyboard brightness API removed by Apple on Macs after 2016 馃槶 (If you know of any new one, plz help馃檹) #1

Open
DylanVolz opened this issue Jul 14, 2017 · 30 comments
Labels

Comments

@DylanVolz
Copy link

macOS sierra version: 10.12.5 (16F73)
mbp 15-in, 2016

Display controls work fine but keyboard read and write operations fail:

$ ./dbrightness
0.650391
$ ./dbrightness .8
$ ./kbrightness
getLightSensors() error: failed to find ambient light sensor
getKeyboardBrightness() error
0.000000
$ ./kbrightness 1.0
getLightSensors() error: failed to find ambient light sensor
setKeyboardBrightness() error

I will update with more info when I have some time to debug this evening (and will pr if I find the issue).

@pirate
Copy link
Owner

pirate commented Jul 14, 2017

Thanks, you're not the only one to report this, but I haven't been able to fix it since it's not reproducible on my 2013 MacBook Pro.

@DylanVolz
Copy link
Author

Ok, well I will see if I can get anywhere with it this weekend.

@pirate
Copy link
Owner

pirate commented Jul 14, 2017

Actually I think I fixed it 1d1daf1, pull master and give it a shot when you get a chance.

The binaries were just out of date from the c code (where I had removed getLightSensors), so I just recompiled them and pushed.

@DylanVolz
Copy link
Author

Still having an issue, but got a new error message:
$ ./kbrightness 1.0
Failed to connect to AppleLMUController
setKeyboardBrightness() error
$ ./kbrightness
Failed to connect to AppleLMUController
getKeyboardBrightness() error

@pirate
Copy link
Owner

pirate commented Jul 14, 2017

Hmm the IOKit methods I'm using are all deprecated, it's possible Apple removed support for them when it added upgraded hardware in the 2015+ MBP models.

I can try copying over this newer swift code instead for krightness: https://github.com/bhoeting/DiscoKeyboard/blob/b50d1722007aadba1059e5324cc0a572419dfd54/DiscoKeyboard/Backlight.swift

@pirate pirate added the bug label Jul 14, 2017
@Alex293
Copy link

Alex293 commented Aug 16, 2017

Same is happening with DiscoKeyboard any leads on how to read KeyboardBrightness ?

I have a work around to set it by sending keystrokes but I can't read the value. I'll post it here soon.

@pirate
Copy link
Owner

pirate commented Aug 16, 2017

Does ./dbrightness from the latest commit work? If so I think I have a fix for you @Alex293.

@Alex293
Copy link

Alex293 commented Aug 16, 2017

Yes it does work,

./kbrightness give
Failed to connect to AppleLMUController
getKeyboardBrightness() error

Edit : Also it would be awesome to be able to set the value as for now the only thing I managed to get working is to send the keystrokes that increase the value by steps.

@tymscar
Copy link

tymscar commented Aug 26, 2017

Hello!
For me dbrightness works beautifully.
However kbrightness always returns 0.000000%

Now if I run blink, it gives me this error: setKeyboardBrightness() error

I am on a 2017 MacBook pro nTB

@Alex293
Copy link

Alex293 commented Aug 26, 2017

They changed the driver for the keyboard I'll post here soon how to read the value. But they didn't implemented the set function so we can't set the value without simulating the keyboard keys.

@tymscar
Copy link

tymscar commented Aug 26, 2017

Got it!

Can we somehow implement the "simulating keyboard keys" part? I would love to have the keyboard flash when I get a notification for example :)

@pirate
Copy link
Owner

pirate commented Aug 26, 2017

I haven't figured out how to do it by simulating key presses yet, but if you find a way, do post back!

This article says there isn't an easy way to do it via AppleScript, and I don't know Swift/ObjC well enough to do it there.

fn + F6 on my keyboard is keyboard brightness up, does it vary between macs?

@Alex293
Copy link

Alex293 commented Aug 28, 2017

import IOKit

static func readKeyboardBrigthness() -> Float?
    {
        let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleHIDKeyboardEventDriverV2"))
        defer
        {
            IOObjectRelease(service)
        }
        let ser: CFTypeRef = IORegistryEntryCreateCFProperty(service, "KeyboardBacklightBrightness" as CFString, kCFAllocatorDefault,0).takeUnretainedValue()
        if let result = ser as? Float {
            return result
        }


        return nil
    }

@Alex293
Copy link

Alex293 commented Aug 28, 2017

// Simulate illumination up
let code = NX_KEYTYPE_ILLUMINATION_UP
let event1 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xa00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xa << 8 as Int32))), data2: -1)
event1?.cgEvent?.post(tap: .cghidEventTap)
let event2 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xb00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xb << 8 as Int32))), data2: -1)
event2?.cgEvent?.post(tap: .cghidEventTap)



// Simulate illumination down
let code = NX_KEYTYPE_ILLUMINATION_DOWN
let event1 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xa00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xa << 8 as Int32))), data2: -1)
event1?.cgEvent?.post(tap: .cghidEventTap)
let event2 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xb00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xb << 8 as Int32))), data2: -1)
event2?.cgEvent?.post(tap: .cghidEventTap)

My previous comment give you the value. Good thing to note is that this is kinda slow. I tried to implement a slider and its too slow for nice results. If you can make something from this please keep me updated.

@tymscar here it is !

@Alex293
Copy link

Alex293 commented Aug 28, 2017

@pirate the is no way to simulate key press for keyboard illumination but you can simulate nsevent sent when those keys are pressed.

@Alex293
Copy link

Alex293 commented Aug 28, 2017

Also now that I'm thinking about this, you may actually be able to listen to quicks change by listening to those events (in my second comment). Like first you read the value with the driver to get the initial value then you only listen to the events. I don't have time to experiment those days this but I will when I can.

@Alex293
Copy link

Alex293 commented Aug 28, 2017

Here is the start of an observer for IOKit. I does not work but I think its not so far :

import IOKit
import Foundation

let IOKitListenerNewDataNotificationIdentifier: NSNotification.Name = NSNotification.Name("IOKitListenerNewDataNotification")
let IOKitListenerNewDataNotificationKeyboardBrightnessIdentifier = "IOKitListenerNewDataNotificationKeyboardBrightness"

class IOKitListener: NSObject
{
    //var masterPort : mach_port_t?
    var isListenerActive : Bool = false
    var service : io_registry_entry_t
    var notificationPort : IONotificationPortRef?
    //var notificationRunLoopSource : CFRunLoopSource?

    //var info : Dictionary?

    private override init()
    {
        service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleHIDKeyboardEventDriverV2"))
    }

    //MARK: Shared Instance

    static let shared: IOKitListener = IOKitListener()

    func start()
    {
        guard !isListenerActive else { return }
        notificationPort = IONotificationPortCreate(kIOMasterPortDefault)
        //let notificationObject : io_object_t
        IOServiceAddInterestNotification(notificationPort, service, kIOGeneralInterest, { (_, _, _, _) in IOKitListener.shared.didRefresh() }, nil, nil)
        IONotificationPortSetDispatchQueue(notificationPort, DispatchQueue.main)
        isListenerActive = true
    }

    func did (arg1 : UnsafeMutableRawPointer?, arg2 : io_service_t, arg3 : UInt32, arg4 : UnsafeMutableRawPointer?)
    {
        didRefresh()
    }

    func stop()
    {
        guard isListenerActive else { return }
        IONotificationPortDestroy(notificationPort)
    }

    func request()
    {
        didRefresh()
    }

    func didRefresh()
    {
        guard let result = IORegistryEntryCreateCFProperty(service, "KeyboardBacklightBrightness" as CFString, kCFAllocatorDefault,0).takeUnretainedValue() as? Float else { return }
        NotificationCenter.default.post(name: IOKitListenerNewDataNotificationIdentifier, object: nil, userInfo: [IOKitListenerNewDataNotificationKeyboardBrightnessIdentifier: result])
    }
}

@tymscar
Copy link

tymscar commented Aug 28, 2017

That looks awesome @Alex293 ! I've however never done macOS dev so I'm not sure how to execute it :(

I opened up a new Xcode project and made a cocoa app but it doesn't seem to play well with the code.

@Alex293
Copy link

Alex293 commented Aug 29, 2017

Look for a quick tutorial on the net with just a simple button in a controller then add one of the two part of my second comment.

@tymscar
Copy link

tymscar commented Sep 8, 2017

Works nicely! :D

@Alex293
Copy link

Alex293 commented Sep 8, 2017

This didn't match my requirements but I'm happy that it still useful to someone !

@pirate
Copy link
Owner

pirate commented Dec 2, 2019

As mentioned in #8 I now have a new mac to test this on, so I can hopefully get this working again sometime in the next few weeks. Post any tips here if you have them.

@pirate
Copy link
Owner

pirate commented Dec 3, 2019

Related issue: maxmouchet/LightKit#1

@pirate
Copy link
Owner

pirate commented Dec 3, 2019

As far as I can tell, the keyboard brightness is not present in the IORegistry at all :/

ioreg > before.txt
# changed keyboard brightness via touchbar
ioreg > after.txt
diff before.txt after.txt
# no indication of keyboard-brightness related changes in the difff

This means it's either controlled via some other secret API or is not accessible at all. I'll keep investigating, but if I don't find anything we may have to resort to faking the key events as @Alex293 showed above.

@pirate pirate changed the title keyboard brightness read/write fails on mbp 2016 Keyboard brightness read/write fails on TouchBar MBPs (>2016) Mar 17, 2020
@tbrodbeck
Copy link

I just reproduced the issue on my Machine:

$ ./brightness 0.85
Failed to connect to AppleLMUController
setKeyboardBrightness() error
$ neofetch
               .OMMMMo           OS: macOS 10.15.3 19D76 x86_64
               OMMM0,            Host: MacBookPro15,1
     .;loddo:' loolloddol;.      Kernel: 19.3.0
   cKMMMMMMMMMMNWMMMMMMMMMM0:    Uptime: 1 day, 19 hours, 21 mins
 .KMMMMMMMMMMMMMMMMMMMMMMMWd.    Packages: 123 (brew)
 XMMMMMMMMMMMMMMMMMMMMMMMX.      Shell: zsh 5.7.1
;MMMMMMMMMMMMMMMMMMMMMMMM:       Resolution: 1920x1200@2x, 3840x1600@2x
:MMMMMMMMMMMMMMMMMMMMMMMM:       DE: Aqua
.MMMMMMMMMMMMMMMMMMMMMMMMX.      WM: Quartz Compositor
 kMMMMMMMMMMMMMMMMMMMMMMMMWd.    WM Theme: Blue (Dark)
 .XMMMMMMMMMMMMMMMMMMMMMMMMMMk   Terminal: iTerm2
  .XMMMMMMMMMMMMMMMMMMMMMMMMK.   Terminal Font: HackNerdFontComplete-Regular 12
    kMMMMMMMMMMMMMMMMMMMMMMd     CPU: Intel i7-8850H (12) @ 2.60GHz
     ;KMMMMMMMWXXWMMMMMMMk.      GPU: Intel UHD Graphics 630, Radeon Pro 560X
       .cooc,.    .,coo:.        Memory: 11195MiB / 16384MiB

@pirate
Copy link
Owner

pirate commented Mar 31, 2020

Yeah there's no known fix unfortunately, the registry options that were used to control it in the past are no longer available on new machines.

@cotfas
Copy link

cotfas commented May 17, 2020

Any news on this? I have the same issue.

cotfas:mac-keyboard-brightness work$ ./kbrightness
Failed to connect to AppleLMUController
getKeyboardBrightness() error
0.000000
cotfas:mac-keyboard-brightness work$

@pirate
Copy link
Owner

pirate commented May 18, 2020

@cotfas

there's no known fix unfortunately

@daisy-spec

This comment was marked as duplicate.

@pirate pirate pinned this issue Feb 1, 2023
@pirate pirate changed the title Keyboard brightness read/write fails on TouchBar MBPs (>2016) Keyboard brightness API removed by Apple on Macs after 2016 馃槶 (If you know of any new one, plz help馃檹) Feb 1, 2023
@JamesEthan261
Copy link

Maybe
https://github.com/EthanRDoesMC/KBPulse

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

8 participants