可拖动的 NSWindow 闪烁

Posted

技术标签:

【中文标题】可拖动的 NSWindow 闪烁【英文标题】:Draggable NSWindow flickering 【发布时间】:2013-02-24 03:17:09 【问题描述】:

我创建了一个可拖动的 NSWindow,可以通过它的内容进行拖动。它没有标题栏(无边框)。

拖动效果很好,但时不时会闪烁。似乎窗口正在快速转到某个错误位置,然后返回到鼠标所在的位置(仍然按住鼠标)。它在我的 macbook 上似乎也比在我的 imac 上运行得更好。

谁能弄清楚我做错了什么?

在init中我调用了这两个方法:

[self setMovableByWindowBackground:YES];
[self setMovable:YES];

这些是使用的变量:

NSPoint currentLocation;
NSPoint newOrigin;
int offsetX,offsetY;

这里是关于拖动的代码:

- (void)mouseMoved:(NSEvent *)theEvent



- (void)mouseDown:(NSEvent *)theEvent

    currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];

    offsetX = currentLocation.x - [self frame].origin.x;
    offsetY = currentLocation.y - [self frame].origin.y;


- (void)mouseDragged:(NSEvent *)theEvent
    currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];

    newOrigin.x = currentLocation.x - offsetX;
    newOrigin.y = currentLocation.y - offsetY;

    [self setFrameOrigin:newOrigin];


编辑:好的,如上所述,这是一个透明的无边框 NSPanel。是的,我似乎不需要上面的代码。

但是,我确实需要拖动窗口的位置,并且我需要它不断。

如果我像这样得到框架原点:

self.frame.origin

这报告了一个错误的数字。可可更新这个内部值似乎需要一些时间。

其次,面板是非激活的。在第一次加载(聚焦)并调用 mouseDragged 时移动它时效果很好。但不是当我与另一个应用程序交互然后返回时。只有 mouseDown 和 mouseUp 被调用。

【问题讨论】:

【参考方案1】:

你收到一个 NSWindowDidMove 通知但不是实时的

如果您需要实时更新,默认情况下这是不可能的 AFAIK。与在调整大小期间相同,框架不会更新。

请参阅How to receive notifications when moving Window by mouse? 以获取有关如何执行此操作的一些链接

【讨论】:

【参考方案2】:

如果-setMovableByWindowBackground: 被调用,则不需要您的鼠标跟踪代码;你基本上只是在复制这项工作。从它的声音来看,我会说您的 -init 方法没有被调用,很可能是因为您是从 .xib 加载的(而是调用 -initWithCoder:)。

如果窗口是专门由 xib 加载创建的,则将上述所有代码替换为:

- (void)awakeFromNib

    [self setMovableByWindowBackground:YES];

至于为什么您会看到闪烁,我最好的猜测是,这是因为鼠标输入与屏幕刷新不同步,因此以编程方式使窗口跟随鼠标比仅随着每次鼠标移动而更新要复杂一些.但是如果你让 NSWindow 为你处理它,你就完全不用担心这个了。

【讨论】:

顺便提一下,[self setMovable:YES] 也是不必要的,除非您在其他地方将其设置为 NO - 默认为 YES。 AFAIK,有必要(重新)实现使用 NSBorderlessWindowMask 的窗口的鼠标跟踪/移动代码。看起来该代码基于 Apple 的 RoundTransparentWindow 示例代码:developer.apple.com/library/mac/#samplecode/…。我还认为initWithCoder: 的东西适用于除了NSWindow 之外的几乎所有东西,因为它不支持<NSCoding> 没错,就是透明的无边框窗口。很抱歉没有提到这一点!但是,它似乎确实可以在没有 mousedragged / mousedown 代码的情况下工作(移动)。但我首先拥有该代码的原因是在拖动时对拖动的位置做一些事情。并且 cocoa 在拖动时似乎没有正确报告帧来源(它在报告正确数字时有点滞后)。我会在五分钟后更新我的问题并提供更多信息。

以上是关于可拖动的 NSWindow 闪烁的主要内容,如果未能解决你的问题,请参考以下文章

PCL:NSWindow 拖动区域应该只在主线程上无效

制作我自己的“可拖动”功能

如何使 NSWindow 阻止其他 Windows?

VBox拖动闪烁

Jquery UI 可拖动列表项到框

UIView锚点->拖动->旋转变换导致闪烁