You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSWindow的sharingType属性生效但取值始终无法正确更新

macOS NSWindow sharingType 回读异常问题解决

问题现象

设置NSWindow的sharingType为NSWindowSharingNone或NSWindowSharingReadOnly后,从第二次循环开始调用sharingType获取值时,始终返回0(即NSWindowSharingNone),但窗口防截图的功能本身正常,仅属性回读出现异常。

原因分析

这是AppKit框架的已知行为:当窗口共享类型设置为NSWindowSharingNone或NSWindowSharingReadOnly时,系统内部不会维护该属性的回读值,导致后续调用sharingType无法返回实际设置的状态。框架优先保证功能生效,而非属性值的回读准确性。

解决方案

放弃依赖系统属性的回读,自行维护窗口的共享状态即可。以下是修改后的代码:

@interface ViewController () {
    NSWindowSharingType _currentSharingType; // 自行维护当前共享状态
}

@property (strong) NSWindow* childWindow;
@property (strong) NSTimer* timer;
@end

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self createWindowAction: nil];
    
    _currentSharingType = NSWindowSharingNone; // 初始化状态
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(triggerAction:) name: @"NotificationMessageEvent" object: nil];
    
    self.timer = [NSTimer scheduledTimerWithTimeInterval: 4.0f repeats: YES block:^(NSTimer * _Nonnull timer)
    {
        // 切换状态
        _currentSharingType = (_currentSharingType == NSWindowSharingNone) ? NSWindowSharingReadOnly : NSWindowSharingNone;
        
        NSLog( @"Current maintained sharing type: %lu", (unsigned long)_currentSharingType );
        NSLog( @"Updating sharing type to: %lu", (unsigned long)_currentSharingType );
        [self.childWindow setSharingType: _currentSharingType];
        // 直接使用自行维护的状态,不再依赖系统回读
        NSLog( @"After update, maintained sharing type: %lu", (unsigned long)_currentSharingType );
        NSLog(@"");
    }];
}

-(void) dealloc
{
    [self.timer invalidate];
    self.timer = nil;
}

- (IBAction)createWindowAction:(NSButton *)sender {
    NSLog(@"createWindowAction");
    if (!self.childWindow) {
        self.childWindow = [[NSWindow alloc] initWithContentRect: CGRectMake( 100.0f, 150.0f, 500.0f, 400.0f ) styleMask: NSWindowStyleMaskBorderless | NSWindowStyleMaskNonactivatingPanel backing: NSBackingStoreBuffered defer: NO];
        self.childWindow.collectionBehavior = NSWindowCollectionBehaviorMoveToActiveSpace | NSWindowCollectionBehaviorTransient | NSWindowCollectionBehaviorAuxiliary | NSWindowCollectionBehaviorParticipatesInCycle;
        self.childWindow.hasShadow = NO;
        self.childWindow.accessibilityElement = YES;
        [self.childWindow setCanHide: NO];
        // 初始化窗口时同步设置共享类型
        [self.childWindow setSharingType: _currentSharingType];
    }
    
    [self.childWindow orderFrontRegardless];
}

关键修改点

  • 用NSWindowSharingType类型的变量_currentSharingType替代原布尔值,直接维护当前状态
  • 所有状态判断、日志输出均基于自行维护的变量,不再调用[self.childWindow sharingType]
  • 窗口初始化时同步设置共享类型,确保初始状态一致

验证说明

若需确认功能是否生效,直接用系统截图工具测试窗口是否被截取即可,无需依赖属性回读值。

内容的提问来源于stack exchange,提问作者Oleg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:26:38