Programmation d'adesklets - adesklets 0.6.1
Description: adesklets 0.6.1

Next: Extension d'adesklets, Previous: Utiliser adesklets, Up: Top

## 5 Programmation d'adesklets

### 5.1 Une introduction à adesklets

Comme expliqué ci-dessus (See A propos d'adesklets.), adesklets est principalement une console interactive d'Imlib2, avec une ou deux fonctions supplémentaires:

- Quand un affichage X est présent, la gestion automatique d'une fenêtre simple.
- Support automatique de la pseudo-transparence
- Gestion d'applets persistants entre sessions

Commençons une session interactive typique pour voir ce qui se passe. Sous X, ouvrez un terminal et tapez:

         adesklets :

Comme dans la section précédente (See 'Utilisation d'adesklets comme un éditeur graphique en ligne de commande'.), vous obtenez une invite. Maintenant entrez la commande '`images_info`'. Vous devriez obtenir sur la sortie standard :

         2 images
         id 0 width 1 height 1 alpha 1 filename (null)
         id 1 width 1 height 1 alpha 1 filename (null)
         command 0 ok: images_info

Cela signifie que vous avez deux images : l'image 0 et l'image 1, et qu'elles ont une taille de 1x1 pixel. Ce sont les seules images que vous ne pourrez jamais détruire ou modifier (redimensionner indépendamment, retourner diagonalement, etc.) comme vous le souhaitez. Qu'est-ce que c'est que cela?

- Image 0 est l'image d'avant-plan. Par défaut, c'est la seule image qui est affichée dans une fenêtre simple gérée par `adesklets`.
- Image 1 est l'image d'arrière-plan. Par défaut, elle contient toujours le contenu de la fenêtre racine (le bureau) qui est sous cette fenêtre. Sans modification de notre part, elle est toujours mise à jour lorsque l'utilisateur la déplace, la redimensionne, lorsque le fond d'écran change, etc.

Mais où est cette fenêtre? Eh bien, pour l'instant, ce sont seulement des images de 1x1 pixel, et elles ne sont pas affichées1 à l'écran. Ainsi, redimensionnons les à 100x100 pixels: tapez '`window_resize 100 100`'. Maintenant, si vous retapez la commande '`images_info`', vous obtiendrez:

         2 images
         id 0 width 100 height 100 alpha 1 filename (null)
         id 1 width 100 height 100 alpha 1 filename (null)
         command 2 ok: images_info

Vous voyez? Les images d'avant-plan et d'arrière-plan ont été redimensionées à 100x100 pixels: de plus l'arrière-plan a été mis à jour pour contenir la nouvelle image de fond. Maintenant, rendons cette fenêtre visible. Tapez les deux commandes: '`window_reset managed`' et enfin '`window_show`'.

La première commande demande à adesklets de laisser votre gestionnaire de fenêtres "gérer" votre fenêtre (ce qui n'est pas fait par défaut): cela signifie que la fenêtre va être décorée, et que vous pourrez changer sa visibilité2 de façon interactive. La seconde montre votre fenêtre de 100x100. Rien d'impressionnant: un carré noir de 100x100 avec une barre de titre et des bordures fixes.

Comme dit plus haut, seule l'image 0 (l'avant-plan) est affichée par défaut. Maintenant, tapons : '`window_set_transparency 1`'. Wouah! Nous voyons la fenêtre racine du dessous! Avec "window transparency" activé, l'image 1 (arrière-plan) est d'abord copiée dans la fenêtre, puis l'image 0 (avant-plan) qui est entièrement noire et transparente, est mise par-dessus3.

Il est temps de parler des couleurs: souvenez-vous, adesklets est une console d'Imlib2. Par conséquent, comme Imlib24, les couleurs sont toujours de véritables couleurs 32 bits codées en RVBA - huit bits par canal (de 0 à 255), incluant un canal alpha pour la transparence. La conversion de palette se fera automatiquement si la définition de votre écran est inférieure, vous n'avez pas à vous en occuper. Si vous tapez: '`context_get_color`', vous obtiendrez:

         command 0 ok: context color 255 255 255 255

Imlib2 est une sorte de machine par états; en tant que tel, il utilise un "contexte" qui garde en mémoire une série d'attributs qui seront utilisés dans ses opérations futures. Par exemple, nous savons maintenant que la couleur qui sera utilisée, aussi longtemps que nous ne la modifions pas, sera un blanc opaque (rouge=255, bleu=255, vert=255, alpha=255). Si nous tapons: '`context_get_image`', il retourne:

         command 0 ok: context image 0

Cela signifie que toute opération que nous effectuons sur une fenêtre sera faite directement sur l'image d'avant-plan. Dessinons un rectangle plein semi-transparent de couleur magenta sur l'avant-plan. Les commandes seront: '`context_set_color 255 0 0 200`' et '`image_fill_rectangle 25 25 50 50`'. Élégant, n'est-ce pas?

Si vous avez l'habitude de programmer avec Imlib2, vous avez du remarquer que ces dernières commandes ont l'air familières. C'est assez normal; la plupart des fonctions C d'Imlib2 sont présentées de la même façon dans les 'commandes' d'adesklets. Ainsi, la commande d'adesklets '`image_fill_rectangle`' suit la même sémantique que la fonction '`imlib_image_fill_rectangle()`' d'Imlib2, la commande '`context_set_color`' suit celle de la fonction '`imlib_context_set_color()`', etc. Les deux seules différences significatives (et systématiques) sont premièrement que partout où vous utiliserez un objet '`Imlib_Quelquechose`' en C, vous utiliserez un ID entier avec adesklets, et deuxièmement dans la sémantique des fonctions '`imlib_free_Quelquechose()`' où on doit préciser l'ID de l'objet auquel s'applique la fonction au lieu de libérer l'objet de ce type sélectionné dans le contexte.

Tout ceci est facile à illustrer. Chargeons la police "Vera" incluse dans adesklets à la taille 20pt, mettons la en police par défaut et écrivons 'Hello' en blanc opaque en diagonale sur l'image d'avant-plan en partant du coin en haut à gauche, avant de décharger la police. Cela devrait ressembler à:

         6 >>> load_font Vera/20
         command 6 ok: new font 0
         7 >>> context_set_font 0
         command 7 ok: context_set_font 0
         8 >>> context_set_direction text_to_angle
         command 8 ok: context_set_direction text_to_angle
         9 >>> context_set_angle 45
         command 9 ok: context_set_angle 45
         10 >>> context_set_color 255 255 255 255
         command 10 ok: context_set_color 255 255 255 255
         11 >>> text_draw 0 0 Hello
         command 11 ok: text_draw 0 0 Hello
         12 >>> free_font 0
         command 12 ok: free_font 0

Si vous regardez votre documentation d'Imlib2, vous remarquerez immédiatement les deux différences que l'on vient d'évoquer: toutes les références à la police Vera/20 sont faites par un ID entier (0 ici), et la commande '`free_font`', contrairement à la fonction correspondante '`imlib_free_font()`', est appliquée à la police dont l'ID est donné en argument plutôt qu'à la police du contexte.

A partir de là, imaginons que vous voulez sauvegarder l'image résultante; aucun problème! Tapez: '`save_image out.png`', et l'avant-plan sera sauvé dans un fichier "out.png" dans le répertoire courant5. Maintenant, juste pour le plaisir, quittons adesklets, et lançons une autre session interactive pour voir si nous pouvons recharger cette image. Tapez juste la commande "`quit`" ou pressez ^D (Control D: fin de fichier), votre nouvelle session devrait ressembler à ceci :

         0 >>> window_resize 100 100
         command 0 ok: window_resize 100 100
         1 >>> window_reset managed
         command 1 ok: window_reset managed
         2 >>> window_set_transparency 1
         command 2 ok: window_set_transparency 1
         3 >>> load_image out.png
         command 3 ok: new image 2
         4 >>> blend_image_onto_image 2 1 0 0 100 100 0 0 100 100
         command 4 ok: blend_image_onto_image 2 1 0 0 100 100 0 0 100 100
         5 >>> window_show
         command 5 ok: window_show
         6 >>> free_image 2
         command 6 ok: free_image 2

Bien sur, nous voulions visualiser le résultat - c'est pourquoi nous avons utilisé les commandes '`window_reset`', '`window_set_transparency`' et '`window_show`': elles n'ont pas d'autre utilité. La commande '`blend_image_onto_image`' vient elle aussi tout droit d'Imlib2; elle prend la nouvelle image 2 que l'on vient de créer avec la troisième commande, et la met dans l'image du contexte (image 0 - avant-plan par défaut), à partir de ses coordonnées (0,0) et d'une taille de 100x100 pixels, et la met dans un rectangle partant de (0,0) et de taille 100x100 pixels dans l'image 0. Il est finalement bon de noter que, avec adesklets, il y a toujours une image dans le contexte d'Imlib2: dès que vous essayez de libérer l'image courante, le contexte d'image est réinitialisé à l'image d'avant-plan.

Voila, c'est presque la fin de cette introduction... A partir de là vous devriez pouvoir jouer un peu avec adesklets. Si vous êtes déjà familier avec Imlib2 vous vous y ferez très rapidement. Sinon vous devriez garder la documentation d'Imlib2 sous la main. :-)

Quelques dernières astuces:

- Si vous êtes fatigué de taper encore et encore, n'oubliez pas l'auto-complétion: 'TAB your problems away!'
- Si vous avez besoin d'aide sur quoi que ce soit, il existe la commande '`help`'.
- Si vous exécutez une série de commandes, que ça ne marche pas et que tout cet usage interactif vous fatigue:
  1. Utilisez la commande '`history`' pour enregistrer votre session courante dans un fichier6.
  2. Utilisez l'option '-f' avec adesklets pour passer les commandes à partir d'un fichier plutôt que de la console tty.
  3. Si vous essayez de visualiser quelque chose, insérez une commande '`pause`' à la fin du script pour geler l'interpréteur.
  4. Tous les caractères après un dièse '#' jusqu'à la fin de la ligne seront ignorés, ce qui vous permet d'écrire des commentaires.

Voici un exemple:

         #!/usr/bin/env adesklets -f

         # Rendre la fenêtre 'gérée'
         #
         window_reset managed

         # Redimmensioner la fenêtre à 100x100 pixels
         #
         window_resize 100 100

         # Montrer la fenêtre, puis la geler pendant 10 secondes avant de sortir
         #
         window_show
         pause 10

Vous aurez juste besoin de rendre ce script exécutable et de le lancer. Comme d'habitude, les résultats seront affichées sur la sortie standard.

### 5.2 Véritable programmation avec adesklets: écriture d'un script de desklet

Lorsque vous serez prêt pour un vrai travail7, vous voudrez surement utiliser un véritable langage de script plutôt que l'interpréteur rudimentaire d'`adesklets` que nous avons utilisé dans l'introduction; ne serait-ce que pour pouvoir utiliser des variables.

Au moment où j'écris ces lignes (31 mars 2006), le support pour Python et Perl 5 est inclus dans le paquetage d'adesklets8.

#### 5.2.1 Quelques astuces pour les programmeurs

Une fonction très utile de l'interpréteur d'`adesklets` est sa capacité à produire un trace complète d'une de ses sessions (commandes, évènements et messages spéciaux), que ce soit sur `stderr` ou dans un fichier journal, et ce indépendemment de ce qui le contrôle. Pour se servir de cette fonctionalité, il faut:

1. Configurer le paquetage au niveau des sources en activant la trappe `--enable-debug` de `configure`.
2. Exporter la variable `ADESKLETS_LOG` dans l'environnement si la sortie de la session doit être enregistrée dans un fichier plutôt qu'affichée sur `stderr`9. Ce doit être un chemin absolu qui servira de préfixe à l'interpréteur qui, l'ayant hérité de l'environnement, s'en servira pour créer les noms complets des fichiers dans lesquels il écrira.

A partir de là, il est possible de lire des journaux de session complets et chronologiques; utilisés correctement, ils peuvent être utiles pour débugger. Vous pouvez vous en servir conjointement avec la commande `echo` pour placer des marqueurs faciles à trouver10.

#### 5.2.2 adesklets et Python

##### Un exemple d'utilisation de Python

Avec Python, les choses ne sont pas très différentes de l'interpréteur. Les commandes ont été encapsulées dans des fonctions Python, et une classe publique `Events_handler` a été construite pour manipuler les retours asynchrones de l'interpréteur. Jetons un coup d'oeil sur le script `test/test.py` de l'archive source de la version 0.6.1:

    """
    test_fr.py - S.Fourmanoit <syfou@users.sourceforge.net>,
                 Guillaume Boitel <g.boitel@wanadoo.fr>

    Petit script de test non-exhaustif pour adesklets :

          - Redimensionne la fenêtre adesklets à 100x100 pixels
          - La met sous le contrôle du gestionnaire de fenêtre
          - La rend pseudo-transparente
          - L'affiche à l'écran
          - Attends ensuite que l'utilisateur la quitte,
            génère une alarme toutes les 10 secondes
            et attrape les événements motion_notify dès qu'ils apparaissent.

    Pour l'essayer :
          - Installer adesklets avec le support python activé (par défaut)
          - Lancer python test.py à partir de ce répertoire.
    """
    import adesklets

    class My_Events(adesklets.Events_handler):
        def __init__(self):
            adesklets.Events_handler.__init__(self)

        def __del__(self):
            adesklets.Events_handler.__del__(self)

        def ready(self):
            adesklets.window_resize(100,100)
            adesklets.window_reset(adesklets.WINDOW_MANAGED)
            adesklets.window_set_transparency(True)
            adesklets.window_show()

        def quit(self):
            print 'Quitting...'

        def alarm(self):
            print 'Alarm. Next in 10 seconds.'
            return 10

        def motion_notify(self, delayed, x, y):
            print 'Motion notify:', x, y, delayed

    My_Events().pause()

Voilà! 26 lignes de code Python, et nous avons un desklet parfaitement fonctionnel. Je pense qu'il s'explique de lui-même; jetez un coup d'oeil à l'aide intégrée de python à propos de `adesklets`, `adesklets.functions` et `adesklets.Events_handler` pour de bonnes et complètes explications (See Documentation du paquetage Python.) . Tout ce que nous avons fait ici c'est:

1. Importer le paquetage `adesklets`: cela instancie automatiquement un processus fils `adesklets` et configure toutes les communications. Si l'initialisation du paquetage termine sans provoquer d'exception, cela signifie que l'interpréteur tourne et qu'il attend des commandes.
2. Faire une sous-classe d'`adesklets.Events_handler` et redéfinir les méthodes invoquées pour les événements qui nous intéressent (tous les autres événements ne sont pas simplement ignorés, ils ne sont pas générés).
3. Instancier un objet de cette classe, et le mettre en boucle infinie 11.

##### Attention, piège: quelques détails sur les ID d'objets

Tous les objets d'adesklets (polices, images, palettes de couleurs, polygones, etc), sont stockés dans des piles (une pile par type d'objet). Les ID de Python ne sont rien d'autre que la position initale d'objets donnés dans la pile correspondante, et deviendront donc invalides si un objet du même type situé en-dessous est libéré.

Par exemple, partant d'un état vierge, il n'y a d'autre dans la pile des images que l'avant-plan (ID O) et l'arrière-plan (ID 1) de la fenêtre. Lorsque quelqu'un créé deux autres images depuis Python comme ceci:

         im_1 = adesklets.create_image(10,10)
         im_2 = adesklets.create_image(10,10)

on a `im_1==2`, et `im_2==3`. Dès qu'on fera:

         adesklets.free_image(im_1)

La pile commence à s'écraser, et ce qui était l'image 3 (`im_2`) est maintenant l'image 2, et `im_2` est une réference invalide. Cela signifie clairement qu'invoquer:

         adesklets.free_image(im2)

génerera le message d'erreur `image out of range`.

##### Un sujet spécial: les animations

`adesklets` inclut maintenant aussi bien un mode d'exécution indirect que les variables textuelles (pour être précis, le remplacement textuel non-récursif). Cela signifie que les auteurs de desklets ont ce qu'il faut pour créer des animations précisément temporisées. Vous trouverez un exemple simple à suivre dans `test/fading.py`. Une utilisation plus poussée de ces fonctionalités est faite dans le desklet `yab`. Pour réaliser un animation en Python, il faut:

1. Enregistrer une séquence de commandes (que nous appelerons une commande macro, ou macro). Avec Python, il faut passer en mode indirect avec la fonction `adesklets.start_recording()`, émettre un nombre indéterminé de commandes `adesklets`, puis repasser en mode normal (execution directe) avec `adesklets.stop_recording()`. Bien sur, aucune commande n'est évaluée quand l'interpréteur est en mode indirect; les commandes sont seulement conservées dans l'historique pour être rejouées plus tard.
2. Choisir si la séquence de commandes à rejouer peut être interrompue par des évènements ou pas, en utilisant la fonction `adesklets.play_set_abort_on_events()`. La méthode de haut niveau `adesklets.Events_handler::set_events()` peut aussi être utilisée pour choisir dynamiquement quels évènements seront rattrapés. Pour un exemple, voyez `test/test_events.py`.
3. Initialiser les variables utilisées dans la macro enregistrée avec la fonction `adesklets.set()`, qui est très similaire à son homonyme du shell Bourne.
4. Lire la macro avec la fonction `adesklets.play()`.

Quelques remarques supplémentaires:

- Une temporisation précise de la séquence peut être faite par la commande `time_gate`. Elle fonctionne très simplement: à chaque fois qu'une macro est exécutée, adesklets enregistre à quel moment elle à commencé. Dès qu'une commande `time_gate` apparait lors de l'exécution, le programme attend que le nombre de secondes données en argument à `time_gate` soient écoulées. Par exemple, écrire `time_gate 0.1` dans une macro empêchera l'execution de toutes les commandes suivantes de la macro tant que celle-ci n'aura pas fonctionné pendant au moins un dixième de seconde.
- La substitution des variables à toujours lieu juste avant l'exécution des commandes, indépendemment du mode d'execution (direct ou indirect). Toute séquence de caractères ne contenant pas d'espace précedée directement par un seul '$' sera remplacée par le contenu de la variable correspondante (configuré précedemment avec `set`). Si aucune variable ne correspond, la séquence est simplement ignorée.
- Toutes les macros exécutées par la commande `play` sont, du point de vue du desklet qui les contrôle, élémentaires, comme toutes les autres commandes. En un mot, cela signifie qu'aucun évènement ne sera jamais géneré pendant qu'une macro est exécutée; ils apparaitront tous juste après que la commande `play` ait terminé.
- Comme d'habitude, l'interpréteur d'adesklets fonctionne par états pour les variables et les états liés au mode indirect. Vous n'avez pas à fixer le drapeau `set_abort_on_events` ou les variables à chaque fois que vous appelez une macro, sauf si quelquechose doit être changé depuis l'appel précedent.
- La fonction de haut niveau `adesklets.Events_handler::set_events()` sert principalement à arrêter la prise en charge de certains évenements pendant l'exécution de la macro, ainsi la macro ne peut être interrompue que dans des circonstances bien précises. Bien sur, tous les évènements génerés avant l'appel à cette méthode ne seront pas perdus mais placés en file d'attente, et les méthodes d'évènements appropriées seront appelées plus tard, pourvu que les trappes soient en place lorsque l'exécution de la macro est terminée.
- Avons-nous rappelé que faire tout cela depuis un endroit non protégé est une mauvaise idée? Eh bien, ça l'est. N'oubliez pas d'utiliser `adesklets.Events_handler::block()` et `adesklets.Events_handler::unblock()` autour de tout code relatif à une animation si vous avez instancié un objet d'une classe fille de `adesklets.Events_handler`.

##### Configuration et internationalisation

Mentionnons jute ici que depuis `adesklets` 0.4.0, le module `adesklets.utils` inclut maintenant une classe optionelle `ConfigFile` qui peut être facilement réutilisée par les auteurs de desklets pour ajouter un système de configuration facilement extensible à leur code12 (See Documentation du paquetage Python.) . Par défaut, la classe prend aussi en charge l'internationalisation automatiquement, en sélectionnant les jeux de caractères selon les besoins de l'utilisateur. L'utilisation des jeux peut bien sûr être déterminée ou changée à tout moment en utilisant les fonctions `adesklets.get_charset()` et `adesklets.set_charset()`. La classe `adesklets.utils.ConfigFile` a aussi un attribut `charset` qu'on peut examiner pour connaitre les préferences de l'utilisateur. En utilisant cette classe on notera que le jeu de caractères 'ASCII' est considéré comme choix par défaut, et qu'il ne désactivera pas une éventuelle conversion. Ainsi, les utilisateurs de plate-formes ne supportant pas iconv pourront toujours utiliser `adesklets` sans le support de l'internationalisation.

##### Derniers mots

Enfin, signalons que vous pourriez avoir envie de jeter un oeil au code source du desklet `weather` disponible sur le site web du projet SourceForge pour voir un plus gros morceau de code Python utilisant adesklets. Il y a aussi quelques autres desklets de test sous le répertoire `test/` qui pourraient vous donner des idées. Vous pourriez aussi jeter un oeil au paquetage d'aide autogéneré d'`adesklets` par pydoc, inclus dans ce document (See Documentation du paquetage Python.). Dès que vous êtes suffisement content de votre desklet, n'hésitez pas à le partager avec le reste d'entre nous (ce qui serait très apprécié). Faites-en un paquetage (See GNU Makefile pour empaqueter les desklets.), puis soumettez-le (See Soumettre un desklet.).

#### 5.2.3 adesklets et Perl

Depuis adesklets 0.6.0, adesklets peut par défaut être commandé par Perl, grâce au travail de Lucas Brutschy . Bien sur, les liens avec Perl sont complètement perpendiculaires à Python, et n'ont besoin que de l'environnement Perl 5 en plus de l'interpréteur de base d'adesklets, écrit en C.

##### Exemple d'utilisation de Perl

Comme avec le paquetage Python, les commandes sont encapsulées dans des routines Perl. Une boucle de gestion des évènements peut alors être lancée, enregistrant et appelant automatiquement les routines données (`BackgroundGrab`, `ButtonRelease`, `LeaveNotify`, `MotionNotify`, `ButtonPress`, `EnterNotify`, `MenuFire`) selon le cas approprié. `adesklets::event_loop` ne termine que lors de la fin de l'interpréteur adesklets commandé. Voici le script `test/test.pl` du paquetage source de la version 0.6.1:

    # test.pl - Lucas Brutschy <lbrutschy@users.sourceforge.net>, 2006
    #
    # Small, non-exhaustive adesklets test script:
    #        - Resize adesklets window to 100x100 pixels
    #        - Set it to be pseudo-transparent
    #        - Draw a translucent light grey rectangle on it
    #        - Map it on screen
    #        - Mark with a red dot the pointer position every time
    #          a user click
    #
    # To try it:
    #        - Install adesklets with perl support enabled (default)
    #        - Run perl test.py from this directory

    use strict;
    use adesklets;

    adesklets::open_streams();

    # these are just normal adesklet commands
    adesklets::window_resize(100,100);
    adesklets::window_reset(adesklets::WINDOW_UNMANAGED);
    adesklets::window_set_transparency(1);
    adesklets::context_set_color(255,255,255,64);
    adesklets::image_fill_rectangle(5,5,90,90);
    adesklets::window_show();

    adesklets::event_loop(ButtonPress=>\&onbutton); # supply a hash of callbacks
    adesklets::close_streams();

    sub onbutton
    {
        my($x,$y) = @_;
        adesklets::context_set_color(255,0,0,255);
        adesklets::image_fill_rectangle($x,$y,3,3);
    }

Simplement vingt lignes de code, et comme précedemment, nous avons déjà un desklet fonctionnel. Il doit être assez simple à comprendre, mais voici quelques indications génerales sur ce qu'il fait:

1. D'abord, il importe de module adesklets de Perl (`use adesklets`), et instancie l'interpréteur d'adesklets en appelant `adesklets::open_stream()`. Lorsque la sous-routine termine, la ligne de commande est déjà traitée et l'interpréteur est prêt à accepter des commandes.
2. A partir de là, nous avons simplement initialisé une fenêtre non-gerée de 100 pixels sur 100, que nous avons remplie avec un fond transluicide blanc, et l'avons affichée.
3. Enfin, nous allumons une boucle des évènements, enregistrant une sous-routine de retour qui agit quand l'utilisateur clique dessus (ici, l'action consiste à dessiner un carré rouge de 3 pixels de coté sous le pointeur). Cette boucle des évènements tourne tant que l'interpréteur d'adesklets n'est pas tué (que ce soit manuellement ou à cause de la fin d'une session X11). Quand elle termine, la sous-routine de nettoyage `adesklets::close_streams()` est appelée.

##### Rattraper les erreurs

Lorsqu'une commande adesklets retourne une erreur, le script Perl meurt. Vous pouvez récuperer le message d'erreur d'origine comme ceci:

         eval { my $image = adesklets::load_image("aaarrhg"); };
         if($@) { print $@; }

See Quelques astuces pour les programmeurs, pour une alternative.

##### Configuration

Vous pouvez très bien conserver de multiples instances du même desklet en Perl configurées differemment; il s'agit simplement d'utiliser la valeur de retour de `adesklets::get_id()` pour identifier de manière unique l'instance en cours d'exécution; la manière dont vous utilisez cet unique identifiant entier pour sélectionner les paramètres de configuration dépends entièrement de vous.

##### Derniers mots

Vous désirez certainement jeter un oeil aux sections précedentes concernant les ID d'objets (See Attention.) et les animations (See Un sujet spécial: les animations.), qui sont toujours valables pour Perl.

Vous pouvez aussi voir la vieille documentation (plain old documentation – POD) du paquetage Perl, incluse dans ce document (See Documentation du paquetage Perl.). Comme signalé precedemment, dès que vous êtes suffisemment satisfait de votre desklet, n'hésitez pas à le partage avec le reste d'entre nous (ce qui serait très apprecié) – faites-en un paquetage (See GNU Makefile pour empaqueter les desklets.), puis soumettez-le (See Soumettre un desklet.).

#### Footnotes

[1] "Mappé" dans le jargon d'X Window

[2] Une fenêtre "non-gérée" est très utile pour les desklets: c'est comme si c'était une partie de la fenêtre racine puisqu'elle peut être faite pour ne jamais être en avant-plan et pour rester affichée (mapped) lorsque l'on change d'espace de travail.

[3] Enfin... Pas tout à fait : il y a un buffer qui intervient pour la performance, mais l'opération est logiquement équivalente à cette description.

[4] Gardez votre documentation d'Imlib2 à proximité: c'est très utile! See Documentation d'Imlib2.

[5] Pour que ça marche, il faut que votre installation d'Imlib2 soit correctement configurée pour utiliser libpng, sinon vous risquez de recevoir l'erreur "no loader for file format".

[6] Pour que ça marche, GNU history doit être installé lors de la compilation d'adesklets.

[7] :-)

[8] adesklets a été écrit pour être facilement utilisé depuis toutes sortes de langages interprétés; n'hésitez pas à proposer votre aide si vous voulez que votre langage favori soit supporté!

[9] L'afficher sur `stderr` risque fortement de perturber les liens avec les langages externes, il est donc préferable de ne le faire que lors d'une invocation de l'interpréteur directement sur la console.

[10] Certains systèmes de gestion des paquetages, comme les ebuilds de Portage avec le drapeau USE `debug`, utilisent cette fonctionalité automatiquement.

[11] Cette dernière étape n'est pas obligatoire; le script peut très bien continuer, mais devra alors avoir été écrit pour supporter les interruptions des signaux. Lisez ``help(adesklets.Events_handler)`' pour de plus amples informations.

[12] Pour en voir un exemple voyez n'importe quel desklet non issu de contributions.