Files
gKeyMapper/src/help.cpp
2026-10-18 20:26:22 +02:00

116 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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> opens this window minimized to the tray "
"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 yet come along."),
};
} // 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