Сложности с отображением иконок рабочего стола

от автора


Последние три недели я работал над рефакторингом и исправлением легаси-кода (самые старые части которого были написаны в 2013 году), отвечающего за позиционирование иконок в KDE Plasma, а также сохранение и загрузку этих данных.

Вот мой запрос на внесение изменений: plasma-desktop: Refactor icon positioner saving and loading.

Имевшийся код работал, но происходили всякие странности типа состояний гонки, когда иконки вдруг располагались в необычном порядке, плюс частично перемешался код фронтенда и бэкенда.

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

Бывало у вас такое, что провода наушников спутываются, когда вы убираете их в шкаф или кладёте ненадолго в карман? И с базами кода происходит нечто похожее, когда множество людей записывают в них изменения, исправляя баги друг друга. Каждый мыслит по-своему, поэтому вполне естественно, что всё со временем запутывается.

В итоге периодически кому-то нужно разгребать такую запутанную базу кода и подчищать её.

▍ Самое сложное — это чтение кода

Читая старый код, особенно такой, где комментарии делались редко, бывает очень непросто понять, что в нём происходит. Честно говоря, бо́льшую часть времени я пытался разобраться, как он вообще работает, что и когда вызывается, где обновляется расположение иконок и так далее.

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

▍ Экраны и иконки

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

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

Вполне разумно. Зачем отображать иконки на экране, которого нет? Но когда ваш монитор при переходе ПК в режим сна вслед за ним отключается, начинают происходить неправильные вещи.

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

▍ Полосы и разрешение экрана

В нашем алгоритме позиционирования иконок используются некие «stripe» (полосы).

У каждого разрешения есть своё количество таких полос. В свою очередь, полосы содержат массив иконок или пустых участков.

Поэтому, если разрешение вашего экрана, скажем, 1920х1080, то мы вычисляем, сколько полос он содержит, и сколько элементов на каждую полосу вместится.

Stripe1: 1 2 3 4 5 6 7 Stripe2: 1 2 3 4 5 6 7 Stripe3: 1 2 3 4 5 6 7  И так далее..

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

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

После этого, когда экран снова включался, алгоритм недоумевал, что происходит, и восстанавливал подобающее число и размер полос. Вот только к тому моменту все прежние данные позиционирования уже были потеряны, и расположение иконок обновлялось. У пользователя в этот момент тоже возникало недоумение, почему иконки вдруг переместились.

В этом случае нам снова нужно проверять, используется ли экран. Но есть и другие проблемы.

▍ Сохранение позиций иконок

Прежний код сохранял позиции иконок при каждом их изменении. Разумно.

Но в нём не учитывался сценарий с выключением экрана… и в итоге позиции иконок сохранялись, пока рабочий стол находился в своём неестественном состоянии. Это тоже может раздражать, поскольку некоторые люди располагают иконки по-своему, а после очередного выкрутаса экрана они снова оказываются не в тех местах.

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

Пришлось разделить действия пользователя и системы. Если иконки сохраняет компьютер, в идеале нам не нужно сохранять их позиции, если только не случится нечто радикальное вроде изменения разрешения.

Позиции иконок сохраняются в соответствии с разрешением, поэтому если вы меняете их расположение на экране 3440х1440, а затем переключаете его разрешение на 1920х1080, то их позиции тоже изменятся. Ранее эта часть кодовой базы не работала, и постоянно перезаписывалась старая конфигурация, создавая головную боль.

Поэтому теперь мы сохраняем позиции иконок, только когда пользователь:

  • добавляет иконку или удаляет,
  • перемещает иконку,
  • изменяет разрешение экрана.

Это значительно снижает непредсказуемость расположения иконок, так как сохранение их позиций происходит только после явных действий пользователя.

▍ Ошибки отступов

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

В прежнем коде это вызывало смещение иконок с обновлением их позиций и последующим сохранением этих позиций.

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

Эта проблема уже была частично исправлена исключением сохранения позиций иконок при их перемещении системой: мы просто загружаем позиции иконок, когда экран используется, на чём их позиционирование на рабочем столе заканчивается. Часть изменений отступов происходит при отключённом экране.

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

▍ Заключение

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

К счастью, благодаря активной помощи ревьюеров и тестировщиков, я смог значительно оптимизировать работу этого механизма. Когда я берусь решать какую-то проблему, то кропотливо вникаю во все детали, поэтому очень ценю терпение, которое они проявили ко мне и моим вопросам 😀

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

Надеюсь, что после всех этих изменений иконки рабочего стола будут работать стабильнее. Если же вы заметите какие-то баги, пишите на https://bugs.kde.org.

Спасибо за чтение! 🙂

PS. Самое забавное в этой истории, что лично я предпочитаю, когда на рабочем столе вообще нет иконок :’D

Telegram-канал со скидками, розыгрышами призов и новостями IT 💻


ссылка на оригинал статьи https://habr.com/ru/articles/858598/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *