不透明的NSWindow和WindowServer性能不佳

问题描述 投票:0回答:1

我需要创建不透明的透明窗口,并在其中创建不透明的子视图(称为surfaceView)。每个子视图可以包含数千个子视图(称它们为controlView)。所以结构必须是这样的:

NSWindow(非透明)-NSView(非透明)(窗口contentview)-NSView(不透明)(SurfaceView)--- NSView(不透明)(ControlView)

Illustration

问题是,当内部有成千上万的controlViews时,WindowServer变得过载。看起来窗口中的所有NSView都变得不透明。我不明白我该怎么办。

如果NSWindow不透明,则WindowServer不会过载。但是我需要不透明的窗口。这种情况证明,不透明的NSView可以包含许多性能良好的子视图。

如果NSWindow的样式掩码为[.titled,.resizable],则窗口变为透明(这证明透明窗口具有良好的性能是可能的),但是鼠标不能通过窗口的透明部分工作,不会有任何重载。此外,NSWindow还具有私有类NSThemeframe的圆角。该解决方案非常脏,因为它需要重新实现鼠标事件并替换私有类中的某些方法。

如果表面是childWindows而不是子视图,则没有重载。但是在这种情况下,曲面不能被主窗口裁剪,缩小动画效果不起作用,实际上该窗口并不是实际的窗口。

我已经尝试过与CAlayer,opaque和其他应用程序进行不同的组合和操作,但是它看起来像个bug。绝对有可能获得良好的性能,但我不知道如何。有什么想法吗?

macos cocoa nsview nswindow appkit
1个回答
0
投票

也许这会帮助某人。问题是两个意外事实的结合。

  1. NSWindow属性ignoresMouseEvents具有非常奇怪的行为。如果此ignoresMouseEvents为true,则窗口对鼠标完全透明;如果为false,则窗口对鼠标完全不透明,即使窗口的某些部分是透明的。窗口ignoresMouseEvents的默认值为false,但窍门是,如果您不更改此属性,则窗口的实际行为ignoresMouseEvents将具有第三个选项-窗口在其透明部分对鼠标透明是窗口的默认状态。

所以ignoresMouseEvents是一个布尔值,实际上具有三个选项:true,false和Schrödinger的默认状态(如果您不更改的话。)]]

  1. 如果窗口具有透明的背景并且窗口内部有很多CALayer,则ignoresMouseEvents的这种不直观的第三选项会导致windowServer的cpu意外过载。因此,在某些情况下,对鼠标的windowServer透明性检查是令人难以置信的缓慢。
  2. 因此,默认情况下,此代码将使您的windowServer在任何鼠标移动时都哭泣:

    let window = NSWindow(contentRect: windowrect, styleMask: [.borderless], backing: .buffered, defer: false);
    window.setIsVisible(true);

    window.contentView?.wantsLayer = true;
    window.contentView?.layer?.borderWidth = 1;
    window.backgroundColor = NSColor.clear;

    for _ in 0...5000 {
        let view =  NSView(frame: viewrect);
        view.wantsLayer = true;
        view.layer?.backgroundColor = CGColor(gray: 1.0, alpha: 1.0);
        window.contentView?.addSubview(view);
    }

而且您的视图或图层是否不透明也没关系,它们是否是其他视图的子视图。但是,如果添加window.ignoresMouseEvents = false或true

,则windowServer会平静下来,但窗口对鼠标变为完全不透明或完全透明。

该解决方案正在对鼠标的移动(使用trackingArea或GlobalMonitor)实现鼠标的透明性检查,如果将鼠标置于窗口的透明部分,请将ignoresmouseevents

设置为true,否则设置为false。幸运的是,很难编写鼠标检查的实现,这比默认的windowServer方法要慢。

P.S。抱歉,语言不好。

© www.soinside.com 2019 - 2024. All rights reserved.