objective-c - 重新实现 Mac OS X Dock 的自动隐藏

标签 objective-c cocoa nsview nswindow

我正在尝试用 Objective-C 制作一个服务器监视器,其行为有点像 OS X 中的扩展坞。我希望当鼠标移动到一侧时它可以从屏幕的一侧滑动屏幕的位置,有点像自动隐藏打开时的底座。我不知道从哪里开始..

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

最佳答案

我认为你的想法是正确的。但请记住,根据您想要做什么,无边框窗口并不是最容易使用的东西(它们可能很棘手,尤其是像 Spaces 和 Exposé 这样的东西可能会增加复杂性)。

如果这只是一个个人项目,您可能会只显示窗口的一个像素边缘。如果这是一个专业项目,我建议考虑使用事件点击(稍后会详细介绍)。

如果您采用“个人项目”方式,您可以保留显示窗口的 1 px 边缘,使用自定义 NSView 子类将其自身绘制为透明并设置 NSTrackingArea 来通知您 mouseEntered: 事件。

要绘制透明区域,您可以在drawRect中执行类似的操作:

- (void)drawRect:(NSRect)frame {
   [[NSColor clearColor] set];
   NSRectFill(frame);
}

要设置跟踪区域,请在 View 子类的 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];
}

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

如果您想走“专业”路线,您应该能够设置事件点击来基本上完成与跟踪区域代码相同的任务。通过这条路线,您可以将 window 完全隐藏起来,这样它就不会干扰任何东西。要了解事件点击的工作原理,您可能需要下载以下 2 个应用程序:

http://brockerhoff.net/quay/

http://pfiddlesoft.com/eventtapstestbench/

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

第二个应用程序对于检查 Quay(或 QuayMenu,实际上)对其事件点击的操作方式和内容至关重要。

顺便说一句,事件点击 API 位于 Quartz 中(以下是您用来设置事件点击的示例):

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

我自己对事件点击了解不够,无法举例说明如何设置它,但这至少应该为您指明正确的方向。

希望这有帮助......

关于objective-c - 重新实现 Mac OS X Dock 的自动隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3911831/

相关文章:

objective-c - Finder 和 Carbon 文件管理器中的文件夹大小存在差异

objective-c - 如何更改 IBAction 中 NSMatrix 的选择?

swift - 如何为 NSWindow 的标题栏着色

cocoa - 在 cocoa 中使用 while 循环创建数组

objective-c - setNeedsLayout :YES 后未调用NSView布局方法

iphone - 如何测试生产推送通知?

ios - UITextField 失去焦点事件

Cocoa:NSView 未绘制矩形

cocoa - 使 NSView 具有固定宽度和可变高度以适应内容

ios - 从 CLProximity 获取距离