2009-10-07 2 views
4

У меня есть подкласс NSBorderlessWindow NSWindow с прозрачным и непрозрачным фоном (поэтому он не прямоугольный по внешнему виду). Я добавил свои собственные кнопки, чтобы функционировать как кнопки закрытия и сворачивания, когда я нажимаю на них, но по какой-то причине окно не будет реагировать на CMD-W или CMD-M, как обычно. У меня есть набор подклассов NSWindow для возврата YES в canBecomeKeyWindow и canBecomeMainWindow.NSBorderlessWindow не отвечает на CMD-W/CMD-M

У моего NIB все еще есть все стандартные элементы меню, которые есть, когда вы создаете новый проект, включая элемент «Свернуть» в меню «Окно» с установленным по умолчанию ярлыком CMD-M. Он подключен, чтобы отправить performMiniaturize: первому ответчику. Однако он не включен, когда приложение запущено, поэтому кажется, что он должен запрашивать окно, если он может свести к минимуму, а окно говорит «нет» или что-то в этом роде. (Я все еще очень новичок в OSX/Cocoa.)

Что мне не хватает?

Кроме того, возможно, это связано с тем, что мое окно без полей имеет включенную тень, но в отличие от обычного озаглавленного окна, когда я делаю свое окно активным/передним окном, нажимая на него, тень не изменяется. Обычно окно, ориентированное на OSX, имеет немного большую/более темную тень, чтобы выделять ее больше, но моя никогда не меняет тень. Это похоже на то, что я что-то упустил, чтобы ОС рассматривала это окно как реальное/нормальное/главное окно или что-то еще, и в результате я теряю теневое изменение и работу CMD-W/CMD-M.

+0

Я думаю, если вы измените селектор от -performMiniaturize: до -miniaturize: вы получите то, что хотите. -performMiniaturize: не просто отправляет окно на док-станцию, но также мгновенно выделяет кнопку миниатюры. Возможно, это то, что тебя подвешивает. – NSResponder

+0

Вы не должны использовать префикс NS. Это префикс Apple для своих классов в Foundation, AppKit и Core Data. Если Apple когда-либо добавит класс NSBorderlessWindow, даже частный, их класс и ваш будут конфликтовать. Составьте свой префикс и используйте его. –

+0

Peter: Класс не называется NSBorderlessWindow, это NSWindow, созданный с использованием флага NSBorderlessWindowMask. Я признаю, что это было сформулировано плохо. :) – Sean

ответ

3

Вам не хватает того, что при создании окна без полей вы удаляете FrameView, в который входят стандартные окна, которые фактически реализуют метод -keyDown:, который получает эти нажатия клавиш и миниатюризирует или закрывает окно.

NSWindow сам по себе является довольно легким классом, и большинство из того, что мы считаем стандартным поведением окна, выполняется с помощью рамочного представления.

+0

И NSFrameView недокументирован, не так ли? ARG! Даже если я перехватил события или нажатия клавиш в моем окне, чтобы сделать это, что контролирует пункт меню в элементе меню окна из включения/выключения? Там где-то должно быть много волшебства. – Sean

+0

Никакая магия, только цепочка ответчиков. Проверьте документы Apple для описания того, как элементы меню проверяются.В двух словах для каждого пункта меню запрашивается его цель, чтобы увидеть, реагирует ли она на селектор действий меню. Если целью является firstResponder, то он будет перемещаться по цепочке ответчиков, ища все, что реализует данный метод. – NSResponder

+0

В этом случае, не следует ли включать пункт меню? NSWindow сам реагирует на performMiniaturize: это то, к чему подключен элемент меню (по крайней мере). Разве это не первый ответчик или нет в цепи или что-то еще? Почему бы и нет? Я добавил acceptsFirstResponder в свой подкласс NSWindow и вернул YES, чтобы быть уверенным, но он все равно не работает. – Sean

1

Возможно, вы удалили пункт меню «Файл»> «Закрыть»?

По умолчанию это имеет комбинацию клавиш быстрого доступа Cmd-W и подключена к цели в первом ответчике.

Мы исправили это, перетащив стандартное меню «Файл» на панели «Библиотека» в «Интерфейсостроителе».

0

Сначала я попробовал реализовать keyDown: за предложение NSResponder, но это не помогло.

Я решил это, просто создав свои собственные IBActions для Close и Minimize. Обратите внимание, что вы хотите позвонить close и miniaturize: на свой NSBorderlessWindow, а не performClose: или performMiniaturize:.

Смежные вопросы