Commit cc13fe2a authored by Estérel-Tech's avatar Estérel-Tech 🐧

initial commit

parents
menucat.geany
MenuCat
This diff is collapsed.
#
# Makefile simple PhM 180724
# Révision 181130
#
# Shell par défaut.
SHELL=/bin/sh
# Compilateur.
CC?=cc
# Nom de l'exécutable en sortie.
APP_NAME=MenuCat
# Les fichiers source C à compiler.
SRCS= \
main.c \
etechapp.c \
etechappwin.c \
options.c \
config.c \
etech_utils.c
# Pour les ressources à compiler avec l'application.
GRES_C=resource.c
GRES_XML=gresource.xml
GRES_DIR=res
# Ajout de resource.c aux fichiers source C.
SRCS+=$(GRES_C)
#
# La taille de l'exécutable est le 5 ème mot de la ligne ls.
#
define lstarget
echo Taille de $1 : $(word 5,$(shell ls -l $1)) octets.
endef
# Fichier de sortie.
OUT=-o $(APP_NAME)
# Optimisé, sans information de débogage.
CRELEASE=-DNDEBUG -Ofast -s
# Débogage.
CDEBUG=-Og -g
# Options de compilation : avertissements et erreurs, C11.
CFLAGS=-march=native -Wall -Wextra -Werror -std=gnu11 -D_GNU_SOURCE
# Liaison aux bibliothèques propres à GTK+ (version 3.0).
CPPLAGS=`pkg-config --cflags gtk+-3.0`
LDFLAGS=`pkg-config --libs gtk+-3.0`
# Cibles ne correspondant à aucun fichier.
.PHONY: all release debug _rel _dbg clean
# Cible par défaut.
.DEFAULT_GOAL=release
# Cibles.
release: $(GRES_C) _rel
@$(call lstarget,$(APP_NAME))
debug: $(GRES_C) _dbg
@$(call lstarget,$(APP_NAME))
# Compilation de l'exécutable.
_rel: $(SRCS)
$(CC) $(CFLAGS) $(CRELEASE) $(CFLAGS) $(OUT) $^ $(CPPLAGS) $(LDFLAGS)
_dbg: $(SRCS)
$(CC) $(CFLAGS) $(CDEBUG) $(CFLAGS) $(OUT) $^ $(CPPLAGS) $(LDFLAGS)
# Compilation des ressources.
$(GRES_C): $(GRES_XML) $(GRES_DIR)
glib-compile-resources --target=[email protected] \
--generate-source $< \
--sourcedir=$(word 2,$^)
# Nettoyage.
clean:
$(RM) *.h~
$(RM) *.c~
$(RM) Makefile~
$(RM) $(GRES_C)
clobber: clean
$(RM) $(APP_NAME)
**MenuCat - menu d'applications par catégories pour système Linux.**
*Langage C - Interface graphique utilisateur GTK+ 3 >= 3.20*
Ce menu des applications est conforme à Freedesktop.org, quant à l'
interopérabilité des environnements graphiques sur systèmes Linux / Unix.
Les applications sont proposées par catégories.
Les 10 principales catégories utilisées sont :
Accessoires, Bureautique, Éducation, Infographie, Internet - Réseau,
Jeux, Multimédia, Paramètres, Programmation, Système.
À l'origine, j'ai créé cette application pour un ordinateur portable ayant pour système d'exploitation la distribution GNU/Linux Debian "testing" avec l'environnement de Bureau OpenBox.
Les autres environnements de bureau, comme les plus connus, Xfce, Gnome, Mate, KDE etc. ont leur propre menu d'applications. MenuCat est donc destiné à des environnements de bureau minimalistes et se montre très efficace avec un raccourci clavier.
**Captures d'écran**
Le rendu dépend du thème GTK 3.x utilisé.
![Menu principal](screenshots/mc_main.png)
![Menu secondaire](screenshots/mc_sub.png)
![Configuration](screenshots/mc_conf.png)
![Dialogue 'À propos'](screenshots/mc_about.png)
**Notes :**
La configuration simple permet d'indiquer les coordonnées d'affichage du menu
sur l'écran ainsi que la commande permettant d'exécuter des applications
nécessitant le terminal. Pour les distributions Debian et dérivées MenuCat
utilise /etc/alternatives/x-terminal-emulator (émulateur de terminal par
défaut). Pour les autres distributions, par exemple celles utilisant l'
environnement de bureau Gnome, la commande est : 'gnome-terminal --'; pour
d'autres émulateurs de terminal, se référer à leurs manuels.
Au premier lancement de MenuCat les coordonnées par défaut sont x=4, y=100, ce
qui place le menu à 4 pixels du bord gauche de l'écran et à 100 pixels du bord
supérieur.
Le fichier de configuration menucat.conf est créé dans le répertoire
/home/$USER/.config/Estérel-Tech/.
Un dialogue 'À propos' est proposé par le menu.
L'application MenuCat n'est pas internationalisée en l'état.
**Tests effectués sur les versions récentes des distributions suivantes :**
Debian (stable et testing)
Machines virtuelles :
Fedora
Arch Linux
Mint
Ubuntu (Wayland n'est pas encore au point, choisir Xorg)
Xubuntu
Mageia
Calculate Linux
BunsenLabs
CrunchBang++
**Compilation et utilisation**
Il est nécessaire d'avoir GCC (GNU compiler collection), pkg-config ainsi que les outils de développement (build-essential, sous Debian) pour pouvoir compiler le programme et obtenir un fichier exécutable.
L'application est liée aux bibliothèques partagées GTK+ 3 comme cela est indiqué dans le Makefile :
*# Liaison aux bibliothèques propres à GTK+ (version 3.0).*
*CPPLAGS=`` `pkg-config --cflags gtk+-3.0` ``*
*LDFLAGS=`` `pkg-config --libs gtk+-3.0` ``*
Ouvrir un terminal dans le répertoire du programme.
Pour compiler en mode optimisé :
$ make
Pour compiler en mode de débogage :
$ make debug
Pour exécuter le programme :
$ ./MenuCat
#include "config.h"
//// Privé.
#define ETECH_CONFIG_DIR "Estérel-Tech"
#define ETECH_CONF_DIR_PERMISSIONS 0755
#define ETECH_APP_CONF_FILE_NAME "MenuCat.conf"
#define CONF_GROUP_MENU "menu"
#define CONF_KEY_COORDS_LEFT "coords_left"
#define CONF_KEY_COORDS_TOP "coords_top"
#define CONF_KEY_TERM_CMD "term_cmd"
// Configuration par défaut au premier lancement de MenuCat.
#define CONF_DATA "#\n" \
"#Position du menu sur l'écran :\n" \
"#\n" \
"[menu]\n" \
"coords_left=4\n" \
"coords_top=100\n" \
"#Terminal à utiliser - ex. 'gnome-terminal --' " \
"'gnome-terminal --' ou 'x-terminal-emulator -e'.\n" \
"term_cmd="
struct stconfig
{
GKeyFile *key_file;
gchar *key_file_path;
gboolean is_loaded;
};
//// Public.
struct stconfig*
config_new()
{
struct stconfig *cfg = NULL;
cfg = (struct stconfig*)g_malloc(sizeof(struct stconfig));
if ( cfg != NULL ) {
cfg->key_file = NULL;
cfg->key_file_path = NULL;
cfg->is_loaded = FALSE;
}
cfg->key_file = g_key_file_new();
if ( cfg->key_file == NULL ) {
g_free(cfg);
cfg = NULL;
}
return cfg;
}
void
config_free(struct stconfig *cfg)
{
if ( cfg == NULL ) {
return;
}
if ( cfg->key_file_path != NULL ) {
g_free(cfg->key_file_path);
}
cfg->key_file_path = NULL;
if ( cfg->key_file != NULL ) {
g_key_file_free(cfg->key_file);
}
cfg->key_file = NULL;
g_free(cfg);
cfg = NULL;
}
/*
* Chargement du fichier de configuration.
* S'il n'existe pas déjà, le fichier est créé dans le répertoire dédié, ici :
* '/home/$USER/.config/ETECH_CONFIG_DIR/ETECH_APP_CONF_FILE_NAME'.
*/
gboolean
config_load(struct stconfig *cfg)
{
GError *error = NULL;
gchar *dir_path = NULL;
/*
* Répertoire de configuration de l'utilisateur en cours, normalement
* '/home/$USER/.config'.
*/
const gchar *user_cfg_dir = NULL;
user_cfg_dir = g_get_user_config_dir();
if ( ! user_cfg_dir ) {
return FALSE;
}
/*
* Création d'un répertoire 'ETECH_CONFIG_DIR' dans le répertoire de
* configuration de l'utilisateur s'il n'existe pas déjà, par exemple :
* '/home/$USER/.config/ETECH_CONFIG_DIR'
*/
dir_path = g_strdup_printf("%s%s%s",
user_cfg_dir,
G_DIR_SEPARATOR_S,
ETECH_CONFIG_DIR);
if ( ! dir_path ) {
return FALSE;
}
if ( ! g_file_test(dir_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) {
if ( g_mkdir(dir_path, ETECH_CONF_DIR_PERMISSIONS) != 0 ) {
g_print("Erreur à la création du répertoire %s\n", dir_path);
g_free(dir_path);
return FALSE;
}
}
/*
* Création d'un fichier de configuration dans ce répertoire, par exemple :
* '/home/$USER/.config/ETECH_CONFIG_DIR/ETECH_APP_CONF_FILE_NAME'.
*/
if ( ! g_key_file_load_from_data(cfg->key_file,
CONF_DATA,
-1,
G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
&error) ) {
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
g_free(dir_path);
return FALSE;
}
}
// Chemin vers le fichier.
cfg->key_file_path = g_strdup_printf("%s%s%s",
dir_path,
G_DIR_SEPARATOR_S,
ETECH_APP_CONF_FILE_NAME);
if ( cfg->key_file_path == NULL ) {
g_print("%s\n", "key_file_path = NULL");
g_free(dir_path);
return FALSE;
}
// Ne créer le fichier que s'il n'existe pas déjà.
if ( ! g_file_test(cfg->key_file_path,
G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR) ) {
if ( ! g_key_file_save_to_file(cfg->key_file,
cfg->key_file_path,
&error) ) {
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
g_free(dir_path);
return FALSE;
}
}
}
// Charger le fichier de configuration.
g_key_file_load_from_file(cfg->key_file,
cfg->key_file_path,
G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR,
&error);
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
g_free(dir_path);
return FALSE;
}
g_free(dir_path);
cfg->is_loaded = TRUE;
return TRUE;
}
gboolean
config_is_loaded(struct stconfig *cfg)
{
return cfg->is_loaded;
}
// Les coordonnées seront ileft et itop.
gboolean
config_set_menu_left(struct stconfig *cfg, gint ileft)
{
GError *error = NULL;
g_key_file_set_integer(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_COORDS_LEFT,
ileft);
if ( ! g_key_file_save_to_file(cfg->key_file,
cfg->key_file_path,
&error) ) {
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
}
return FALSE;
}
return TRUE;
}
gboolean
config_set_menu_top(struct stconfig *cfg, gint itop)
{
GError *error = NULL;
g_key_file_set_integer(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_COORDS_TOP,
itop);
if ( ! g_key_file_save_to_file(cfg->key_file,
cfg->key_file_path,
&error) ) {
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
}
return FALSE;
}
return TRUE;
}
gboolean
config_set_menu_coords(struct stconfig *cfg, gint ileft, gint itop)
{
GError *error = NULL;
g_key_file_set_integer(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_COORDS_LEFT,
ileft);
g_key_file_set_integer(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_COORDS_TOP,
itop);
if ( ! g_key_file_save_to_file(cfg->key_file,
cfg->key_file_path,
&error) ) {
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
}
return FALSE;
}
return TRUE;
}
gboolean
config_get_menu_coords(struct stconfig *cfg,
gint *ileft,
gint *itop)
{
GError *error = NULL;
gint _left = g_key_file_get_integer(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_COORDS_LEFT,
&error);
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
return FALSE;
}
gint _top = g_key_file_get_integer(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_COORDS_TOP,
&error);
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
return FALSE;
}
*ileft = _left;
*itop = _top;
return TRUE;
}
gboolean
config_set_terminal_command(struct stconfig *cfg, const gchar *tcmd)
{
GError *error = NULL;
g_key_file_set_string(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_TERM_CMD,
tcmd);
if ( ! g_key_file_save_to_file(cfg->key_file,
cfg->key_file_path,
&error) ) {
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
}
return FALSE;
}
return TRUE;
}
gchar*
config_get_terminal_command(struct stconfig *cfg)
{
GError *error = NULL;
gchar *_tcmd = g_key_file_get_string(cfg->key_file,
CONF_GROUP_MENU,
CONF_KEY_TERM_CMD,
&error);
if ( error ) {
g_print("%s\n", error->message);
g_error_free(error);
error = NULL;
return NULL;
}
// g_print("_tcmd = %s\n", _tcmd);
return _tcmd;
}
/*
Projet : Configuration pour une application GTK+.
Auteur : © Philippe Maréchal
Date : 12 janvier 2019
Version :
Notes :
Le module ne dérive pas de l'interface GObject bien qu'il utilise GLib.
Révisions :
13 janvier 2019 > structure 'stconfig' et permissions du fichier de
configuration : CONF_FILE_PERMISSIONS + 'cfg->key_file' est créé dans le
constructeur.
16 janvier 2019 > ETECH_CONF_DIR_PERMISSIONS (0700).
25 mars 2019 > possibilité de modifier les coordonnées séparément.
17 avril 2019 > adapté à l'application 'MenuCat' et correction d'un bogue
dans config_load(Config).
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#include <glib.h>
#include <glib/gstdio.h>
#define __unused __attribute__((unused))
#define __used __attribute__((used))
typedef struct stconfig *Config;
// Constructeur / destructeur.
Config
config_new(void);
void
config_free(Config);
// Chargement ou création du fichier.
gboolean
config_load(Config);
gboolean
config_is_loaded(Config cfg);
// Accesseurs.
gboolean
config_set_menu_left(Config cfg, gint ileft);
gboolean
config_set_menu_top(Config cfg, gint itop);
gboolean
config_set_menu_coords(Config, gint ileft, gint itop);
gboolean
config_get_menu_coords(Config, gint *ileft, gint *itop);
gboolean
config_set_terminal_command(Config cfg, const gchar *tcmd);
gchar*
config_get_terminal_command(Config cfg);
[file_prefs]
final_new_line=true
ensure_convert_new_lines=true
strip_trailing_spaces=true
replace_tabs=false
[indentation]
indent_width=4
indent_type=1
indent_hard_tab_width=4
detect_indent=false
detect_indent_width=false
indent_mode=3
[project]
name=etech-menucat
base_path=/home/philippe/devel/git/etech_menucat
description=
file_patterns=
[long line marker]
long_line_behaviour=1
long_line_column=80
[files]
current_page=10
FILE_NAME_0=20;Make;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2FMakefile;0;4
FILE_NAME_1=2458;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fmain.c;0;4
FILE_NAME_2=823;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fetechapp.h;0;4
FILE_NAME_3=788;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fetechapp.c;0;4
FILE_NAME_4=1364;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fetechappwin.h;0;4
FILE_NAME_5=13383;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fetechappwin.c;0;4
FILE_NAME_6=2188;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Foptions.h;0;4
FILE_NAME_7=1243;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Foptions.c;0;4
FILE_NAME_8=627;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fconfig.h;0;4
FILE_NAME_9=697;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fconfig.c;0;4
FILE_NAME_10=1007;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fetech_utils.h;0;4
FILE_NAME_11=120;C;0;EUTF-8;1;1;1;%2Fhome%2Fphilippe%2Fdevel%2Fgit%2Fetech_menucat%2Fetech_utils.c;0;4
[VTE]