Как рисовать рабочий стол в Mac OS X?

Я хочу нарисовать рабочий стол на Mac OS X (Snow Leopard). В частности, я хочу добиться того же эффекта, что и при запуске:

/System/Library/Frameworks/ScreenSaver.framework/Resources/
ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background

(Если вы не рядом со своим компьютером, это отображает скринсейвер, где вы обычно видите фон рабочего стола.)

Я знаю, как сделать окно без рамки (путем подкласса NSWindow и переопределения initWithContentRect: styleMask: backing: defer: установить стиль окна в NSBorderlessWindowMask) и без тени (setHasShadow: NO.)

Я знаю, что я могу вызвать setLevel: kCGDesktopWindowLevel или kCGDesktopIconWindowLevel, чтобы поместить мое окно под другие окна (см. вопрос 418791.) Однако это не то, что я хочу, потому что окно на этом уровне все еще находится на вершине значков на рабочем столе. Я хочу быть на фоне рабочего стола, но ниже значков.

Мой взгляд непрозрачен. Если есть метод, который сжимает фон рабочего стола, это нормально.

Ответ 1

Вы должны создать подкласс NSWindow и установить уровень (kCGDesktopWindowLevel - 1). Это закроет ваше окно под значками. Вы также должны убедиться, что ваше окно не становится ключевым или основным и что оно правильно обрабатывает Exposé/Spaces, не перемещаясь.

- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
    self = [super initWithContentRect:contentRect styleMask:windowStyle backing:bufferingType defer:deferCreation];
    if(self)
    {
        [self setLevel:kCGDesktopWindowLevel - 1];
        [self setCollectionBehavior:
            (NSWindowCollectionBehaviorCanJoinAllSpaces | 
             NSWindowCollectionBehaviorStationary | 
             NSWindowCollectionBehaviorIgnoresCycle)];
    }
    return self;
}

- (BOOL)canBecomeMainWindow
{
    return false;
}

- (BOOL)canBecomeKeyWindow
{
    return false;
}

Ответ 2

Чтобы отобразить над рабочим столом, но ниже значков на рабочем столе, вам нужно сделать две вещи:

  • Вызовите [window setLevel:kCGDesktopWindowLevel], чтобы плавать под другими окнами приложений.
  • Вызовите [window orderBack:self] для слоя за окном, которое рисует значки на рабочем столе.

Что-то во время запуска приложения приносит приложение на передний план, поэтому вы должны вызвать orderBack: в вашем приложении делегируется applicationDidFinishLaunching: method.