单击自定义 NSWindow
Click through custom NSWindow
我有自定义 NSWindow,自定义 NSView 设置为它的 contentView。
window 初始化为:
[window setOpaque:NO];
[window setBackgroundColor: [NSColor clearColor]];
[window setHasShadow: NO];
[window setAcceptsMouseMovedEvents: YES];
[window setLevel: NSFloatingWindowLevel];
内容视图,在其 drawRect
中绘制了由纯色填充的简单圆圈。
一切正常 - window 出现在桌面上,我看到了那个圆圈。
唯一不起作用的是:整个 window 矩形对于鼠标点击不是透明的。如果我单击圆圈外(但在不可见的 window 框内),我的视图会收到 mouseDown 事件,但我希望底层 windows (或桌面)被激活。
看来我需要在我的 NSWindow 上覆盖 hitTest 方法之类的东西 class 但不幸的是没有这样的方法。
问题也是如此:是否可以在 OS X 中使用具有自定义点击区域的 NSWindow。如果 "yes" 那么如何?
更新:
查看按预期工作的 RoundTransparentWindow 示例 - window 在透明区域中被点击。好像是这个:
- (void)drawRect:(NSRect)rect {
...
// Reset the window shape and shadow.
if (shouldDisplayWindow) {
[[self window] display];
[[self window] setHasShadow:NO];
[[self window] setHasShadow:YES];
}
}
in CustomView.m 与问题有关,但即使有它(在我的情况下)我也无法实现鼠标点击的透明度:(
回答我自己的问题:
在 OS X 上,为了 windows 在透明区域点击自定义形状必须满足以下条件:
window必须创建,例如[window setStyleMask: NSBorderlessWindowMask]
设置NSBorderlessWindowMask
。
您不得调用[window setIgnoresMouseEvent: NO]
。由于该方法显然包含 Apple 方面的错误。
window的内容视图不得使用图层。所以像这样的 [[window contentView] setWantsLayer: YES]
也有效地禁用了点击。
以防万一:所有这些都是关于 OS X
上 Sciter 中的分层 windows 处理
感谢 c-smile 绝对令人难以置信的回答和 KenThomases 绝对令人难以置信的评论,
这是执行“全屏浮动应用程序”的基本且简单的方法,点击通过,反之,您可以点击“您的”内容。
你会需要这个(出于我不完全理解的原因,window 没有它就无法完全展开),
然后...
override func viewWillAppear() {
super.viewWillAppear()
guard let w = view.window else {
print("what the?")
return
}
w.styleMask = .borderless
// note that you DO NOT do this: w.ignoresMouseEvents = true
// see comments:
w.collectionBehavior = [.fullScreenPrimary]
w.level = .floating
w.isMovable = false
w.titleVisibility = .hidden
w.titlebarAppearsTransparent = true
w.standardWindowButton(.closeButton)?.isHidden = true
w.standardWindowButton(.miniaturizeButton)?.isHidden = true
w.standardWindowButton(.zoomButton)?.isHidden = true
w.hasShadow = false
w.isOpaque = false
w.backgroundColor = NSColor(red: 1, green: 1, blue: 1, alpha: 0)
w.zoom(self)
guard let screen = w.screen ?? NSScreen.main else {
print("what the???")
return
}
w.setFrame(screen.visibleFrame, display: true)
}
我有自定义 NSWindow,自定义 NSView 设置为它的 contentView。
window 初始化为:
[window setOpaque:NO];
[window setBackgroundColor: [NSColor clearColor]];
[window setHasShadow: NO];
[window setAcceptsMouseMovedEvents: YES];
[window setLevel: NSFloatingWindowLevel];
内容视图,在其 drawRect
中绘制了由纯色填充的简单圆圈。
一切正常 - window 出现在桌面上,我看到了那个圆圈。
唯一不起作用的是:整个 window 矩形对于鼠标点击不是透明的。如果我单击圆圈外(但在不可见的 window 框内),我的视图会收到 mouseDown 事件,但我希望底层 windows (或桌面)被激活。
看来我需要在我的 NSWindow 上覆盖 hitTest 方法之类的东西 class 但不幸的是没有这样的方法。
问题也是如此:是否可以在 OS X 中使用具有自定义点击区域的 NSWindow。如果 "yes" 那么如何?
更新:
查看按预期工作的 RoundTransparentWindow 示例 - window 在透明区域中被点击。好像是这个:
- (void)drawRect:(NSRect)rect {
...
// Reset the window shape and shadow.
if (shouldDisplayWindow) {
[[self window] display];
[[self window] setHasShadow:NO];
[[self window] setHasShadow:YES];
}
}
in CustomView.m 与问题有关,但即使有它(在我的情况下)我也无法实现鼠标点击的透明度:(
回答我自己的问题:
在 OS X 上,为了 windows 在透明区域点击自定义形状必须满足以下条件:
window必须创建,例如
[window setStyleMask: NSBorderlessWindowMask]
设置NSBorderlessWindowMask
。您不得调用
[window setIgnoresMouseEvent: NO]
。由于该方法显然包含 Apple 方面的错误。window的内容视图不得使用图层。所以像这样的
[[window contentView] setWantsLayer: YES]
也有效地禁用了点击。
以防万一:所有这些都是关于 OS X
上 Sciter 中的分层 windows 处理感谢 c-smile 绝对令人难以置信的回答和 KenThomases 绝对令人难以置信的评论,
这是执行“全屏浮动应用程序”的基本且简单的方法,点击通过,反之,您可以点击“您的”内容。
你会需要这个(出于我不完全理解的原因,window 没有它就无法完全展开),
然后...
override func viewWillAppear() {
super.viewWillAppear()
guard let w = view.window else {
print("what the?")
return
}
w.styleMask = .borderless
// note that you DO NOT do this: w.ignoresMouseEvents = true
// see comments:
w.collectionBehavior = [.fullScreenPrimary]
w.level = .floating
w.isMovable = false
w.titleVisibility = .hidden
w.titlebarAppearsTransparent = true
w.standardWindowButton(.closeButton)?.isHidden = true
w.standardWindowButton(.miniaturizeButton)?.isHidden = true
w.standardWindowButton(.zoomButton)?.isHidden = true
w.hasShadow = false
w.isOpaque = false
w.backgroundColor = NSColor(red: 1, green: 1, blue: 1, alpha: 0)
w.zoom(self)
guard let screen = w.screen ?? NSScreen.main else {
print("what the???")
return
}
w.setFrame(screen.visibleFrame, display: true)
}