Files
gKeyMapper/src/help.cpp

116 lines
4.8 KiB
C++
Raw Normal View History

2026-10-18 18:26:06 +02:00
// gKeyMapper - the help window.
//
// One page, no scrolling and no search: the program has nine rows and four
// types, so the help is a handful of paragraphs. Each paragraph is one
// translated string including its bold term, so a translator sees the sentence
// the user sees.
#include "help.h"
#include <glib/gi18n.h>
namespace gkeymapper {
namespace {
GtkWidget* helpWindow = nullptr;
// One paragraph: Pango markup (the bold term), wrapped at a readable width.
GtkWidget* paragraph(const char* text) {
GtkWidget* label = gtk_label_new(nullptr);
gtk_label_set_markup(GTK_LABEL(label), text);
gtk_label_set_wrap(GTK_LABEL(label), TRUE);
gtk_label_set_max_width_chars(GTK_LABEL(label), 62);
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
gtk_widget_set_halign(label, GTK_ALIGN_START);
return label;
}
void on_destroy(GtkWidget* /*widget*/, gpointer /*userData*/) {
helpWindow = nullptr;
}
const char* kParagraphs[] = {
N_("<b>The nine rows</b> – one per G key. Choose the type, then enter or capture the "
"target and press <i>Save mappings</i>."),
N_("<b>Key</b> – presses the captured sequence once, e.g. ctrl+c."),
N_("<b>Key (hold)</b> – presses it and keeps it down while the G key is held, e.g. for "
"push-to-talk. Only a single step can be held."),
N_("<b>Command</b> – runs a program or a command line, e.g. /usr/bin/firefox --new-window."),
N_("<b>Disabled</b> – the key does nothing."),
N_("<b>Capture</b> – records the keys you press next: press them, then <i>Done</i>. "
"Modifiers are kept (shift, altgr, …) and the names are layout independent, so ctrl+z "
"means the key that types z on your layout."),
N_("<b>Save mappings</b> – writes ~/.config/gKeyMapper/mappings.conf and makes the daemon "
"reload it. The menu entries <i>Export configuration...</i> and <i>Import "
"configuration...</i> do the same with a file you choose."),
N_("<b>Daemon status</b> – the footer shows whether gkeymapper-daemon is running, which "
"keyboard it found and the last G key that fired. <i>Options</i> shows the same in "
"more detail."),
N_("<b>Autostart</b> – <i>Start with the session</i> only opens this window when you log "
"in. The G keys work without it: gkeymapper-daemon (a user service) reads them and "
"replays the actions, and that daemon is the only part that has to run."),
N_("<b>Tray and window</b> – with <i>Minimize to tray</i> the window is hidden instead of "
"closed when you close or minimize it; the tray icon shows it again (<i>Show</i>) and "
"quits the program (<i>Close</i>). Starting gKeyMapper again closes the old window – "
"rows that were not saved are lost with it."),
};
} // namespace
void show_help_window(GtkWindow* parent) {
if (helpWindow != nullptr) {
gtk_window_present(GTK_WINDOW(helpWindow));
return;
}
GtkWidget* window = gtk_window_new();
gtk_window_set_title(GTK_WINDOW(window), _("Help"));
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
// Themed like the main window: same icon, same resource path (registered by
// build_ui, which always runs before the menu can be used).
gtk_window_set_icon_name(GTK_WINDOW(window), "gkeymapper");
if (parent != nullptr) {
gtk_window_set_transient_for(GTK_WINDOW(window), parent);
}
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_set_margin_top(box, 18);
gtk_widget_set_margin_bottom(box, 18);
gtk_widget_set_margin_start(box, 18);
gtk_widget_set_margin_end(box, 18);
gtk_window_set_child(GTK_WINDOW(window), box);
GtkWidget* heading = gtk_label_new(nullptr);
// The heading is the same word as the menu entry, only bigger; the markup is
// added around the translation so no translator has to carry tags for it.
g_autofree gchar* headingMarkup = g_strdup_printf("<big><b>%s</b></big>", _("Help"));
gtk_label_set_markup(GTK_LABEL(heading), headingMarkup);
gtk_label_set_xalign(GTK_LABEL(heading), 0.0f);
gtk_box_append(GTK_BOX(box), heading);
for (const char* text : kParagraphs) {
gtk_box_append(GTK_BOX(box), paragraph(_(text)));
}
GtkWidget* closeButton = gtk_button_new_with_label(_("Close window"));
gtk_widget_set_halign(closeButton, GTK_ALIGN_END);
g_signal_connect_swapped(closeButton, "clicked", G_CALLBACK(gtk_window_destroy), window);
gtk_box_append(GTK_BOX(box), closeButton);
g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), nullptr);
helpWindow = window;
gtk_window_present(GTK_WINDOW(window));
}
bool help_window_open() {
return helpWindow != nullptr;
}
void close_help_window() {
if (helpWindow != nullptr) {
gtk_window_destroy(GTK_WINDOW(helpWindow));
}
}
} // namespace gkeymapper