重新实现Mac OS X Dock的自动隐藏功能

时间:2010-10-12 05:03:53

标签: objective-c cocoa nsview nswindow

我正在尝试在Objective-C中创建一个服务器监视器,其行为类似于OS X中的扩展坞。我希望当鼠标移动到一侧时它从屏幕一侧滑动屏幕的类似于自动隐藏时的停靠点。我不知道从哪里开始..

我猜我需要一个带有NSBorderlessWindowMask掩码的窗口,但在那之后我不知所措。我只是显示该窗口的1个像素,并等待mouseOver事件,或者这只是一个可以合理完成的hacky解决方案?如果这是最好的方法,我将如何检查鼠标悬停事件?

1 个答案:

答案 0 :(得分:5)

我认为你有正确的想法。请记住,根据你想要做的事情,无边界窗口不是最容易使用的东西(它们可能很棘手,尤其是Spaces和Exposé等可能添加的复杂功能)。

如果这只是一个个人项目,你可能会在窗口的一个像素边缘显示出来。如果这是一个专业项目,我建议使用Event Taps(稍后会详细介绍)。

如果你采用“个人项目”的方式,你可以留下窗口的1 px边缘,使用自定义的NSView子类将自己绘制为透明并设置NSTrackingArea来通知你mouseEntered:events。

要绘制透明区域,您可以在drawRect:

中执行类似的操作
- (void)drawRect:(NSRect)frame {
   [[NSColor clearColor] set];
   NSRectFill(frame);
}

要设置跟踪区域,请在视图子类的awakeFromNib中执行此操作:

- (void)awakeFromNib {
 NSTrackingArea *tracker = [[[NSTrackingArea alloc] initWithRect:[self frame]
   options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)
   owner:self
   userInfo:nil] autorelease];

 [self addTrackingArea:tracker];
}

- (void)mouseEntered:(NSEvent *)theEvent {
 [[[self window] windowController] showWindow:self];
}

- (void)mouseExited:(NSEvent *)theEvent {
 [[[self window] windowController] myHideMethodName:self];
}

这假设你要覆盖窗口控制器的showWindow:方法来做动画或其他什么)。顺便说一句,无论你做什么,都不要寻找鼠标移动的事件。 (在您的情况下没什么大不了的,因为您的区域可能非常小,但一般来说,寻找鼠标移动事件是错误的方法,因为它们可以快速充满事件队列。使用跟踪区域功能Quartz Debug看看大多数软件是如何做到的。请记住,即使视图可能会使其自身透明,但它仍然会阻止您的鼠标事件进入其下面的任何内容(可能是另一个窗口或桌面等)。

如果你想进入“专业”路线,你应该能够设置事件点击,基本上完成跟踪区域代码所做的事情。使用此路线,您可以完全隐藏窗口,这样就不会干扰任何事物。要了解Event Taps的工作原理,您可能需要下载以下2个应用程序:

http://brockerhoff.net/quay/

http://pfiddlesoft.com/eventtapstestbench/

第一个是如何使用事件点击来完成一些很酷的东西的一个很酷的例子(阅读帮助以查看更高级的功能)。当您将鼠标移动到Dock左侧的项目上方时,Rainer使用事件点击来点击Dock来弄清楚。然后他可以显示他的自定义菜单,而不是Dock的内置菜单。

第二个应用程序对于检查Quay(或QuayMenu,真的)如何以及对其事件点击的作用是必不可少的。

BTW,事件点击API在Quartz中(以下是您将用于设置事件点击的示例):

CFMachPortRef CGEventTapCreate (
   CGEventTapLocation tap,
   CGEventTapPlacement place,
   CGEventTapOptions options,
   CGEventMask eventsOfInterest,
   CGEventTapCallBack callback,
   void *refcon
);

我对事件的了解不够充分,我只想举例说明如何设置它,但这至少应该指向正确的方向。

希望这会有所帮助......