Создание аплета Cinnamon

В сети
Аватара пользователя

Автор темы
di_mok
Сообщения: 2011
Зарегистрирован: 27 авг 2016, 16:06
Решено: 15
Откуда: Арзамас
Благодарил (а): 543 раза
Поблагодарили: 314 раз

Создание аплета Cinnamon

Сообщение di_mok » 06 фев 2017, 13:41

Вступление

В этом уроке, мы рассмотрим процесс создания простого аплета, для изучения Applet API. Здесь мы создадим Force Quit applet.

Для тех, кто не знаком с Force Quit: когда окно перестает отвечать и не хочет закрываться, самый эффективный способ его закрыть - убить его процесс. Вы можете использовать команду ps, чтобы найти ID процесса и убить его командой kill. Или же вы можете выполнить команду xkill и просто нажать на окно, которое вы хотите убить. И это именно то, что делает Force Quit applet. После того, как вы кликните на него, курсор мыши превращается в убийцу окна, которым вы выберете окно которое необходимо закрыть.

Создание базовой структуры аплета.

Аплет - это в основном каталог, имя которого будет uuid, содержащий два файла:

metadata.json - файл, который содержит информацию о приложении, такую как его название, описание и т.д..
В файле applet.js содержится код аплета.

Перейдём в ~/.local/share/cinnamon/applets (или в /usr/share/cinnamon/applets, если вы хотите, чтобы аплет был доступен для всех пользоватей) и создадим файлы и папки, необходимые для аплета.

Код: Выделить всё

cd
mkdir -p .local/share/cinnamon/applets/force-quit@cinnamon.org
cd .local/share/cinnamon/applets/force-quit@cinnamon.org
touch metadata.json
touch applet.js

Определение метаданных аплета.

Давайте откроем metadata.json и опишем наш аплет. Этот файл определяет идентификатор UUID, название, описание, значок аплета и используется Cinnamon для отображения его пользователям в настройках.

Код: Выделить всё

{
    "uuid": "force-quit@cinnamon.org",
    "name": "Force Quit",
    "description": "Click on the applet to launch xkill and force any window to quit immediately",
    "icon": "force-exit"
}

По умолчанию только один экземпляр каждого аплета может быть размещен на панели пользователя. Но если у пользователя несколько панелей, он не может иметь аплет force-quit на каждой панели, что очень плохо. Следовательно, мы должны также добавить max-instance экземпляра. Мы можем задать любое число (например, 3), или сделать его неограниченным, сделав его -1. В этом случае, наш новый metadata.json будет:

Код: Выделить всё

{
    "uuid": "force-quit@cinnamon.org",
    "name": "Force Quit",
    "description": "Click on the applet to launch xkill and force any window to quit immediately",
    "icon": "force-exit",
    "max-instances": "-1"
}

Пишем аплет


Это код нашего аплета

Код: Выделить всё

        const Applet = imports.ui.applet;
        const Util = imports.misc.util;

        function MyApplet(orientation, panel_height, instance_id) {
            this._init(orientation, panel_height, instance_id);
        }

        MyApplet.prototype = {
            __proto__: Applet.IconApplet.prototype,

            _init: function(orientation, panel_height, instance_id) {
                Applet.IconApplet.prototype._init.call(this, orientation, panel_height, instance_id);

                this.set_applet_icon_name("force-exit");
                this.set_applet_tooltip(_("Click here to kill a window"));
            },

            on_applet_clicked: function() {
                Util.spawn('xkill');
            }
        };

        function main(metadata, orientation, panel_height, instance_id) {
            return new MyApplet(orientation, panel_height, instance_id);
        }
      
Теперь рассмотрим код построчно, начиная с нижней части.

Код: Выделить всё

        function main(metadata, orientation, panel_height, instance_id) {
            return new MyApplet(orientation, panel_height, instance_id);
        }

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

Вы заметите, что есть много параметров, плавающие вокруг metadata содержат, в основном, информацию в metadata.json плюс еще немного. От этого мало пользы в целом, но иногда может предоставить некоторую нужную информацию.

orientation - где находится панель, в верхней или нижней части. Аплет может вести себя по-разному в зависимости от его позиции, например. чтобы сделать всплывающее меню появляещееся на правой стороне.

panel_height сообщает высоту панели. Таким образом, мы можем масштабировать иконки вверх и вниз в зависимости от того, насколько большая группа.

instance_id говорит, какой это экземпляр аплета, так как там может быть несколько экземпляров аплета. Пока это просто номер, присвоенный аплету и не имеет особого смысла.

Здесь мы передаем информацию в конструктор, и конструктор будет позже передать его в API аплета.

Так что же происходит, когда мы создаем аплет? Сначала посмотрим на первые две строки:

Код: Выделить всё

        const Applet = imports.ui.applet;
        const Util = imports.misc.util;
Здесь мы импортируем определенния API, предоставляемые Cinnamon. Наиболее важным из них является, конечно, API-интерфейс аплета. Нам также потребуется Util для запуска внешней программы (xkill). Когда мы пишем imports.ui.applet, мы вызываем функции определенные в /usr/share/cinnamon/js/ui/applet.js. Аналогично, imports.misc.util доступна в /usr/share/cinnamon/js/misc/util.js. Затем мы называем эти вещи Applet и Util соответственно, чтобы не набирать кучу кода.

Ничего интересного. Далее!

Код: Выделить всё

        function MyApplet(orientation, panel_height, instance_id) {
            this._init(orientation, panel_height, instance_id);
        }


Это стандартная конструкция объекта JavaScript. Когда кто-то делает этот вызов, он вызывает функцию _init объекта. Обратите внимание, что здесь мы назвали наш аплет MyApplet. Вы вольны называть его как угодно (и измененить функцию main соответственно).

Также отметим, что мы передаем все orientation по цепочке, пока она в конечном счете достигнет API для аплетов.

Теперь мы переходим к телу кода:

Код: Выделить всё

        MyApplet.prototype = {
            __proto__: Applet.IconApplet.prototype,

            _init: function(orientation, panel_height, instance_id) {
                Applet.IconApplet.prototype._init.call(this, orientation, panel_height, instance_id);

                this.set_applet_icon_name("force-exit");
                this.set_applet_tooltip(_("Click here to kill a window"));
            },

            on_applet_clicked: function() {
                Util.spawn('xkill');
            }
        };
Грубо говоря, prototype - это список всех функций объекта. Здесь мы имеем функцию _init и функции on_applet_clicked, это всё, что нам нужно.

Здесь мы видим то, что я называют "API-интерфейс аплета" все время. Несколько основных объектов определяются в applet.js и мы наследуем один из них. Здесь мы объявляем наследование Applet.IconApplet, который отображает значок.

Наследование в JavaScript немного странные. Сначала мы копируем Applet.IconApplet с помощью:

Код: Выделить всё

        __proto__: Applet.IconApplet.prototype,
Эта строка копирует все функции, найденные в Applet.IconApplet в наш аплет, который мы собираемся использовать.

Далее, в нашей функции _init, мы вызываем _init функцию Applet.IconApplet. Здесь мы передаем всю информацию об ориентации и т.д. для функции _init, и эта функция необходима для отображения аплета правильно.

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

Код: Выделить всё

        this.set_applet_icon_name("force-exit");
Обратите внимание, что set_applet_icon_name - это функция определенная внутри Applet.IconApplet, что позволяет аплету отображать соответствующий значок. С помощью API аплета, мы спасли себя от хлопот создания иконок и разместив их в нужном месте. (force-exit имя значка из пользователя набор иконок. Иконки доступные для использования можно найти в /usr/share/icons/).

Следующая строка:

Код: Выделить всё

        this.set_applet_tooltip(_("Click here to kill a window"));
говорит о том, что аплет должен иметь всплывающую подсказку с названием _("Click here to kill a window"). Обернув строку в _( ), мы сообщаем Cinnamon, о переводе строки в на текущий язык, если перевод не доступен.

Это весь код нашей функции _init. Теперь мы будем ждать когда пользователь кликнет на аплет. API-интерфейс аплета автоматически слушает эти события, и когда пользователь нажимает на аплет, то API будет вызывать on_applet_clicked вашего аплета. Здесь мы имеем:

Код: Выделить всё

        on_applet_clicked: function() {
            Util.spawn('xkill');
        }
вызов spawn функции из Util, и запуск внешней команды xkill

Перевод статьи с Mint Developer Center
Настоящая водка — это не пьянство, а ключ к своей совести, с нее-то и начинается настоящая мудрость. (c)

Аватара пользователя

zuzabrik
Сообщения: 759
Зарегистрирован: 29 авг 2016, 09:08
Решено: 15
Благодарил (а): 48 раз
Поблагодарили: 221 раз

Создание аплета Cinnamon

Сообщение zuzabrik » 07 фев 2017, 02:22

Думаю стоит это перенести в раздел Руководства.
Имею желание иметь всех желающих, но не имею желающих.

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 07 фев 2017, 10:24

di_mok писал(а): ... рассмотрим процесс создания простого аплета, для изучения Applet API...
немного уже знаком с потрохами циннамоновских апплетов , но всёж интересная тема и есть вопросы
di_mok писал(а): По умолчанию только один экземпляр каждого аплета может быть размещен на панели пользователя. Но если у пользователя несколько панелей, он не может иметь аплет force-quit на каждой панели, что очень плохо.
ну да... есть такое дело
di_mok писал(а): ....Следовательно, мы должны также добавить max-instance экземпляра. Мы можем задать любое число (например, 3), или сделать его неограниченным, сделав его -1.
а вот тут звиняйте не понял ...
это для чего и почему следовательно?
если max-instance дать значение -1 то что? - апплет можно будет, не как по умолчанию всего на усевозможные панели поставить , а без ограничениев? и каким же образом?
или это значение определяет на сколько пользователей его могут использовать если апплет установлен в /usr/share/cinnamon/applets , а не в дом каталоге ?

Ну а то что "По умолчанию только один экземпляр каждого аплета может быть размещен на панели пользователя" довольно легко можно обойти , и поставить несколько одинаковых апплетов
111.png
Вопрос только - а зачем куча одинаковых апплетов , пусть даже на разных панелях.
:hm: а в прочем ... не так давно на форуме показывал установленное на панель 4 раза быстрое меню - QuickMenu

ЗЫ
кстати , чегой-то апплет ни этот , что для примеру разбирали, ни скачанный с оффсайту не работают на минт18.1 , и в каментах на сайте с апплетами жалобы были что минт17 не работает. Есть ещё экземпляр какойто на гитхабе ... но не пробовал.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось пользователем 1 colonel; всего редактировалось раз: 7
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

Аватара пользователя

zuzabrik
Сообщения: 759
Зарегистрирован: 29 авг 2016, 09:08
Решено: 15
Благодарил (а): 48 раз
Поблагодарили: 221 раз

Создание аплета Cinnamon

Сообщение zuzabrik » 07 фев 2017, 10:34

colonel писал(а): если max-instance дать значение -1 то что?
То можно будет запустить больше одного экземпляра аплета. Простой пример - стикеры на раб. столе. Если стоит 1 - стикер может быть только один. Если -1, то можете хоть весь раб стол имы обгадить.
Имею желание иметь всех желающих, но не имею желающих.

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 07 фев 2017, 10:53

zuzabrik писал(а): о можно будет запустить больше одного экземпляра аплета.
вот нахрена из апплета больше одного экземпляра корзины на столе запускать или обновлятора ... или календаря или настроек ...
zuzabrik писал(а): Простой пример - стикеры на раб. столе.
это с чем ещё едят?
точное название апплета назвать можете ?.. или показать на картинке...
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

Аватара пользователя

zuzabrik
Сообщения: 759
Зарегистрирован: 29 авг 2016, 09:08
Решено: 15
Благодарил (а): 48 раз
Поблагодарили: 221 раз

Создание аплета Cinnamon

Сообщение zuzabrik » 07 фев 2017, 11:03

colonel писал(а): это с чем ещё едят?
точное название апплета назвать можете ?.. или показать на картинке...
StickyNotes в аплетах найди, поставь в настройках multiple instance и создай несколько заметок.

Кратко - это как отрывные бумажки с короткими записками, которые лепят на холодильник, стену, или края монитора )
Имею желание иметь всех желающих, но не имею желающих.

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 07 фев 2017, 11:16

zuzabrik писал(а): StickyNotes ....
понятно... не пользуюсь таковыми...
zuzabrik писал(а): отрывные бумажки с короткими записками, которые лепят на холодильник, стену, или края монитора
и чего только людине придумают чтобы загадить рабочий стол.
найдут обоину красивую, прицепят какие десклеты красиво -часики, погоду , фоторамку.... , сделают красиво индикаторы на стол со всё фигнё что в компе крутится - от загрузки инета до температуры стула нпо задницей ...
а потом как наставят поверх этой красоты красивых иконок-ярлычков на пол стола, папочек накидают для быстрого доступа а ещё оказывается можно и записок-памяток сверху добавть ...
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

Аватара пользователя

zuzabrik
Сообщения: 759
Зарегистрирован: 29 авг 2016, 09:08
Решено: 15
Благодарил (а): 48 раз
Поблагодарили: 221 раз

Создание аплета Cinnamon

Сообщение zuzabrik » 07 фев 2017, 11:21

colonel писал(а): записок-памяток сверху добавть ...
Ну вот прикинь я пользуюсь. если мне надо быстро записать что-то на время, чтобы не забыть,

Хотя что я тебе объясняю, ты как старый брюзга в каждой ветке чем то недоволен :-D Стикеры один из примеров, зачем еще может понадобится несколько копий одного приложения можешь сам придумать.
Имею желание иметь всех желающих, но не имею желающих.

В сети
Аватара пользователя

Автор темы
di_mok
Сообщения: 2011
Зарегистрирован: 27 авг 2016, 16:06
Решено: 15
Откуда: Арзамас
Благодарил (а): 543 раза
Поблагодарили: 314 раз

Создание аплета Cinnamon

Сообщение di_mok » 07 фев 2017, 13:02

colonel писал(а): Вопрос только - а зачем куча одинаковых апплетов , пусть даже на разных панелях.
Вопрос, скорее риторический. Я тоже не представляю для чего нужно несколько копий аплета. Вариант с липкими заметками слегка притянут. Это же не аплет, а расширение
Настоящая водка — это не пьянство, а ключ к своей совести, с нее-то и начинается настоящая мудрость. (c)

В сети
Аватара пользователя

Chocobo
Сообщения: 5114
Зарегистрирован: 27 авг 2016, 19:57
Решено: 122
Откуда: НН
Благодарил (а): 384 раза
Поблагодарили: 1330 раз

Создание аплета Cinnamon

Сообщение Chocobo » 07 фев 2017, 13:06

А терминологию можно уточнить? Апплеты, десклеты, расширения, чего там еще есть...

Апплеты наверное те что на панели :scratch:

В сети
Аватара пользователя

Автор темы
di_mok
Сообщения: 2011
Зарегистрирован: 27 авг 2016, 16:06
Решено: 15
Откуда: Арзамас
Благодарил (а): 543 раза
Поблагодарили: 314 раз

Создание аплета Cinnamon

Сообщение di_mok » 07 фев 2017, 13:08

Chocobo писал(а): Апплеты наверное те что на панели
Ну да.

Ой, оговорился. Липкие заметки - десклет.
Chocobo писал(а): А терминологию можно уточнить?
Тут же всё просто: аплет в панели, десклет на столе, расширение - некий функционал.

А вот в Гноме всё называется расширениями
Настоящая водка — это не пьянство, а ключ к своей совести, с нее-то и начинается настоящая мудрость. (c)

Аватара пользователя

zuzabrik
Сообщения: 759
Зарегистрирован: 29 авг 2016, 09:08
Решено: 15
Благодарил (а): 48 раз
Поблагодарили: 221 раз

Создание аплета Cinnamon

Сообщение zuzabrik » 07 фев 2017, 15:14

di_mok писал(а): Вариант с липкими заметками слегка притянут. Это же не аплет, а расширение
это десклет. отличается от того что в уроке лишь названием и базовым классом. пишется аналогично через js и json файлы с указанием кол-ва возможных копий в частности.

нужен пример конкретно для панели с множеством копий? Горячо любимые Dja полочки - когда один аплет это куча ярлыков запиханых в один бокс. каждый такой бокс с ярлыками это отдельный инст аплета. Еще нужны примеры? Разделители на панели к примеру.
Имею желание иметь всех желающих, но не имею желающих.

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 08 фев 2017, 10:52

di_mok писал(а): Вопрос, скорее риторический. Я тоже не представляю для чего нужно несколько копий аплета. Вариант с липкими заметками слегка притянут. Это же не аплет, а расширение
иногда всёж надо бы, пример с быстрым меню приводил - там и 5 быстороменю не помешает, в них же разное наполнение. А вот нафига для "force-exit" запускающего xkill параметр "max-instances": "-1" , который должны следовательно также добавить ... непонятно. Какбе клацнув по апплету один раз получаем крестик вместо курсора мышки , и этим крестиком надо клацнуть по тому что надо "убить". Чего мы убъём клацнув ещё раз по этому апплету? и зачем такой параметр нужен.
Последний раз редактировалось пользователем 1 colonel; всего редактировалось раз: 8
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 08 фев 2017, 11:03

аплет в панели, десклет на столе, расширение - некий функционал.
А вот в Гноме всё называется расширениями
с каких это пор апплет в гноме(мате) стал называться исключительно расширением и можно подумать что в гномах не было понятия gДесклетс и особо Скринлетсов нт и не было.
Последний раз редактировалось пользователем 1 colonel; всего редактировалось раз: 8
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

В сети
Аватара пользователя

Автор темы
di_mok
Сообщения: 2011
Зарегистрирован: 27 авг 2016, 16:06
Решено: 15
Откуда: Арзамас
Благодарил (а): 543 раза
Поблагодарили: 314 раз

Создание аплета Cinnamon

Сообщение di_mok » 08 фев 2017, 11:15

Ну это же просто пример создания, во первых, а во вторых вопрос скорее автору.
Настоящая водка — это не пьянство, а ключ к своей совести, с нее-то и начинается настоящая мудрость. (c)

В сети
Аватара пользователя

Chocobo
Сообщения: 5114
Зарегистрирован: 27 авг 2016, 19:57
Решено: 122
Откуда: НН
Благодарил (а): 384 раза
Поблагодарили: 1330 раз

Создание аплета Cinnamon

Сообщение Chocobo » 08 фев 2017, 11:22

Util.spawn() является общим методом внешнего вызова в api корицы?
Т.е. начинать кастомить апплет не усложняя пока логику с простой подмены вызова стоит похоже начинать отсюда

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 08 фев 2017, 11:45

di_mok писал(а): Ну это же просто пример создания, во первых, а во вторых вопрос скорее автору.
автору авторово... и вопрос конечно не к вам
...
зы
внезапно..
Не по теме
тут не так давно на форуме спрашивали про самоочистку корзины
...таки нашлось чегото
Mate-Screenlets-trash .png
У вас нет необходимых прав для просмотра вложений в этом сообщении.
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

В сети
Аватара пользователя

Автор темы
di_mok
Сообщения: 2011
Зарегистрирован: 27 авг 2016, 16:06
Решено: 15
Откуда: Арзамас
Благодарил (а): 543 раза
Поблагодарили: 314 раз

Создание аплета Cinnamon

Сообщение di_mok » 08 фев 2017, 14:44

Chocobo писал(а): является общим методом внешнего вызова в api корицы?
Ну, собственно - да
This file includes certain useful utility functions such as running external commands.
http://developer.linuxmint.com/referenc ... -util.html
Настоящая водка — это не пьянство, а ключ к своей совести, с нее-то и начинается настоящая мудрость. (c)

Аватара пользователя

zuzabrik
Сообщения: 759
Зарегистрирован: 29 авг 2016, 09:08
Решено: 15
Благодарил (а): 48 раз
Поблагодарили: 221 раз

Создание аплета Cinnamon

Сообщение zuzabrik » 08 фев 2017, 17:37

colonel писал(а): А вот нафига для "force-exit" запускающего xkill параметр "max-instances": "-1"
Это учебный пример показывающий каркас аплета. По сути минимально необходимое для его работы.

Касательно вопроса нафига... а почему нет то? Ну хочет пользователь 2 кнопки xkill, кто мы чтоб запрещать это делать? :-D Может ему одну в левом углу другую в правом удобно держать... Душа пользователя загадка.
Имею желание иметь всех желающих, но не имею желающих.

Аватара пользователя

colonel
Сообщения: 349
Зарегистрирован: 18 дек 2016, 09:08
Решено: 10
Благодарил (а): 14 раз
Поблагодарили: 101 раз

Создание аплета Cinnamon

Сообщение colonel » 09 фев 2017, 15:24

Создание аплета Cinnamon (Пост zuzabrik #10045)
zuzabrik писал(а): Ну хочет пользователь 2 кнопки xkill...
zuzabrik писал(а): > если max-instance дать значение -1 то что?
То можно будет запустить больше одного экземпляра аплета.
так `gnbnm
этот параметр ограничивает\разрешает количество запусков с кнопки апплета или количество устанавливаемых кнопок?
Если количество кнопок, то попробуйте разрешив этим параметром хоть мульён экземпляров поставить какой либо апплет хоть на одну панель два раза , хоть на две панели и покажите как это у вас получилось. (вот только про разделитель не приводите в пример )

Насчёт
zuzabrik писал(а): зачем еще может понадобится несколько копий одного приложения можешь сам придумать.
zuzabrik писал(а): нужен пример конкретно для панели с множеством копий? Горячо любимые Dja полочки - когда один аплет это куча ярлыков запиханых в один бокс. каждый такой бокс с ярлыками это отдельный инст аплета ...
представьте себе не только придумал, даже написал даже ещё в сообщении #3 07 фев , и мало того сделал и могу показать на панели 3-4 или сколько душе потребуется экземпляров "БыстроМеню". Впрочем аналогично и апплет убийства процессов в 3-х экземплярах без особых проблем запихал на панели , но параметр max-instance тут нипричём

Вопрос же возник исключительно по тому что было сказано - "Следовательно, мы должны также добавить max-instance экземпляра" да ещё со значением без ограничений.
Понимаю что "просто пример создания" - но блин... но вы то что заелозили ? афтар не вы не вам и претензии о дурацком в примерах.
zuzabrik писал(а): ...ты как старый брюзга в каждой ветке чем то недоволен...
"...заслуживают всегда глупости высказанные брюзжанья старческого " (с) известного мысль джедая невысказанная :blum:
"Не ты выбираешь Linux, а Linux выбирает тебя"
(с)Себастьян Перейра, торговец чёрным деревом

Вернуться в «Руководства»