有没有办法使自定义NSWindow与Spaces一起工作

时间:2009-11-07 22:00:50

标签: objective-c cocoa

我正在编写一个应用程序,它具有使用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一起使用。我不能通过按住窗口同时通过键盘快捷键切换空格,或者拖动到窗口的底部/顶部/左/右来将窗口移动到另一个空间。无论如何,自定义窗口的行为与Spaces的正常窗口完全相同吗?

3 个答案:

答案 0 :(得分:6)

很长一段时间后,我找到了解决这个烦人问题的方法。 确实[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:)

答案 1 :(得分:1)

这里有两件事。

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

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

答案 2 :(得分:0)

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

  

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

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