Deblan blog

i3wm - menu d'applications

i3wm est un Tiling Window Manager, c'est à dire que l'ensemble des fenêtres de mon environnement de travail est géré de telle sorte que l'espace soit le plus optimisé possible. Dans ce type de configuration (et quelque soit le TWM), c'est au clavier que tout se pilote. Le problème c'est qu'au fond d'un lit, sous une couette, c'est chiant de faire des raccourcis claviers.

Avant de passer à i3wm, j'utilisais Fvwm-Crystal qui possédait un menu d'application pour lancer les logiciels à la souris. i3wm n'en dispose pas et ça me gène.

Pour répondre à cette problématique, il existe un outil qui se nomme SSHPlus. C'est un script écrit en python qui permet de générer un menu comme celui ci.

Manuberro de Absolacom a rédigé un excellent article qui explique comment configurer SSHPlus. Cependant, je suis un gros flemmard et j'ai envie générer automatiquement le menu d'applications. Pour ce faire, j'ai écrit un script PHP qui va piocher dans le répertoire /usr/share/menu/ de ma Debian et qui sort une conf au format SSHPlus.

Il suffira donc de lancer le script et de rediriger la sortie standard vers ~/.sshplus.

$ /chemin/vers/script.php > ~/.sshplus

Voici le script (vous pouvez modifier les fonctions prepend_config() et append_config() pour insérer des configurations spéciales) :

#!/usr/bin/env php
<?php

function append_config()
{
    $config = <<<EOF
sep
folder:Session
Éteindre|sudo|shutdown -h now
Reboot|sudo|shutdown -r now
folder:
EOF;

    return sprintf("%s\n", $config);
}

function prepend_config()
{
    $config = <<<EOF
EOF;

    return sprintf("%s\n", $config);
}

function is_x11_application($setting)
{
    return 0 !== preg_match('`needs="X11"`i', $setting);
}

function get_title($setting)
{
    return preg_replace('`.*title="([^"]+)".*`is', '$1', $setting);
}

function get_sections($setting)
{
    return explode('/', preg_replace('`.*section="([^"]+)".*`is', '$1', $setting));
}

function get_command($setting)
{
    return preg_replace('`.*command="([^"]+)".*`is', '$1', $setting);
}

function get_info($setting)
{
    return array(
        'title'    => get_title($setting),
        'command'  => get_command($setting),
        'sections' => get_sections($setting)
    );
}

function cleanup_config($config)
{
    return preg_replace("`folder:[^\n]+\nfolder:\n`", '', $config);
}

function get_config($menus)
{
    $config = '';

    foreach ($menus as $k => $menu) {
        if (is_array($menu)) {
            if (!empty($menu)) {
                $config.= sprintf("folder:%s\n%sfolder:\n", $k, get_config($menu));
            }
        } else {
            $config.= sprintf("%s\n", $menu);
        }
    }

    return cleanup_config($config);
}

$setting_files = glob('/usr/share/menu/*');
$menus         = array();
$apps          = array();
$final_menus   = array();

foreach ($setting_files as $k => $file) {
    $_settings = explode('package', file_get_contents($file));

    foreach ($_settings as $setting) {
        if (is_x11_application($setting)) {
            $info     = get_info($setting);
            $sections = $info['sections'];

            if (!in_array($sections, $menus)) {
                $menus[] = $sections;
            }

            $apps[] = $info;
        }
    }
}

foreach ($menus as $sections) {
    foreach ($sections as $k => $section) {
        if (!$k && !isset($final_menus[$section])) {
            $final_menus[$section] = array();
        }

        if ($k && !isset($final_menus[$sections[$k-1]][$section])) {
            $final_menus[$sections[$k-1]][$section] = array();
        }
    }
}

foreach ($apps as $app) {
    $eva = '$final_menus';

    foreach ($app['sections'] as $s) {
        $eva.= '["'.addslashes($s).'"]';
    }

    $full_command = explode(' ', addslashes($app['command']));
    $command = array_shift($full_command);
    $params  = implode(' ', $full_command);

    $eva.= '[] = "'.$app['title'].'|'.$command.'|'.$params.'";';

    eval($eva);
}

$config = prepend_config().get_config($final_menus).append_config();

echo $config;

J'admet que le code n'est pas très propre mais il fonctionne, c'est l'essentiel :)

Pour lancer SSHPlus au démarrage de i3wm, il suffira de placer dans ~/.i3/config cette ligne : exec /chemin/vers/sshplus.py (n'oubliez pas de faire un chmod +x sur le fichier et vous devrez disposer du paquet python-appindicator).


Ajouter un commentaire

Vous pouvez utiliser du markdown.Afficher l'aide.