parent
8c833cde89
commit
cf9c983ff8
|
@ -152,15 +152,88 @@ extern os_log_t logHandle;
|
||||||
-(void)startLogMonitor
|
-(void)startLogMonitor
|
||||||
{
|
{
|
||||||
//dbg msg
|
//dbg msg
|
||||||
os_log_debug(logHandle, "starting log monitor for AV events via w/ 'com.apple.SystemStatus'");
|
os_log_debug(logHandle, "starting log monitor for AV events");
|
||||||
|
|
||||||
//macOS 13.3
|
//macOS 14+
|
||||||
// use predicate: "subsystem=='com.apple.cmio'" looking for 'CMIOExtensionPropertyDeviceControlPID'
|
if(@available(macOS 14.0, *)) {
|
||||||
if (@available(macOS 13.3, *)) {
|
|
||||||
|
|
||||||
//regex
|
//regex
|
||||||
NSRegularExpression* regex = nil;
|
NSRegularExpression* regex = nil;
|
||||||
|
|
||||||
|
//dbg msg
|
||||||
|
os_log_debug(logHandle, ">= macOS 14+: Using log monitor for AV events via w/ 'added <private> endpoint <private> camera <private>'");
|
||||||
|
|
||||||
|
//init regex
|
||||||
|
regex = [NSRegularExpression regularExpressionWithPattern:@"\\[\\{private\\}(\\d+)\\]" options:0 error:nil];
|
||||||
|
|
||||||
|
//start logging
|
||||||
|
[self.logMonitor start:[NSPredicate predicateWithFormat:@"subsystem=='com.apple.cmio'"] level:Log_Level_Debug callback:^(OSLogEvent* logEvent) {
|
||||||
|
|
||||||
|
//match
|
||||||
|
NSTextCheckingResult* match = nil;
|
||||||
|
|
||||||
|
//pid
|
||||||
|
NSInteger pid = 0;
|
||||||
|
|
||||||
|
//sync to process
|
||||||
|
@synchronized (self) {
|
||||||
|
|
||||||
|
//only interested msgs that end w/:
|
||||||
|
// "added <private> endpoint <private> camera <private> = <pid>;"
|
||||||
|
if(YES != [logEvent.composedMessage hasSuffix:@"added <private> endpoint <private> camera <private>"])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//match on pid
|
||||||
|
match = [regex firstMatchInString:logEvent.composedMessage options:0 range:NSMakeRange(0, logEvent.composedMessage.length)];
|
||||||
|
if( (nil == match) ||
|
||||||
|
(NSNotFound == match.range.location) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//extract/convert pid
|
||||||
|
pid = [[logEvent.composedMessage substringWithRange:[match rangeAtIndex:1]] integerValue];
|
||||||
|
if( (0 == pid) ||
|
||||||
|
(-1 == pid) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//save
|
||||||
|
self.lastCameraClient = pid;
|
||||||
|
|
||||||
|
//(re)enumerate active devices
|
||||||
|
// delayed need as device deactiavation
|
||||||
|
// then update status menu (on main thread)
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
|
||||||
|
{
|
||||||
|
//update on on main thread
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
|
||||||
|
//update status menu
|
||||||
|
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).statusBarItemController setActiveDevices:[self enumerateActiveDevices]];
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}); //dispatch for delay
|
||||||
|
}
|
||||||
|
|
||||||
|
}];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//macOS 13.3+
|
||||||
|
// use predicate: "subsystem=='com.apple.cmio'" looking for 'CMIOExtensionPropertyDeviceControlPID'
|
||||||
|
else if (@available(macOS 13.3, *)) {
|
||||||
|
|
||||||
|
//regex
|
||||||
|
NSRegularExpression* regex = nil;
|
||||||
|
|
||||||
|
//dbg msg
|
||||||
|
os_log_debug(logHandle, ">= macOS 13.3+: uUsing 'CMIOExtensionPropertyDeviceControlPID'");
|
||||||
|
|
||||||
//init regex
|
//init regex
|
||||||
regex = [NSRegularExpression regularExpressionWithPattern:@"=\\s*(\\d+)\\s*;" options:0 error:nil];
|
regex = [NSRegularExpression regularExpressionWithPattern:@"=\\s*(\\d+)\\s*;" options:0 error:nil];
|
||||||
|
|
||||||
|
@ -225,8 +298,11 @@ extern os_log_t logHandle;
|
||||||
// use predicate: "subsystem=='com.apple.SystemStatus'"
|
// use predicate: "subsystem=='com.apple.SystemStatus'"
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//start logging
|
//dbg msg
|
||||||
[self.logMonitor start:[NSPredicate predicateWithFormat:@"subsystem=='com.apple.SystemStatus'"] level:Log_Level_Default callback:^(OSLogEvent* logEvent) {
|
os_log_debug(logHandle, "< macOS 13.3+: Using 'com.apple.SystemStatus'");
|
||||||
|
|
||||||
|
//start logging
|
||||||
|
[self.logMonitor start:[NSPredicate predicateWithFormat:@"subsystem=='com.apple.SystemStatus'"] level:Log_Level_Default callback:^(OSLogEvent* logEvent) {
|
||||||
|
|
||||||
//sync to process
|
//sync to process
|
||||||
@synchronized (self) {
|
@synchronized (self) {
|
||||||
|
|
|
@ -333,9 +333,12 @@ bail:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//prefs
|
//quit
|
||||||
case quit:
|
case quit:
|
||||||
|
|
||||||
|
//dbg msg
|
||||||
|
os_log_debug(logHandle, "quitting...");
|
||||||
|
|
||||||
//exit
|
//exit
|
||||||
[NSApp terminate:self];
|
[NSApp terminate:self];
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "darkMode.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "lightMode.png",
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "light"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "darkMode.png",
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
|
@ -1,35 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "darkMode.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "lightMode.png",
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "light"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "darkMode.png",
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||||
<rect key="contentRect" x="196" y="240" width="523" height="237"/>
|
<rect key="contentRect" x="196" y="240" width="523" height="237"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="3440" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||||
<view key="contentView" id="se5-gp-TjO">
|
<view key="contentView" id="se5-gp-TjO">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="523" height="237"/>
|
<rect key="frame" x="0.0" y="0.0" width="523" height="237"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
|
Loading…
Reference in New Issue