Inside Universal Control

Universal Control was one of the most anticipated features when Monterey was announced at WWDC almost exactly a year ago. Although it did make some early appearances during the beta phase, it was noticeably absent when macOS 12.0.1 was released on 26 October 2021, and didn’t appear as a beta until 12.3, with its full release in macOS 12.4 and iPadOS 15.4.

It enables you to use one set of input devices – keyboard, mouse, trackpad – across two or three macOS and iPadOS systems, both to control them all, and to work between them using features such as copy and paste, and drag and drop, including the copying of files.

Putting it to work

According to Apple’s definitive account, Universal Control works with the following Macs and iPads:

  • MacBook Pro (2016 and later)
  • MacBook (2016 and later)
  • MacBook Air (2018 and later)
  • iMac (2017 and later)
  • iMac (5K Retina 27-inch, Late 2015)
  • iMac Pro
  • Mac mini (2018 and later)
  • Mac Pro (2019)
  • iPad Pro
  • iPad Air (3rd generation and later)
  • iPad (6th generation and later)
  • iPad mini (5th generation and later).

All devices to be brought under Universal Control must be:

  • running a compatible version of macOS (12.4 or later) or iPadOS (15.4 or later);
  • signed into the same iCloud account using the same Apple ID with two-factor authentication enabled;
  • for wireless connections, have Bluetooth, Wi-Fi and Handoff enabled, and be within 3 m (10 feet) of one another;
  • for USB connection with an iPad, the Mac must be trusted on that iPad;
  • Macs mustn’t be sharing their Internet connection, and iPads mustn’t be sharing their cellular/mobile connection.

univcontrol1

It has one control dialog, accessible through the Universal Control… button in the Displays pane, which enables Universal Control, its ‘push through’ activation, and automatic reconnection. You should normally tick the first two at least, if you want to use Universal Control on your Mac. When it’s available, you can arrange the displays of Macs and devices in the Displays pane, although it’s normally smart enough to detect available displays and position them correctly.

Once that has been done, all you need do is push the pointer from one display to the one you want to control, and it should just work. One marginal tip I offer is for those who set hot corners on their display, for instance to activate the screen saver. If you do that, it’s worth setting both the lower corners to the same action; when one of those corners links to a display under Universal Control, it will no longer function as a hot corner.

univcontrol2

If you want to disconnect a device from Universal Control, simply put it to sleep, use the Add Display popup menu in the Displays pane, or press Control-Option-Command-Delete to disconnect all devices.

How it works

Universal Control uses a simple model, in which the Mac whose paired mouse/trackpad and keyboard become master controllers acts as the Controller, and the Mac or iPad whose display is being controlled by those input devices acts as the Target. Device input continues to be made to the Controller, where the com.apple.universalcontrol sub-system is responsible for managing connections to Targets, and routing input and control events to the Target by sending it events.

At present, because Universal Control is still new, it makes copious and detailed entries in the Unified Log, which can be browsed for the sub-systems com.apple.universalcontrol and com.apple.rapport. One problem you’ll come across is that time isn’t synced precisely across logs, so matching the XID of sent and received events is often the best way to align two log extracts with one another.

Universal Control is activated on the Controller when the pointer enters the Hot Zone, at the edge of the display touching the display of the Target. This activates the Hot Zone, shown sometimes on the display as a blue bar. The Controller then tries connecting to the target, as marked by the Sync Barrier, and synchronisation. The Sync Barrier is assigned a sequential positive integer on each system, for example 12 on the Controller and 13 on the Target, and each is given an XID used to identify events as they’re passed between the two.

Although entries refer to merging clocks, times given for log entries aren’t brought into synchrony. When the link has been established, events are exchanged thus:
Controller
12:15:15.520066 com.apple.rapport Stream UniversalControl CoreUtils 49545: SendEventID 'SYNC', XID 0x74F6E911, <89f65e343169b2869e1c9a9f89f14059> (609 bytes) on link type AWDL
Target
12:15:16.077601 com.apple.rapport Stream UniversalControl CoreUtils 49545: SendEventID 'SYNC', XID 0x64DEDE01, <2794252f88f20fed20f34c9de208bf80> (609 bytes) on link type AWDL

The pointer is moved from the Controller’s display to the Target’s, at the Sync Barrier End, following which all pointer events are forwarded by event messages similar to
Controller
12:15:15.541576 com.apple.rapport Stream UniversalControl CoreUtils 49546: SendEventID 'EVNT', XID 0x11FF58DE, <d31b0525f38b13163f6226068b1fbb3f> (89 bytes) on link type AWDL
Target
12:15:16.105219 com.apple.rapport Stream UniversalControl CoreUtils 49546: Received event ID 'EVNT', XID 0x11FF58DE, 1 keys, from NULL

For example, double-tapping on an app icon on the Target results in a double event:
Controller
12:15:18.019046 com.apple.rapport Stream UniversalControl CoreUtils 49546: SendEventID 'EVNT', XID 0x11FF5A31, <206440470661c2e19adc36cb24b2a14a> (113 bytes) on link type AWDL
12:15:18.019066 com.apple.rapport Stream UniversalControl CoreUtils 49546: SendEventID 'EVNT', XID 0x11FF5A32, <c4a86e8712c9db4aee367bfdc84dfab6> (113 bytes) on link type AWDL

Target
12:15:18.570813 com.apple.rapport Stream UniversalControl CoreUtils 49546: Received event ID 'EVNT', XID 0x11FF5A31, 1 keys, from NULL
12:15:18.571220 com.apple.rapport Stream UniversalControl CoreUtils 49546: Received event ID 'EVNT', XID 0x11FF5A32, 1 keys, from NULL

which is then converted by the Target to send that action, just as if it had been performed on a locally-connected trackpad:
12:15:18.579203 Finder AppKit sendAction:
12:15:18.579695 Finder AppKit sendAction:

EventID types used include:

  • EVNT, an input device event such as moving the pointer and clicking/tapping
  • SYNC, synchronisation events between Controller and Target
  • DRAG, an input device drag of an item
  • CLIP, an event involving the Clipboard of the Target.

Dragging and dropping a file to copy it between Target and Controller involves a sequence of those events. First, the file item is dragged (DRAG), then the point crosses from Target to Controller and is made local to the Controller with a CFPasteboard drag (CLIP) promising the content of the file. When the file is dropped in place on the Controller display, the file is then copied across over the Wi-Fi connection between the two systems.

With the pointer back on the Controller’s local display, Universal Control then ceases sending events to the Target, until the next time the pointer is moved into the Hot Zone, which starts the sequence again.