我正在制作截图Mac应用。我正在尝试重建按下Cmd-Ctrl-Shift-4时发生的情况:十字线光标和屏幕截图的选择矩形。
我在所有其他窗户上使用自定义无边框NSWindow。我禁用光标以绘制自己的选择矩形。
我的问题是,只要我点击&拖动以捕获屏幕截图,我的应用程序被激活(因为点击被我的屏蔽窗口截获)。
有没有办法在我的自定义视图/窗口中接收点击而不让我的应用程序被激活?
我尝试使用带有NSPanel
标记的NSNonactivatingPanelMask
,但在这种情况下,我遇到了光标问题:当另一个应用处于活动状态时,我无法自行绘制,因为我可以不要隐藏其他应用的光标......
答案 0 :(得分:2)
实际上,我对这个涉及更多无证件的好东西的问题有一个新的,更好的答案。这是为了未来的后代:
NSWindow上有一个没有记录的方法,可以完全按照您的要求进行操作:
@interface NSWindow (Private)
- (void )_setPreventsActivation:(bool)preventsActivation;
@end
[myWindow _setPreventsActivation:true];
当用户点击它时,这会阻止窗口激活自身及其应用程序。
关于使用未记录的API的标准警告当然适用:Apple可能会在某些时候改变它(虽然它已经存在许多OS X版本,所以他们很可能不会这样做)并且使用它可能会使您的应用程序被拒绝Mac应用程序商店。
答案 1 :(得分:0)
我祈祷现在有更好的方法可以做到这一点,但是当我不得不做类似的事情时,我最终让我的窗口/视图忽略了所有鼠标输入,然后我使用了{{ 1}}(参见Quarts Event Services documentation)全局捕获鼠标事件(不从事件队列中删除它们)。我把它们手动映射到我的窗口,创建了一个自定义副本CGEventTap
并手动将它发送到我的窗口。
这里的巨大缺点(除了复杂性)是我记得需要以root身份运行才能安装事件。但是,我认为有一种通过普遍访问获得许可的方法。
我完全不确定将自定义NSEvent
直接发送到窗口是否会产生与激活应用程序相同的副作用;特别是因为许多事情自10.6以来发生了变化......我建议进行一项简单的测试,看看这是否可行,然后才能实现。
答案 2 :(得分:0)
对于它的价值,除了创建一个巨大的窗口之外,还有另一种方法可以使光标全局不可见。如果你可以使用它,它涉及一些未记录的API:
extern "C" {
typedef int CGSConnection;
void CGSSetConnectionProperty(int, int, const void *, const void *);
int CGSMainConnectionID();
}
void allowHidingCursorForBackgroundOnlyApp()
{
CFStringRef propertyString = CFStringCreateCopy(NULL, CFSTR("SetsCursorInBackground"));
CGSSetConnectionProperty(CGSMainConnectionID(), CGSMainConnectionID(), propertyString, kCFBooleanTrue);
CFRelease((CFTypeRef)propertyString);
}
将其与明智地使用事件点击相结合,捕获并过滤鼠标点击,您可以创建与内置屏幕截图功能相同的效果。
答案 3 :(得分:0)
还有一个想法,你可以在 - (BOOL)_isNonactivatingPanel
子类中重写 NSWindow
私有方法:
@implementation MyWindow
- (BOOL)_isNonactivatingPanel
{
return YES;
}
@end
瞧,你的行为类似于 NSPanel
:)