neděle 3. listopadu 2013

Jak funguje GNOME Shell a jeho rozšíření

GNOME Shell sám o sobě neoplývá mnoha nastaveními, která by si mohl uživatel jednoduše naklikat, na druhou stranu je navržen tak, že ho lze změnit k nepoznání trochou skriptování. Na jakém principu GS a jeho rozšíření fungují trochu naťuknu a přidám pár tipů pro zájemce o vlastní tvorbu. ...


Základ

Uživatelské rozhraní GNOME Shell stojí na několika knihovnách napsaných v C, jejichž schopnosti do konečného výsledku formuje sada skriptů v jazyce JavaScript, které doplňují CSS styly. Začnu tedy knihovnami:

Shell - základ GS. Zajišťuje například i sledování aplikací v kontextu jejich používání a zobrazovaných oken, interface pro vyhledávání, nebo také nahrávání desktopu do videa. Rozšíření má také vždy k dispozici globální proměnnou global, která je referencí na objekt vrácený Shell.Global.get() (viz ui skript environment.js). Přes global se dostanete k základním součástem desktopu, jako je obrazovka, kurzor myši, nastavení GSettings, ...

Clutter - grafická knihovna využívající OpenGL|ES, navržena byla pro tvorbu rychlých a přenositelných grafických uživatelských rozhraní. Clutter nedefinuje konkrétní styl UI, funguje na nižší úrovni a zprostředkovává API pro využití OpenGL|ES. Společně s Gst (GStreamer) umí i přehrávat média.

St - neboli Shell toolkit, je založený na Clutter a ten již formuje podobu prvků UI, ve formě konkrétních widgetů jako jsou tlačítka, apod.

Tweener - statická třída, která umí animace a různé přechody. Ačkoliv Clutter již animovat umí také, v době kdy GS vznikal tomu tak nebylo a navíc je práce s Tweener údajně jednodušší, takže se stále drží. V ui modulech GS je k němu wrapper (tweener.js), který ho integruje s Clutter.

Mutter (Meta) - kompozitní správce oken nahrazující Metacity, který využívá renderovacích schopností Clutter. Jméno vzniklo spojením jmen Metacity a Clutter. Mutter je v GNOME přímo integrován s Shellem, takže jej nelze vyměňovat za jiné správce, tak jako v minulosti Metacity.

Dále GS stojí na GLib, Gtk, Gdk, Gio, ...

A nad tím vším je tedy JavaScript (konkrétně interpretovaný enginem Spidermonkey od Mozilly), kterému zajišťuje binding na GNOME knihovny Gjs. Ten formuje výslednou podobu GS interfejsu a díky jeho skriptovatosti se v něm formuje velmi rychle a pohodlně, což byl ostatně důvod jeho použití.

Jak fungují extensions

Rozšíření GS se skládá minimálně ze dvou souborů - extension.js a metadata.json. První obsahuje vlastní rozšíření s povinnými funkcemi  init(), enable(), disable() - init() se volá při prvním načtení rozšíření do Shellu, a druhé dvě zajišťují zavedení a odebrání rozšíření. Druhý soubor ho popisuje - musí obsahovat unikátní identifikátor uuid (kerý se musí shodovat se jménem adresáře, ve kterém je rozšíření uloženo), jméno, popis, podporované verze GS.

Volitelně může rozšíření použít i soubor stylesheet.css pro nějaké to stylování a od verze 3.3.5 přibyla i podpora uživatelských nastavení v dalším neponinném souboru prefs.js, které musí z funkce buildPrefsWidget() vracet nějaký ten Gtk.Widget s klikátky pro uživatele.       

Za to, že extension dodrží předchozí, může na oplátku kecat úplně do všeho. Díky JS může totiž přímo přepisovat a doplňovat libovolné skripty Shellu editací prototypů jejich objektů. Říká se tomu monkey patching, mění se kód (s)prostě za běhu. Může přepisovat celé funkce, nebo provádět tzv. code injections, tedy jen původní funkce doplnit o další kód, který se přidá na konec před return. Díky tomu mohou rozšíření měnit design a fungování GS velmi výrazně a naopak je velmi jednoduché doplnit drobnosti, jako položku do Status menu.

Kde jsou

Skripty GS najdete v adresáři

/usr/share/gnome-shell/js/

Přičemž uživatelské rozhraní, které bude tvůrce rozšíření nejvíce zajímat, je v

/usr/share/gnome-shell/js/ui/

Základem je skript main.js, ten tu nádheru rozjíždí. Při startu se nejprve načte základní podoba UI a pak se aplikují povolená rozšíření.

Rozšíření předinstalovaná, nebo doinstalovaná z repozitáře najdete zde:

/usr/share/gnome-shell/extensions/

V domovském adresáři pak najdete ty, které jste si naklikali na extensions.gnome.org:

~/.local/share/gnome-shell/extensions/

Správa instalovaných rozšíření je nejjednodušší přes gnome-tweak-tool a přímo přes web na adrese extensions.gnome.org/local.

Dokumentace

Ke knihovnám, na kterých GS stojí je dokumentace dost, výše jsem ji odkazoval, ale k js modulům ui žádná neexistuje. Ten kód se také průběžně mění, proto rozšíření často nepřežijí upgrade na novou verzi GNOME a musí se kód přizpůsobit. Jediné, co zájemci o programování extensions zbývá, je studium kódu hotových rozšíření a ui modulů. Je třeba pochopit, jak to vlastně funguje, jak je to provázané a jak to využít. Zdrojáky jsou dostupné na webu GNOME, můžete si zobrazit libovolnou verzi, ale často používám při hledání konkrétních funkcí a modulů grep, který mi projede všechny soubory najednou na lokálním disku.

Pár užitečných, i když často starších zdrojů:

https://wiki.gnome.org/GnomeShell/Extensions
https://wiki.gnome.org/GnomeShell/Extensions/StepByStepTutorial - naprostý základ
https://git.gnome.org/browse/gnome-shell/tree/js
http://mathematicalcoffee.blogspot.cz/2012/09/gnome-shell-javascript-source.html

Ladič pian

Debugování skriptů bez chybového výstupu je peklo. GS sice nabízí něco málo v looking glass (Alt+F2, lg, Enter), ale tam se dozvíte jen první chybu při zavádění rozšíření. Jediná rozumná možnost na kterou jsem přišel, je přesměrovat si výstup celého GS do okna terminálu. Jednoduše otevřete svůj oblíbený terminál a spustíte:

gnome-shell -r

GS tak poběží zde a uvidíte vše, co vypíše. Navíc tu zůstane i po měkkém restartu přes Alt+F2, r, Enter. Když poděláte něco ve svém rozšíření, ať už se jedná o to, že nemohlo být vůbec načteno, či aktivováno, nebo runtime errory, tady to najdete. Příkazem print si sem můžete vypisovat debugovací data a atd.

Závěrem

GNOME Shell je zdá se prostředí pro mě. Základ je sice strohý, ale funkční a konzistentní a do toho jak se to bude chovat můžu kecat bez výrazných překážek, což já opravdu rád. Naštěstí je tu i spousta schopnějších nežli já a tak mám plno chytrých rozšíření na jeden klik. Když mi v něčem nevyhovují, prostě se podívám do kódu a přepíšu si to. Osobně jsem začal tím, že jsem dopsal rozumnou navigaci klávesami v režimu náhledu pracovních ploch na základě pár nedodělků z extensions.gnome.org.

Žádné komentáře:

Okomentovat

Zkuste prosím při komentováni používat místo volby Anonymní volbu Název/adresa URL, kde vyplníte nějakou přezdívku, adresu zadávat nemusíte. Vědět, které příspěvky jsou od jednoho člověka, je fajn. Díky.

Pokud by se vám náhodou odeslaný komentář na stránce nezobrazil, vytáhnu ho z koše hned jak si toho všimnu. I Google spam filter se občas sekne.