Реализовать автоматическое скрытие Mac OS X Dock - PullRequest
2 голосов
/ 12 октября 2010

Я пытаюсь сделать серверный монитор в Objective-C, который ведет себя как док в OS X. Я надеюсь, что он будет скользить по краю экрана, когда мышь перемещается в сторонуэкрана, вроде как док, когда автоматическое скрытие включено.Я не уверен, с чего начать ..

Я предполагаю, что мне нужно окно с маской NSBorderlessWindowMask, но после этого я в растерянности.У меня только 1 пиксель этого окна отображается, и я жду события mouseOver, или это просто хакерское решение для чего-то, что можно сделать разумно?Как я могу проверить наличие события мыши, если это лучший способ сделать это?

1 Ответ

5 голосов
/ 12 октября 2010

Думаю, у вас правильная идея.Имейте в виду, однако, что в зависимости от того, что вы хотите сделать, окна без полей - не самая простая вещь для работы (они могут быть сложными, особенно со сложностями, которые могут добавить такие вещи, как Spaces и Exposé).

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

Если вы пойдете по пути «персонального проекта», вы можете оставить 1 пиксель на краю окна, показывая, используйтепользовательский подкласс NSView, который будет рисовать себя как прозрачный и настраивать NSTrackingArea, чтобы информировать вас о mouseEntered: events.

Чтобы нарисовать прозрачную область, вы можете сделать что-то подобное в drawRect:

- (void)drawRect:(NSRect)frame {
   [[NSColor clearColor] set];
   NSRectFill(frame);
}

Чтобы настроить область отслеживания, сделайте это в awakeFromNib в вашем подклассе представления:

- (void)awakeFromNib {
 NSTrackingArea *tracker = [[[NSTrackingArea alloc] initWithRect:[self frame]
   options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)
   owner:self
   userInfo:nil] autorelease];

 [self addTrackingArea:tracker];
}

- (void)mouseEntered:(NSEvent *)theEvent {
 [[[self window] windowController] showWindow:self];
}

- (void)mouseExited:(NSEvent *)theEvent {
 [[[self window] windowController] myHideMethodName:self];
}

Это предполагает, что вы переопределяете оконный контроллер showWindow: метод для создания анимации или чего-либо еще).Кстати, что бы вы ни делали, НЕ ищите события перемещения мыши.(В вашем случае это не имеет большого значения, так как ваша область, вероятно, будет очень маленькой, но в целом поиск перемещенных мышью событий - это неправильный способ сделать это, поскольку они могут быстро заполнить очередь событий. Используйте функцию области отслеживания вQuartz Debug, чтобы увидеть, как это делает большинство программ).Имейте в виду, что даже если представление может выглядеть прозрачным, оно все равно будет препятствовать тому, чтобы события мыши проходили к тому, что находится под ним (это может быть другое окно или рабочий стол и т. Д.).

Если вы хотитечтобы пройти «профессиональный» маршрут, вы должны быть в состоянии настроить «Отводы событий», чтобы в основном выполнить то же самое, что и код области отслеживания.С этим маршрутом вы можете полностью скрыть окно, чтобы оно не мешало чему-либо.Чтобы понять, как работают события, вы можете загрузить следующие 2 приложения:

http://brockerhoff.net/quay/

http://pfiddlesoft.com/eventtapstestbench/

Первое - это крутой пример того, как выможете использовать события, чтобы выполнить некоторые интересные вещи (прочитайте справку, чтобы увидеть некоторые дополнительные функции).Rainer использует события, чтобы коснуться Dock, чтобы понять, когда вы наводите курсор мыши над элементами в левой части Dock.Затем он может показать свои пользовательские меню вместо встроенных меню Dock.

Второе приложение будет незаменимо при изучении того, как и что Quay (или QuayMenu, действительно) делает со своими событиями.

Кстати, API отводов событий находится в Quartz (ниже приведен пример того, что вы бы использовали для настройки отводов событий):

CFMachPortRef CGEventTapCreate (
   CGEventTapLocation tap,
   CGEventTapPlacement place,
   CGEventTapOptions options,
   CGEventMask eventsOfInterest,
   CGEventTapCallBack callback,
   void *refcon
);

Я сам недостаточно знаю о отводах событийпривести пример того, как его настроить, но это должно, по крайней мере, указать вам правильное направление.

Надеюсь, это поможет ....

...