我需要创建不透明的透明窗口,并在其中创建不透明的子视图(称为surfaceView)。每个子视图可以包含数千个子视图(称它们为controlView)。所以结构必须是这样的:
NSWindow(非透明)-NSView(非透明)(窗口contentview)-NSView(不透明)(SurfaceView)--- NSView(不透明)(ControlView)
问题是,当内部有成千上万的controlViews时,WindowServer变得过载。看起来窗口中的所有NSView都变得不透明。我不明白我该怎么办。
如果NSWindow不透明,则WindowServer不会过载。但是我需要不透明的窗口。这种情况证明,不透明的NSView可以包含许多性能良好的子视图。
如果NSWindow的样式掩码为[.titled,.resizable],则窗口变为透明(这证明透明窗口具有良好的性能是可能的),但是鼠标不能通过窗口的透明部分工作,不会有任何重载。此外,NSWindow还具有私有类NSThemeframe的圆角。该解决方案非常脏,因为它需要重新实现鼠标事件并替换私有类中的某些方法。
如果表面是childWindows而不是子视图,则没有重载。但是在这种情况下,曲面不能被主窗口裁剪,缩小动画效果不起作用,实际上该窗口并不是实际的窗口。
我已经尝试过与CAlayer,opaque和其他应用程序进行不同的组合和操作,但是它看起来像个bug。绝对有可能获得良好的性能,但我不知道如何。有什么想法吗?
也许这会帮助某人。问题是两个意外事实的结合。
所以ignoresMouseEvents是一个布尔值,实际上具有三个选项:true,false和Schrödinger的默认状态(如果您不更改的话。)]]
因此,默认情况下,此代码将使您的windowServer在任何鼠标移动时都哭泣:
,则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
该解决方案正在对鼠标的移动(使用trackingArea或GlobalMonitor)实现鼠标的透明性检查,如果将鼠标置于窗口的透明部分,请将ignoresmouseevents
设置为true,否则设置为false。幸运的是,很难编写鼠标检查的实现,这比默认的windowServer方法要慢。P.S。抱歉,语言不好。