【问题标题】:Is there a way to make a custom NSWindow work with Spaces有没有办法让自定义 NSWindow 与 Spaces 一起使用
【发布时间】:2009-11-07 22:00:49
【问题描述】:

我正在编写一个应用程序,该应用程序具有使用 NSWindow 子类创建的自定义透明 NSWindow,其中包含以下内容:

- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag 
{
   self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag];

   if (self)
   {
     [self setOpaque:NO];
     [self setBackgroundColor:[NSColor clearColor]];
   }

   return self;
}

- (BOOL)canBecomeKeyWindow
{
  return YES;
}

- (BOOL)canBecomeMainWindow
{
  return YES;
}

我的一切工作都完美无缺,包括拖动和调整大小,除了窗口不适用于 Spaces。通过键盘快捷键切换空间时按住窗口或拖动到窗口的底部/顶部/左侧/右侧,我无法将窗口移动到另一个空间。无论如何,是否有一个自定义窗口的行为与空间方面的普通窗口完全一样?

【问题讨论】:

标签: objective-c cocoa


【解决方案1】:

经过很长时间,我找到了解决这个烦人问题的方法。 确实[window setMovableByWindowBackground:YES];和我自己的大小调整方法冲突,窗口在颤抖,看起来很糟糕!

但是像下面这样覆盖鼠标事件方法解决了我的问题:)

- (void)mouseMoved:(NSEvent *)event
{
    //set movableByWindowBackground to YES **ONLY** when the mouse is on the title bar
    NSPoint mouseLocation = [event locationInWindow];
    if (NSPointInRect(mouseLocation, [titleBar frame])){
        [self setMovableByWindowBackground:YES];
    }else{
        [self setMovableByWindowBackground:NO];
    }

    //This is a good place to set the appropriate cursor too
}

- (void)mouseDown:(NSEvent *)event
{
    //Just in case there was no mouse movement before the click AND
    //is inside the title bar frame then setMovableByWindowBackground:YES
    NSPoint mouseLocation = [event locationInWindow];
    if (NSPointInRect(mouseLocation, [titleBar frame])){
        [self setMovableByWindowBackground:YES];
    }else if (NSPointInRect(mouseLocation, bottomRightResizingCornerRect)){
        [self doBottomRightResize:event];
    }//... do all other resizings here. There are 6 more in OSX 10.7!
}

- (void)mouseUp:(NSEvent *)event
{
    //movableByBackground must be set to YES **ONLY**
    //when the mouse is inside the titlebar.
    //Disable it here :)
    [self setMovableByWindowBackground:NO];
}

我所有的调整大小的方法都是从 mouseDown 开始的:

- (void)doBottomRightResize:(NSEvent *)event {
    //This is a good place to push the appropriate cursor

    NSRect r = [self frame];
    while ([event type] != NSLeftMouseUp) {
        event = [self nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask)];
        //do a little bit of maths and adjust rect r
        [self setFrame:r display:YES];
    }

    //This is a good place to pop the cursor :)

    //Dispatch unused NSLeftMouseUp event object
    if ([event type] == NSLeftMouseUp) {
        [self mouseUp:event];
    }
}

现在我有了自定义窗口,并且可以很好地使用 Spaces :)

【讨论】:

    【解决方案2】:

    这里有两件事。

    需要设置窗口允许背景拖动,[window setMovableByWindowBackground:YES];

    并且如果您希望可拖动的自定义窗口区域是自定义 NSView 子类,您必须覆盖方法 - (BOOL)mouseDownCanMoveWindow 以返回YES 在任何需要能够通过拖动来移动窗口的 NSView 子类中。

    【讨论】:

      【解决方案3】:

      您是否覆盖了 isMovable?
      Apple documentation 说,它改变了 Spaces 的行为:

      如果一个窗口返回 NO,这意味着它 只能在空格之间拖动 F8 模式,...

      另一种可能相关的方法: NSWindow setCollectionBehavior

      【讨论】:

      • 不幸的是,isMovable 没有效果,setCollectionBehavior 只允许我强制应用出现在所有空间上。我确实发现通过使用 setMovableByWindowBackground,一切都适用于 Spaces,但这会干扰我不想要的自定义拖动和调整代码大小。所以 setMovableByWindowBackground 必须做一些事情,使窗口能够在空间之间移动。
      猜你喜欢
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      • 2012-03-28
      • 2013-03-27
      • 2010-09-12
      相关资源
      最近更新 更多