I don't think it makes sense to put bare fds as ports for the runloop. This is because, as you've already observed that these are only eventfds and timerfds in the runloop internals; it's not really a bug per se. Furthermore, the semantics described in the documentation suggest that the runloop expects plain signalling rather than the select style readable/writable/exceptional set. You would need to create a runloop source that adapts filehandle events to runloop signals -- as you note, that's what FileHandle (presumably? I have not looked at that closely) does.
If you're needing to handle the libinput events at a higher priority than other events, it appears CFRunLoop doesn't offer you that functionality and maybe that API is a bad fit for you. Maybe trying to hook into Dispatch directly (as others mention) might be more useful, but it may not be any easier than writing a hot loop with XNextEvent for now and trying to figure this all out when you have the basics of your library in place.