четверг, 2 июня 2011 г.

Почему бы оконному менеджеру просто не взять на себя некоторые действия, которые раньше выполнялись приложениями?

Это перевод Why doesn't the window manager just take over behavior that used to be within the application's purview? Автор: Реймонд Чен.

Комментатор Al интересуется почему менеджер окон не может просто взять на себя ответственность, которая принадлежала приложению (вроде перерисовывания неклиентской области), чтобы избежать проблем с задержкой ответа приложений. Если оконный менеджер переписать, то, возможно, он мог бы так делать. Но тогда это принесёт много новых проблем совместимости.

Во-первых, существует много приложений, которые имеют неявные зависимости на порядок сообщений или приём определённых типов сообщений в заданное время, даже хотя нет никакой официальной гарантии в спецификации, что эти сообщения будут доставлены и именно в таком порядке. К примеру, есть куча приложений, которые рассчитывают на приход сообщения WM_PAINT при отсутствии области для рисования - потому что они откладывают важные вычисления до момента первого прихода сообщения WM_PAINT. Соответственно, если что-то, что требует результата этих вычислений, будет запущено до первого сообщения WM_PAINT, то приложение вылетит. К примеру, если вы запустите программу в свёрнутом виде, затем щёлкните правой кнопкой по окну программу в панели задаче - такие программы вылетают, потому что код, который управляет у них системным меню, использует указатель, который инициализируется в обработчике сообщения WM_PAINT, либо же происходит деление на ноль - т.к. значение переменной не было вычислено во время обработки WM_PAINT. Чтобы позволить работать таким программам, менеджеру окон приходится рассылать фальшивое сообщение WM_PAINT (dummy) с пустым rcPaint. Если вы в первый раз увидите такое сообщение в программах вроде Spy++, то вам может показаться, что оно ничего не делает. Но теперь вы знаете, что тут цель не в самом сообщении, а в том, что оно вообще приходит - и позволяет программам обработать сообщение WM_PAINT и счастливо выполнять любые операции, которые зависят от результата обработки первого WM_PAINT.

Во-вторых, удаление возможности менять внешний вид сообщениями поставит препятствие для программ, которые изменяют свой внешний вид не стандартным способом. Думаю, что медиа-проигрыватели являются самым популярным примером программ, которые хотят аннулировать обычную неклиентскую прорисовку, чтобы показать полностью кастомизированное окно. Вам бы понравилось, если бы новая версия Windows означала бы, что вы больше не можете использовать обложки ("скины") в вашем любимом медиа-проигрывателе?

Как уже было сказано, в менеджере окон за все эти годы были сделаны изменения, чтобы поддерживать этот "дух изменяемости", одновременно вводя вещи, удобные для пользователя. К примеру, если окно длительное время не отвечает на перерисовку, то Windows берёт эту функцию на себя - рисуя стандартный заголовок окна (даже если приложение рисует свой нестандартный заголовок), так что пользователь хотя и не увидит родной "скин" приложения, но увидит хотя бы что-то.

Другой пример этой "виртуализации сообщений" - это добавление фразы "(Не отвечает)" к заголовку окна, которое перестало отвечать, и сохранение последнего удачного перерисованного содержимого окна, рисуя это сохранённое содержание с затенением, пока приложение не очнётся и не продолжит обработку перерисовки. Windows даже позволяет теперь перемещение, изменение размеров, сворачивание и максимизацию "замороженных" окон. Инфраструктура, необходимая для реализации всего этого поведения, довольно дорогостоящая, потому что оконному менеджеру нужно хранить два набора информации. Первый набор: "Что приложения думают о состоянии окна"; если приложение спросит о размере зависшего окна, то ему нужно ответить: "Ах, да, это окно имеет тот же размер, что и раньше, когда его создали, не волнуйся", даже хотя реальный размер на экране мог значительно измениться. Как только зависшее окно снова начнёт прокачку сообщений, все действия, которые произошли за время, пока окно висело, будут "проиграны" заново, чтобы окно "догнало" текущее состояние вещей. При этом могут происходить любопытные вещи, если приложение хочет кастомизировать одно из действий, которые происходят с "виртуальным окном". К примеру, приложение может хотеть отказать в изменении размеров окна до определённого размера или показать сообщение до сворачивания окна. Разрешение подобных конфликтов способом, которые не приводил бы к вылету существующих уже написанных приложений, является ещё одной из тех сложностей процесса согласования виртуального и реального состояний окон.

Поэтому, в этом смысле оконный менеджер действительно берёт на себя часть ответственностей приложения, но делает это настолько деликатным способом, чтобы ни само приложение, ни пользователь не сообразили бы, что происходит. И именно это делает такие вещи очень сложными.

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.