【问题标题】:NSWindow title bar is not draggable on its right halfNSWindow 标题栏在其右半部分不可拖动
【发布时间】:2011-05-02 18:33:33
【问题描述】:

我有一个 NSWindow 实例,我以编程方式调整大小(使用 setFrame)。在创建时,它的默认大小为 50x50。然后我调用 setFrame 将其调整为 350x450:一切都很好,我可以随意拖动我的窗口。然后,稍后在程序中,我将其大小调整为 1024x768。此时,我可以拖动的标题栏的唯一部分是前 350 像素:左侧部分。如果我拖动正确的部分,什么都不会发生。好像标题栏仍然认为窗口具有以前的大小。

更新(添加了设置框架的代码):

void CGLWindowMac::_setSize(int width, int height)
    {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        NSRect sFrame;

        sFrame = [NSWindow contentRectForFrameRect:[mObjcImp frame] styleMask:[mObjcImp styleMask]];

        sFrame.origin.y += sFrame.size.height;
        sFrame.origin.y -= height;
        sFrame.size.height = height;
        sFrame.size.width = width;
        sFrame = [NSWindow frameRectForContentRect:sFrame
                                                    styleMask:[mObjcImp styleMask]];

        NSLog(@"Frame Before setsize: cur Size(%f, %f) ", [mObjcImp frame].size.width, [mObjcImp frame].size.height);

        [mObjcImp setFrame:sFrame display:YES animate:NO];

        NSLog(@"Frame After setsize: cur Size(%f, %f) new val(%d, %d)", [mObjcImp frame].size.width, [mObjcImp frame].size.height, width, height);

        // Tell the application that the window size has change.
        onSize(width, height);

        [pool release];
    }

这是输出:

2011-05-04 08:50:47.313 ClientProMac[2461:a0f] Frame Before setsize: cur Size(50.000000, 72.000000) 
2011-05-04 08:50:47.340 ClientProMac[2461:a0f] Frame After setsize: cur Size(350.000000, 472.000000) new val(350, 450)
2011-05-04 08:50:49.148 ClientProMac[2461:7003] Frame Before setsize: cur Size(350.000000, 472.000000) 
2011-05-04 08:50:49.160 ClientProMac[2461:7003] Frame After setsize: cur Size(1024.000000, 790.000000) new val(1024, 768)

奇怪的是,如果我随后通过拖动窗口的角来调整窗口大小,则完整的标题栏再次变得可拖动:错误消失了。

以前有人见过这种行为吗?是什么原因造成的,我该如何解决。

谢谢。

【问题讨论】:

  • 您应该包含调整窗口大小和调用位置的代码。可能是在导致此错误的地方调整了窗口的大小。
  • Josh:屏幕大小似乎对此没有影响。我遇到了双显示器(1280x1024)和单显示器(1280x1024 和 1024x768)的错误。
  • 我同意 jslap,什么时候调用你的“_setSize”方法?您很可能在无法安全调整窗口大小时进行调整大小。您发布的代码没有任何问题,因此它必须取决于之前/之后发生的情况。
  • 为什么要创建自己的自动释放池?没有错,但它表明你在后台线程或什么? NSWindow 不太可能是线程安全的。
  • 是的。我是在另一个线程中做的。我认为 NSWindows 是线程安全的。我只是在主线程中完成了它,它就消失了。 @Abhi:想写一个答案,以便我可以将其标记为已回答?

标签: objective-c cocoa macos nswindow


【解决方案1】:

NSWindow(以及 cocoa 中的大多数 GUI 操作)不是线程安全的。确保您正在调整主线程上的窗口大小。

例如:

NSRect frame = NSMakeRect(42, 42, 420, 420);
dispatch_sync(dispatch_get_main_queue(), ^{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window setFrame:frame];
    [pool release];
});

如果需要向后兼容又不想使用 GCD,可以使用 -[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]。

【讨论】:

    猜你喜欢
    • 2015-07-21
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2013-02-24
    • 2023-03-13
    • 1970-01-01
    • 2023-03-14
    • 2018-12-19
    相关资源
    最近更新 更多