【问题标题】:Click through custom NSWindow点击自定义 NSWindow
【发布时间】:2015-04-03 23:24:20
【问题描述】:

我有自定义 NSWindow,自定义 NSView 设置为其 contentView。

窗口被初始化为:

[window setOpaque:NO];
[window setBackgroundColor: [NSColor clearColor]];
[window setHasShadow: NO];

[window setAcceptsMouseMovedEvents: YES];
[window setLevel: NSFloatingWindowLevel];

内容视图,在其drawRect 中绘制由纯色填充的简单圆圈。

这一切正常 - 窗口出现在桌面上,我看到了那个圆圈。

唯一不起作用的:整个窗口矩形对于鼠标点击是不透明的。如果我单击圆圈外(但在不可见的窗口框内),我的视图会收到 mouseDown 事件,但我希望激活底层窗口(或桌面)。

看来我需要在我的 NSWindow 类上覆盖类似 hitTest 方法的东西,但不幸的是没有这样的方法。

那么问题来了:是否可以在 OS X 中通过自定义点击区域来设置 NSWindow。如果“是”,那么如何实现?

更新:

查看 RoundTransparentWindow 示例,该示例按预期工作 - 窗口在透明区域中单击通过。好像是这样的:

- (void)drawRect:(NSRect)rect {
   ...
   // Reset the window shape and shadow.
    if (shouldDisplayWindow) {
        [[self window] display];
        [[self window] setHasShadow:NO];
        [[self window] setHasShadow:YES];
    }
}

在 CustomView.m 中与问题有关,但即使使用它(在我的情况下)我也无法实现鼠标点击的透明度:(

【问题讨论】:

  • 您是否在任何时候设置了窗口的ignoresMouseEvents 属性? (您不应该这样做。)尝试从内容视图的-drawRect: 调用-invalidateShadow 而不是来自RoundTransparentWindow 的代码。你说-drawRect: 只是画了一个圆圈。在这样做之前,它是否会尝试填补其界限?最后,在不打开窗口的acceptsMouseMovedEvents的情况下试一试。
  • 我没有碰ignoresMouseEventsinvalidateShadow 没有帮助。在绘图时 - 没什么特别的 CGContextAddEllipseInRect/CGContextFillPath.

标签: macos nswindow


【解决方案1】:

回答我自己的问题:

在 OS X 上,为了使窗口具有自定义形状并点击透明区域,必须满足以下条件:

  1. 创建窗口必须仅使用NSBorderlessWindowMask 设置,例如[window setStyleMask: NSBorderlessWindowMask]

  2. 不得致电[window setIgnoresMouseEvent: NO]。因为该方法显然包含苹果方面的错误。

  3. 窗口的内容视图不得使用图层。所以像[[window contentView] setWantsLayer: YES] 这样的东西也有效地禁用了点击。

以防万一:所有这些都是关于 OS X 上 Sciter 中的分层窗口处理

【讨论】:

  • 我不会说设置ignoresMouseEvents 是错误的。只是有三种状态(忽略所有事件,不忽略任何事件,忽略透明区域上的事件)。窗口从第三种状态开始,您可以将属性设置为在前两种状态之间切换,但是一旦这样做,您将永远无法回到原始状态。这是一个不幸的设计。
  • “不幸的设计”有点矛盾,不是吗?
  • @KenThomases 对ignoresMouseEvents 的三态性的评论值得一提。谢谢。
  • 它似乎对我有用,即使wantsLayer = true
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 2015-05-30
相关资源
最近更新 更多