New locale
This commit is contained in:
78
AGENTS.md
Normal file
78
AGENTS.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# AGENTS.md
|
||||
|
||||
## What this is
|
||||
A pure GTK4 C++ GUI for remapping the G1–G9 keys of a Logitech G910. Today it
|
||||
only edits and persists mappings: there is **no** hardware G-key detection and
|
||||
**no** command execution yet (a native daemon is the planned next step). The
|
||||
whole program is one translation unit, `src/main.cpp`.
|
||||
|
||||
## Build / run / verify
|
||||
- `make` — builds the `gkeymapper` binary **and** the `.mo` catalogs.
|
||||
Needs `g++` (C++17), `make`, `gettext`, `libgtk-4-dev` (see README for
|
||||
`apt install` on a fresh machine).
|
||||
- `make translations` — only runs `msgfmt` on the existing `.po` files.
|
||||
- `make run` — builds, then runs with `GKEYMAPPER_LOCALEDIR=$PWD/locale` and
|
||||
`GKEYMAPPER_ASSETS_DIR=$PWD/assets` so the working-tree translations and
|
||||
assets are used. Plain `./gkeymapper` works too (assets fall back to
|
||||
`./assets`).
|
||||
- `make clean` — deletes the binary and the generated `locale/` tree.
|
||||
- No tests and no CI. Verify changes by building and running the app.
|
||||
|
||||
## i18n — easy to get wrong
|
||||
- English is the source language (the `msgid`) **and** also has an explicit
|
||||
identity catalog `po/en.po`. Languages: `de`, `en`, `es`, `fr`.
|
||||
- `make translations` does **not** regenerate the `.pot`. When you add or change
|
||||
a UI string, edit `po/gkeymapper.pot` and `po/*.po` by hand, then run
|
||||
`make translations`; validate with `msgfmt --check -o /dev/null po/<lang>.po`.
|
||||
- Never edit the generated `.mo` files under `locale/` (gitignored). Delete any
|
||||
`po/*.po~` backups before committing.
|
||||
- All documentation and source comments are English. German appears only inside
|
||||
`po/de.po`.
|
||||
|
||||
## Code layout and conventions
|
||||
- `src/main.cpp` holds everything in an anonymous namespace. The global `rows`
|
||||
vector keeps one `KeyRow` (widget pointers) per G key. `on_activate` registers
|
||||
the app actions `app.export-config`, `app.import-config`, `app.about`;
|
||||
`build_ui` constructs the window. App id: `com.example.gkeymapper`.
|
||||
- The Type dropdown index is meaningful everywhere: `0=Key`, `1=Command`,
|
||||
`2=Disabled`. Keep that order — import/export map against it.
|
||||
- The capture dialog's `CaptureSession` is heap-allocated and freed only by the
|
||||
window's `"destroy"` handler. Always close the dialog with
|
||||
`gtk_window_destroy` so the session is released.
|
||||
- Use GTK4 API only: `gtk_editable_set_text` / `gtk_editable_get_text` (there is
|
||||
no `gtk_entry_set_text`), `gtk_window_destroy` (no `gtk_dialog_run`),
|
||||
`G_APPLICATION_FLAGS_NONE`.
|
||||
- The main window is intentionally **non-resizable** and has **no**
|
||||
`GtkScrolledWindow` (one collapsed the rows earlier). Keep the fixed widths
|
||||
(Type dropdown 150 px, target entry 440 px min, action button 180 px) so rows
|
||||
do not jump when the language changes.
|
||||
- Because it is pure GTK4 it follows the system theme (Mint-Y ships a
|
||||
`gtk-4.0` theme). Do **not** add the `suggested-action` CSS class — Mint-Y
|
||||
tints it green and it clashes with the rest of the layout.
|
||||
|
||||
## Config file format
|
||||
`Save mappings` writes `~/.config/gKeyMapper/mappings.conf`; Export/Import use
|
||||
the same format:
|
||||
|
||||
```
|
||||
G1=key:ctrl+c,ctrl+v
|
||||
G2=command:/usr/bin/firefox
|
||||
G3=disabled:
|
||||
```
|
||||
|
||||
`<type>:<target>`, one line per key. `key` is a captured sequence (lowercase
|
||||
`gdk_keyval_name` output; modifiers joined with `+`, steps joined with `,`),
|
||||
`command` is a program/file path, `disabled` is inactive.
|
||||
|
||||
## Assets
|
||||
`find_asset()` resolves in order: `$GKEYMAPPER_ASSETS_DIR` → `./assets` →
|
||||
compiled-in `ASSETS_DIR` (`/usr/local/share/gkeymapper/assets`). The icon
|
||||
(`assets/icon.png`) is used in the header bar and the About dialog.
|
||||
|
||||
## Driving the GUI for manual checks
|
||||
There is no `xdotool`/`wtype` on this machine, and the capture-dialog buttons
|
||||
(`Clear`/`Cancel`/`Done`) expose an empty AT-SPI accessible name — the text is in
|
||||
a child `label` node, so target the button by its child label. `pyatspi`
|
||||
(`queryAction().doAction(0)`) plus `Xlib`'s `xtest.fake_input` can click buttons
|
||||
and inject keys. Warn the user before synthesizing keystrokes or stealing window
|
||||
focus.
|
||||
32
README.md
32
README.md
@@ -81,6 +81,38 @@ make clean
|
||||
|
||||
Removes the binary and the generated `locale/` directory.
|
||||
|
||||
## Capturing key sequences
|
||||
|
||||
For rows of type **Key**, the action button opens a capture dialog:
|
||||
|
||||
- Press keys one after another; each press becomes one step.
|
||||
- Modifier keys (Ctrl, Alt, Shift, Super) held during a press are recorded
|
||||
as part of that step.
|
||||
- The live preview shows the sequence. `Clear` resets it, `Done` writes it
|
||||
into the row, `Cancel` discards it.
|
||||
|
||||
The sequence uses the same format as
|
||||
[g910-gkey-macro-support](https://github.com/JSubelj/g910-gkey-macro-support):
|
||||
modifiers are joined with `+`, steps are separated with `,`
|
||||
(e.g. `ctrl+c,ctrl+v` or `shift+f4,super+t`).
|
||||
|
||||
## Configuration format
|
||||
|
||||
`Save mappings` writes `~/.config/gKeyMapper/mappings.conf`:
|
||||
|
||||
```
|
||||
# gKeyMapper mappings (G1..G9)
|
||||
G1=key:ctrl+c,ctrl+v
|
||||
G2=command:/usr/bin/firefox
|
||||
G3=disabled:
|
||||
```
|
||||
|
||||
The same format is used by Export/Import. `key` holds a captured shortcut
|
||||
sequence, `command` a program or file path, `disabled` ignores the G key
|
||||
(similar to the `shortcut` / `run` / `nothing` hotkey types of the
|
||||
reference project above; a native C++ daemon for G-key detection and
|
||||
replay is planned next, no Python involved).
|
||||
|
||||
## Project structure
|
||||
|
||||
```
|
||||
|
||||
66
po/de.po
66
po/de.po
@@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:53+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 21:00+0000\n"
|
||||
"POT-Creation-Date: 2026-10-16 22:12+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 22:12+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de\n"
|
||||
@@ -15,124 +15,116 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main.cpp:53
|
||||
msgid "Choose file"
|
||||
msgstr "Datei auswählen"
|
||||
|
||||
#: src/main.cpp:56 src/main.cpp:224 src/main.cpp:236
|
||||
msgid "_Cancel"
|
||||
msgstr "_Abbrechen"
|
||||
|
||||
#: src/main.cpp:57 src/main.cpp:237
|
||||
msgid "_Open"
|
||||
msgstr "_Öffnen"
|
||||
|
||||
#: src/main.cpp:75
|
||||
msgid "<Press a key...>"
|
||||
msgstr "<Taste drücken...>"
|
||||
msgid "No keys recorded yet"
|
||||
msgstr "Noch keine Tasten aufgezeichnet"
|
||||
|
||||
msgid "Capture key sequence"
|
||||
msgstr "Tastensequenz aufnehmen"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "Leeren"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
msgid "Done"
|
||||
msgstr "Fertig"
|
||||
|
||||
msgid ""
|
||||
"Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded "
|
||||
"too). Click Done to apply or Cancel to discard."
|
||||
msgstr ""
|
||||
"Tasten der Reihe nach drücken (Modifikatoren wie Strg, Alt, Shift und Super "
|
||||
"werden mit aufgezeichnet). Mit Fertig übernehmen oder mit Abbrechen verwerfen."
|
||||
|
||||
#: src/main.cpp:87
|
||||
msgid "Choose file..."
|
||||
msgstr "Datei auswählen..."
|
||||
|
||||
#: src/main.cpp:89 src/main.cpp:364
|
||||
msgid "e.g. /usr/bin/firefox or custom command"
|
||||
msgstr "z. B. /usr/bin/firefox oder eigener Befehl"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Aufnehmen"
|
||||
|
||||
#: src/main.cpp:125
|
||||
msgid "e.g. ctrl+c, ctrl+v"
|
||||
msgstr "z. B. Strg+C, Strg+V"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "Konnte %s nicht speichern.\n"
|
||||
|
||||
#: src/main.cpp:129
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Mappings gespeichert nach "
|
||||
|
||||
#: src/main.cpp:135
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "Konnte %s nicht öffnen.\n"
|
||||
|
||||
#: src/main.cpp:187
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "Mappings konnten nicht exportiert werden.\n"
|
||||
|
||||
#: src/main.cpp:210 src/main.cpp:273
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
#: src/main.cpp:213
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "G-Key-Mapper für die Logitech G910 (GTK4)."
|
||||
|
||||
#: src/main.cpp:221
|
||||
msgid "Export configuration"
|
||||
msgstr "Konfiguration exportieren"
|
||||
|
||||
#: src/main.cpp:225
|
||||
msgid "_Save"
|
||||
msgstr "_Speichern"
|
||||
|
||||
#: src/main.cpp:233
|
||||
msgid "Import configuration"
|
||||
msgstr "Konfiguration importieren"
|
||||
|
||||
#: src/main.cpp:269
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
#: src/main.cpp:277
|
||||
msgid "Export configuration..."
|
||||
msgstr "Konfiguration exportieren..."
|
||||
|
||||
#: src/main.cpp:278
|
||||
msgid "Import configuration..."
|
||||
msgstr "Konfiguration importieren..."
|
||||
|
||||
#: src/main.cpp:281
|
||||
msgid "About"
|
||||
msgstr "Über"
|
||||
|
||||
#: src/main.cpp:305
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr "G1 bis G9 der Logitech G910 auf Tasten oder Befehle ummappen"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "G-Key"
|
||||
msgstr "G-Taste"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Ziel (Taste/Befehl)"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Action"
|
||||
msgstr "Aktion"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Key"
|
||||
msgstr "Taste"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Command"
|
||||
msgstr "Befehl"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktiviert"
|
||||
|
||||
#: src/main.cpp:358
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr "z. B. Strg+C oder ls -la"
|
||||
|
||||
#: src/main.cpp:378
|
||||
msgid "Save mappings"
|
||||
msgstr "Mappings speichern"
|
||||
|
||||
#: src/main.cpp:383
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Gespeichert in ~/.config/gKeyMapper/mappings.conf"
|
||||
|
||||
102
po/de.po~
102
po/de.po~
@@ -1,102 +0,0 @@
|
||||
# German translation for gkeymapper.
|
||||
# Copyright (C) 2026
|
||||
# This file is distributed under the same license as the gkeymapper package.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:00+0000\n"
|
||||
"PO-Revision-Date: 2026-10-16 21:00+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "<Press a key...>"
|
||||
msgstr "<Taste drücken...>"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "Konnte %s nicht speichern.\n"
|
||||
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Mappings gespeichert nach "
|
||||
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "Konnte %s nicht öffnen.\n"
|
||||
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "Mappings konnten nicht exportiert werden.\n"
|
||||
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "G-Key-Mapper für die Logitech G910 (GTK4)."
|
||||
|
||||
msgid "Export configuration"
|
||||
msgstr "Konfiguration exportieren"
|
||||
|
||||
msgid "_Cancel"
|
||||
msgstr "_Abbrechen"
|
||||
|
||||
msgid "_Save"
|
||||
msgstr "_Speichern"
|
||||
|
||||
msgid "Import configuration"
|
||||
msgstr "Konfiguration importieren"
|
||||
|
||||
msgid "_Open"
|
||||
msgstr "_Öffnen"
|
||||
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
msgid "Export configuration..."
|
||||
msgstr "Konfiguration exportieren..."
|
||||
|
||||
msgid "Import configuration..."
|
||||
msgstr "Konfiguration importieren..."
|
||||
|
||||
msgid "About"
|
||||
msgstr "Über"
|
||||
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr "G1 bis G9 der Logitech G910 auf Tasten oder Befehle ummappen"
|
||||
|
||||
msgid "G-Key"
|
||||
msgstr "G-Taste"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Ziel (Taste/Befehl)"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Aktion"
|
||||
|
||||
msgid "Key"
|
||||
msgstr "Taste"
|
||||
|
||||
msgid "Command"
|
||||
msgstr "Befehl"
|
||||
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktiviert"
|
||||
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr "z. B. Strg+C oder ls -la"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Aufnehmen"
|
||||
|
||||
msgid "Save mappings"
|
||||
msgstr "Mappings speichern"
|
||||
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Gespeichert in ~/.config/gKeyMapper/mappings.conf"
|
||||
131
po/en.po
Normal file
131
po/en.po
Normal file
@@ -0,0 +1,131 @@
|
||||
# English translation for gkeymapper.
|
||||
# Copyright (C) 2026
|
||||
# This file is distributed under the same license as the gkeymapper package.
|
||||
# English is the source language; this catalog keeps the strings explicit.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 22:12+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 22:12+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: English\n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "Choose file"
|
||||
msgstr "Choose file"
|
||||
|
||||
msgid "_Cancel"
|
||||
msgstr "_Cancel"
|
||||
|
||||
msgid "_Open"
|
||||
msgstr "_Open"
|
||||
|
||||
msgid "No keys recorded yet"
|
||||
msgstr "No keys recorded yet"
|
||||
|
||||
msgid "Capture key sequence"
|
||||
msgstr "Capture key sequence"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "Clear"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
msgid ""
|
||||
"Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded "
|
||||
"too). Click Done to apply or Cancel to discard."
|
||||
msgstr ""
|
||||
"Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded "
|
||||
"too). Click Done to apply or Cancel to discard."
|
||||
|
||||
msgid "Choose file..."
|
||||
msgstr "Choose file..."
|
||||
|
||||
msgid "e.g. /usr/bin/firefox or custom command"
|
||||
msgstr "e.g. /usr/bin/firefox or custom command"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Capture"
|
||||
|
||||
msgid "e.g. ctrl+c, ctrl+v"
|
||||
msgstr "e.g. ctrl+c, ctrl+v"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "Could not save %s.\n"
|
||||
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Mappings saved to "
|
||||
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "Could not open %s.\n"
|
||||
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "Could not export mappings.\n"
|
||||
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
|
||||
msgid "Export configuration"
|
||||
msgstr "Export configuration"
|
||||
|
||||
msgid "_Save"
|
||||
msgstr "_Save"
|
||||
|
||||
msgid "Import configuration"
|
||||
msgstr "Import configuration"
|
||||
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
msgid "Export configuration..."
|
||||
msgstr "Export configuration..."
|
||||
|
||||
msgid "Import configuration..."
|
||||
msgstr "Import configuration..."
|
||||
|
||||
msgid "About"
|
||||
msgstr "About"
|
||||
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
|
||||
msgid "G-Key"
|
||||
msgstr "G-Key"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Target (Key/Command)"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
msgid "Key"
|
||||
msgstr "Key"
|
||||
|
||||
msgid "Command"
|
||||
msgstr "Command"
|
||||
|
||||
msgid "Disabled"
|
||||
msgstr "Disabled"
|
||||
|
||||
msgid "Save mappings"
|
||||
msgstr "Save mappings"
|
||||
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
67
po/es.po
67
po/es.po
@@ -4,8 +4,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:53+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 21:00+0000\n"
|
||||
"POT-Creation-Date: 2026-10-16 22:12+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 22:12+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Language: es\n"
|
||||
@@ -13,124 +13,117 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main.cpp:53
|
||||
msgid "Choose file"
|
||||
msgstr "Elegir archivo"
|
||||
|
||||
#: src/main.cpp:56 src/main.cpp:224 src/main.cpp:236
|
||||
msgid "_Cancel"
|
||||
msgstr "_Cancelar"
|
||||
|
||||
#: src/main.cpp:57 src/main.cpp:237
|
||||
msgid "_Open"
|
||||
msgstr "_Abrir"
|
||||
|
||||
#: src/main.cpp:75
|
||||
msgid "<Press a key...>"
|
||||
msgstr "<Pulsa una tecla...>"
|
||||
msgid "No keys recorded yet"
|
||||
msgstr "Aún no se ha registrado ninguna tecla"
|
||||
|
||||
msgid "Capture key sequence"
|
||||
msgstr "Capturar secuencia de teclas"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "Borrar"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
msgid "Done"
|
||||
msgstr "Aceptar"
|
||||
|
||||
msgid ""
|
||||
"Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded "
|
||||
"too). Click Done to apply or Cancel to discard."
|
||||
msgstr ""
|
||||
"Pulsa las teclas en orden (los modificadores como Ctrl, Alt, Mayús y Super "
|
||||
"también se registran). Haz clic en Aceptar para aplicar o en Cancelar para "
|
||||
"descartar."
|
||||
|
||||
#: src/main.cpp:87
|
||||
msgid "Choose file..."
|
||||
msgstr "Elegir archivo..."
|
||||
|
||||
#: src/main.cpp:89 src/main.cpp:364
|
||||
msgid "e.g. /usr/bin/firefox or custom command"
|
||||
msgstr "p. ej. /usr/bin/firefox o comando personalizado"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Capturar"
|
||||
|
||||
#: src/main.cpp:125
|
||||
msgid "e.g. ctrl+c, ctrl+v"
|
||||
msgstr "p. ej. ctrl+c, ctrl+v"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "No se pudo guardar %s.\n"
|
||||
|
||||
#: src/main.cpp:129
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Asignaciones guardadas en "
|
||||
|
||||
#: src/main.cpp:135
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "No se pudo abrir %s.\n"
|
||||
|
||||
#: src/main.cpp:187
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "No se pudieron exportar las asignaciones.\n"
|
||||
|
||||
#: src/main.cpp:210 src/main.cpp:273
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
#: src/main.cpp:213
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "Asignador de teclas G para el Logitech G910 (GTK4)."
|
||||
|
||||
#: src/main.cpp:221
|
||||
msgid "Export configuration"
|
||||
msgstr "Exportar configuración"
|
||||
|
||||
#: src/main.cpp:225
|
||||
msgid "_Save"
|
||||
msgstr "_Guardar"
|
||||
|
||||
#: src/main.cpp:233
|
||||
msgid "Import configuration"
|
||||
msgstr "Importar configuración"
|
||||
|
||||
#: src/main.cpp:269
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
#: src/main.cpp:277
|
||||
msgid "Export configuration..."
|
||||
msgstr "Exportar configuración..."
|
||||
|
||||
#: src/main.cpp:278
|
||||
msgid "Import configuration..."
|
||||
msgstr "Importar configuración..."
|
||||
|
||||
#: src/main.cpp:281
|
||||
msgid "About"
|
||||
msgstr "Acerca de"
|
||||
|
||||
#: src/main.cpp:305
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr "Reasigna las G1 a G9 del Logitech G910 a teclas o comandos"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "G-Key"
|
||||
msgstr "Tecla G"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Destino (Tecla/Comando)"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Action"
|
||||
msgstr "Acción"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Key"
|
||||
msgstr "Tecla"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Command"
|
||||
msgstr "Comando"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Disabled"
|
||||
msgstr "Desactivado"
|
||||
|
||||
#: src/main.cpp:358
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr "p. ej. ctrl+c o ls -la"
|
||||
|
||||
#: src/main.cpp:378
|
||||
msgid "Save mappings"
|
||||
msgstr "Guardar asignaciones"
|
||||
|
||||
#: src/main.cpp:383
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Guardado en ~/.config/gKeyMapper/mappings.conf"
|
||||
|
||||
100
po/es.po~
100
po/es.po~
@@ -1,100 +0,0 @@
|
||||
# Spanish translation for gkeymapper.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:00+0000\n"
|
||||
"PO-Revision-Date: 2026-10-16 21:00+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "<Press a key...>"
|
||||
msgstr "<Pulsa una tecla...>"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "No se pudo guardar %s.\n"
|
||||
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Asignaciones guardadas en "
|
||||
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "No se pudo abrir %s.\n"
|
||||
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "No se pudieron exportar las asignaciones.\n"
|
||||
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "Asignador de teclas G para el Logitech G910 (GTK4)."
|
||||
|
||||
msgid "Export configuration"
|
||||
msgstr "Exportar configuración"
|
||||
|
||||
msgid "_Cancel"
|
||||
msgstr "_Cancelar"
|
||||
|
||||
msgid "_Save"
|
||||
msgstr "_Guardar"
|
||||
|
||||
msgid "Import configuration"
|
||||
msgstr "Importar configuración"
|
||||
|
||||
msgid "_Open"
|
||||
msgstr "_Abrir"
|
||||
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
msgid "Export configuration..."
|
||||
msgstr "Exportar configuración..."
|
||||
|
||||
msgid "Import configuration..."
|
||||
msgstr "Importar configuración..."
|
||||
|
||||
msgid "About"
|
||||
msgstr "Acerca de"
|
||||
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr "Reasigna las G1 a G9 del Logitech G910 a teclas o comandos"
|
||||
|
||||
msgid "G-Key"
|
||||
msgstr "Tecla G"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Destino (Tecla/Comando)"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Acción"
|
||||
|
||||
msgid "Key"
|
||||
msgstr "Tecla"
|
||||
|
||||
msgid "Command"
|
||||
msgstr "Comando"
|
||||
|
||||
msgid "Disabled"
|
||||
msgstr "Desactivado"
|
||||
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr "p. ej. ctrl+c o ls -la"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Capturar"
|
||||
|
||||
msgid "Save mappings"
|
||||
msgstr "Guardar asignaciones"
|
||||
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Guardado en ~/.config/gKeyMapper/mappings.conf"
|
||||
71
po/fr.po
71
po/fr.po
@@ -4,8 +4,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:53+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 21:00+0000\n"
|
||||
"POT-Creation-Date: 2026-10-16 22:12+0200\n"
|
||||
"PO-Revision-Date: 2026-10-16 22:12+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr\n"
|
||||
@@ -13,126 +13,117 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main.cpp:53
|
||||
msgid "Choose file"
|
||||
msgstr "Choisir un fichier"
|
||||
|
||||
#: src/main.cpp:56 src/main.cpp:224 src/main.cpp:236
|
||||
msgid "_Cancel"
|
||||
msgstr "_Annuler"
|
||||
|
||||
#: src/main.cpp:57 src/main.cpp:237
|
||||
msgid "_Open"
|
||||
msgstr "_Ouvrir"
|
||||
|
||||
#: src/main.cpp:75
|
||||
msgid "<Press a key...>"
|
||||
msgstr "<Appuyez sur une touche...>"
|
||||
msgid "No keys recorded yet"
|
||||
msgstr "Aucune touche enregistrée pour le moment"
|
||||
|
||||
msgid "Capture key sequence"
|
||||
msgstr "Capturer une séquence de touches"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "Effacer"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
msgid "Done"
|
||||
msgstr "Terminer"
|
||||
|
||||
msgid ""
|
||||
"Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded "
|
||||
"too). Click Done to apply or Cancel to discard."
|
||||
msgstr ""
|
||||
"Appuyez sur les touches dans l'ordre (les modificateurs comme Ctrl, Alt, "
|
||||
"Maj et Super sont également enregistrés). Cliquez sur Terminer pour "
|
||||
"appliquer ou sur Annuler pour abandonner."
|
||||
|
||||
#: src/main.cpp:87
|
||||
msgid "Choose file..."
|
||||
msgstr "Choisir un fichier..."
|
||||
|
||||
#: src/main.cpp:89 src/main.cpp:364
|
||||
msgid "e.g. /usr/bin/firefox or custom command"
|
||||
msgstr "ex. /usr/bin/firefox ou commande personnalisée"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Capturer"
|
||||
|
||||
#: src/main.cpp:125
|
||||
msgid "e.g. ctrl+c, ctrl+v"
|
||||
msgstr "ex. ctrl+c, ctrl+v"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "Impossible d'enregistrer %s.\n"
|
||||
|
||||
#: src/main.cpp:129
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Attributions enregistrées dans "
|
||||
|
||||
#: src/main.cpp:135
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "Impossible d'ouvrir %s.\n"
|
||||
|
||||
#: src/main.cpp:187
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "Impossible d'exporter les attributions.\n"
|
||||
|
||||
#: src/main.cpp:210 src/main.cpp:273
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
#: src/main.cpp:213
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "Assignateur de touches G pour le Logitech G910 (GTK4)."
|
||||
|
||||
#: src/main.cpp:221
|
||||
msgid "Export configuration"
|
||||
msgstr "Exporter la configuration"
|
||||
|
||||
#: src/main.cpp:225
|
||||
msgid "_Save"
|
||||
msgstr "_Enregistrer"
|
||||
|
||||
#: src/main.cpp:233
|
||||
msgid "Import configuration"
|
||||
msgstr "Importer la configuration"
|
||||
|
||||
#: src/main.cpp:269
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
#: src/main.cpp:277
|
||||
msgid "Export configuration..."
|
||||
msgstr "Exporter la configuration..."
|
||||
|
||||
#: src/main.cpp:278
|
||||
msgid "Import configuration..."
|
||||
msgstr "Importer la configuration..."
|
||||
|
||||
#: src/main.cpp:281
|
||||
msgid "About"
|
||||
msgstr "À propos"
|
||||
|
||||
#: src/main.cpp:305
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr ""
|
||||
"Réassignation des touches G1 à G9 du Logitech G910 vers des touches ou des "
|
||||
"commandes"
|
||||
msgstr "Réassignation des touches G1 à G9 du Logitech G910 vers des touches ou des commandes"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "G-Key"
|
||||
msgstr "Touche G"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Cible (Touche/Commande)"
|
||||
|
||||
#: src/main.cpp:327
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Key"
|
||||
msgstr "Touche"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Command"
|
||||
msgstr "Commande"
|
||||
|
||||
#: src/main.cpp:335
|
||||
msgid "Disabled"
|
||||
msgstr "Désactivé"
|
||||
|
||||
#: src/main.cpp:358
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr "ex. ctrl+c ou ls -la"
|
||||
|
||||
#: src/main.cpp:378
|
||||
msgid "Save mappings"
|
||||
msgstr "Enregistrer les attributions"
|
||||
|
||||
#: src/main.cpp:383
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Enregistré dans ~/.config/gKeyMapper/mappings.conf"
|
||||
|
||||
100
po/fr.po~
100
po/fr.po~
@@ -1,100 +0,0 @@
|
||||
# French translation for gkeymapper.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:00+0000\n"
|
||||
"PO-Revision-Date: 2026-10-16 21:00+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "<Press a key...>"
|
||||
msgstr "<Appuyez sur une touche...>"
|
||||
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr "Impossible d'enregistrer %s.\n"
|
||||
|
||||
msgid "Mappings saved to "
|
||||
msgstr "Attributions enregistrées dans "
|
||||
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr "Impossible d'ouvrir %s.\n"
|
||||
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr "Impossible d'exporter les attributions.\n"
|
||||
|
||||
msgid "gKeyMapper"
|
||||
msgstr "gKeyMapper"
|
||||
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr "Assignateur de touches G pour le Logitech G910 (GTK4)."
|
||||
|
||||
msgid "Export configuration"
|
||||
msgstr "Exporter la configuration"
|
||||
|
||||
msgid "_Cancel"
|
||||
msgstr "_Annuler"
|
||||
|
||||
msgid "_Save"
|
||||
msgstr "_Enregistrer"
|
||||
|
||||
msgid "Import configuration"
|
||||
msgstr "Importer la configuration"
|
||||
|
||||
msgid "_Open"
|
||||
msgstr "_Ouvrir"
|
||||
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr "gKeyMapper – Logitech G910"
|
||||
|
||||
msgid "Export configuration..."
|
||||
msgstr "Exporter la configuration..."
|
||||
|
||||
msgid "Import configuration..."
|
||||
msgstr "Importer la configuration..."
|
||||
|
||||
msgid "About"
|
||||
msgstr "À propos"
|
||||
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr "Réassignation des touches G1 à G9 du Logitech G910 vers des touches ou des commandes"
|
||||
|
||||
msgid "G-Key"
|
||||
msgstr "Touche G"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr "Cible (Touche/Commande)"
|
||||
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
msgid "Key"
|
||||
msgstr "Touche"
|
||||
|
||||
msgid "Command"
|
||||
msgstr "Commande"
|
||||
|
||||
msgid "Disabled"
|
||||
msgstr "Désactivé"
|
||||
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr "ex. ctrl+c ou ls -la"
|
||||
|
||||
msgid "Capture"
|
||||
msgstr "Capturer"
|
||||
|
||||
msgid "Save mappings"
|
||||
msgstr "Enregistrer les attributions"
|
||||
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr "Enregistré dans ~/.config/gKeyMapper/mappings.conf"
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-16 21:53+0200\n"
|
||||
"POT-Creation-Date: 2026-10-16 22:12+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -17,124 +17,150 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main.cpp:53
|
||||
#: src/main.cpp:55
|
||||
msgid "Choose file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:56 src/main.cpp:224 src/main.cpp:236
|
||||
#: src/main.cpp:58 src/main.cpp:419 src/main.cpp:431
|
||||
msgid "_Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:57 src/main.cpp:237
|
||||
#: src/main.cpp:59 src/main.cpp:432
|
||||
msgid "_Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:75
|
||||
msgid "<Press a key...>"
|
||||
#: src/main.cpp:129 src/main.cpp:218
|
||||
msgid "No keys recorded yet"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:87
|
||||
#: src/main.cpp:187
|
||||
msgid "Capture key sequence"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:191
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:192
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:193
|
||||
msgid "Done"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:213
|
||||
msgid ""
|
||||
"Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded "
|
||||
"too). Click Done to apply or Cancel to discard."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:263
|
||||
msgid "Choose file..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:89 src/main.cpp:364
|
||||
#: src/main.cpp:265
|
||||
msgid "e.g. /usr/bin/firefox or custom command"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:267 src/main.cpp:586
|
||||
msgid "Capture"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:125
|
||||
#: src/main.cpp:269 src/main.cpp:579
|
||||
msgid "e.g. ctrl+c, ctrl+v"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:306
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:129
|
||||
#: src/main.cpp:310
|
||||
msgid "Mappings saved to "
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:135
|
||||
#: src/main.cpp:316
|
||||
#, c-format
|
||||
msgid "Could not open %s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:187
|
||||
#: src/main.cpp:368
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:210 src/main.cpp:273
|
||||
#: src/main.cpp:393 src/main.cpp:499
|
||||
msgid "gKeyMapper"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:213
|
||||
#: src/main.cpp:396
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:221
|
||||
#: src/main.cpp:416
|
||||
msgid "Export configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:225
|
||||
#: src/main.cpp:420
|
||||
msgid "_Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:233
|
||||
#: src/main.cpp:428
|
||||
msgid "Import configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:269
|
||||
#: src/main.cpp:488
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:277
|
||||
#: src/main.cpp:503
|
||||
msgid "Export configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:278
|
||||
#: src/main.cpp:504
|
||||
msgid "Import configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:281
|
||||
#: src/main.cpp:507
|
||||
msgid "About"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:305
|
||||
#: src/main.cpp:531
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:327
|
||||
#: src/main.cpp:548
|
||||
msgid "G-Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:327
|
||||
#: src/main.cpp:548
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:327
|
||||
#: src/main.cpp:548
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:327
|
||||
#: src/main.cpp:548
|
||||
msgid "Action"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:335
|
||||
#: src/main.cpp:556
|
||||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:335
|
||||
#: src/main.cpp:556
|
||||
msgid "Command"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:335
|
||||
#: src/main.cpp:556
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:358
|
||||
msgid "e.g. ctrl+c or ls -la"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:378
|
||||
#: src/main.cpp:603
|
||||
msgid "Save mappings"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:383
|
||||
#: src/main.cpp:608
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr ""
|
||||
|
||||
229
src/main.cpp
229
src/main.cpp
@@ -4,10 +4,12 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <locale.h>
|
||||
#include <libintl.h>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -60,20 +62,227 @@ static void pick_command_file(KeyRow* row, GtkWindow* parent) {
|
||||
gtk_window_present(GTK_WINDOW(dialog));
|
||||
}
|
||||
|
||||
struct CaptureSession {
|
||||
KeyRow* row = nullptr;
|
||||
GtkWidget* displayLabel = nullptr;
|
||||
std::vector<std::string> steps;
|
||||
std::set<guint> heldKeys; // non-modifier keyvals currently held (ignores auto-repeat)
|
||||
};
|
||||
|
||||
static bool is_modifier_keyval(guint keyval) {
|
||||
switch (keyval) {
|
||||
case GDK_KEY_Control_L:
|
||||
case GDK_KEY_Control_R:
|
||||
case GDK_KEY_Alt_L:
|
||||
case GDK_KEY_Alt_R:
|
||||
case GDK_KEY_Shift_L:
|
||||
case GDK_KEY_Shift_R:
|
||||
case GDK_KEY_Super_L:
|
||||
case GDK_KEY_Super_R:
|
||||
case GDK_KEY_Meta_L:
|
||||
case GDK_KEY_Meta_R:
|
||||
case GDK_KEY_ISO_Level3_Shift: // AltGr
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Format one step like the reference project: modifiers joined with '+',
|
||||
// e.g. "ctrl+shift+t". Multiple steps are joined with ',' ("ctrl+c,ctrl+v").
|
||||
static std::string format_capture_step(GdkModifierType state, guint keyval) {
|
||||
std::string step;
|
||||
if (state & GDK_CONTROL_MASK) {
|
||||
step += "ctrl+";
|
||||
}
|
||||
if (state & GDK_ALT_MASK) {
|
||||
step += "alt+";
|
||||
}
|
||||
if (state & GDK_SHIFT_MASK) {
|
||||
step += "shift+";
|
||||
}
|
||||
if (state & (GDK_SUPER_MASK | GDK_META_MASK)) {
|
||||
step += "super+";
|
||||
}
|
||||
const char* name = gdk_keyval_name(keyval);
|
||||
std::string key = name ? name : "?";
|
||||
std::transform(key.begin(), key.end(), key.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
step += key;
|
||||
return step;
|
||||
}
|
||||
|
||||
static std::string join_capture_steps(const std::vector<std::string>& steps) {
|
||||
std::string out;
|
||||
for (size_t i = 0; i < steps.size(); ++i) {
|
||||
if (i > 0) {
|
||||
out += ",";
|
||||
}
|
||||
out += steps[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void update_capture_display(CaptureSession* session) {
|
||||
std::string text = join_capture_steps(session->steps);
|
||||
if (text.empty()) {
|
||||
text = _("No keys recorded yet");
|
||||
}
|
||||
gtk_label_set_text(GTK_LABEL(session->displayLabel), text.c_str());
|
||||
}
|
||||
|
||||
static gboolean on_capture_key_pressed(GtkEventControllerKey* /*controller*/,
|
||||
guint keyval, guint /*keycode*/,
|
||||
GdkModifierType state, gpointer userData) {
|
||||
auto* session = static_cast<CaptureSession*>(userData);
|
||||
if (is_modifier_keyval(keyval)) {
|
||||
return TRUE; // modifiers are recorded as part of the next real key
|
||||
}
|
||||
if (session->heldKeys.count(keyval)) {
|
||||
return TRUE; // ignore auto-repeat while the key is held down
|
||||
}
|
||||
session->heldKeys.insert(keyval);
|
||||
constexpr GdkModifierType kModMask = static_cast<GdkModifierType>(
|
||||
GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_ALT_MASK |
|
||||
GDK_SUPER_MASK | GDK_META_MASK);
|
||||
session->steps.push_back(format_capture_step(
|
||||
static_cast<GdkModifierType>(state & kModMask), keyval));
|
||||
update_capture_display(session);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean on_capture_key_released(GtkEventControllerKey* /*controller*/,
|
||||
guint keyval, guint /*keycode*/,
|
||||
GdkModifierType /*state*/, gpointer userData) {
|
||||
auto* session = static_cast<CaptureSession*>(userData);
|
||||
session->heldKeys.erase(keyval);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_capture_session_destroy(GtkWidget* /*widget*/, gpointer userData) {
|
||||
delete static_cast<CaptureSession*>(userData);
|
||||
}
|
||||
|
||||
static void on_capture_done_clicked(GtkButton* btn, gpointer userData) {
|
||||
auto* session = static_cast<CaptureSession*>(userData);
|
||||
if (!session->steps.empty()) {
|
||||
gtk_editable_set_text(GTK_EDITABLE(session->row->targetEntry),
|
||||
join_capture_steps(session->steps).c_str());
|
||||
}
|
||||
GtkWindow* window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(btn)));
|
||||
gtk_window_destroy(window); // triggers session cleanup via "destroy"
|
||||
}
|
||||
|
||||
static void on_capture_cancel_clicked(GtkButton* btn, gpointer /*userData*/) {
|
||||
GtkWindow* window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(btn)));
|
||||
gtk_window_destroy(window); // triggers session cleanup via "destroy"
|
||||
}
|
||||
|
||||
static void on_capture_clear_clicked(GtkButton* /*btn*/, gpointer userData) {
|
||||
auto* session = static_cast<CaptureSession*>(userData);
|
||||
session->steps.clear();
|
||||
session->heldKeys.clear();
|
||||
update_capture_display(session);
|
||||
}
|
||||
|
||||
static void open_key_capture_dialog(KeyRow* row, GtkWindow* parent) {
|
||||
auto* session = new CaptureSession();
|
||||
session->row = row;
|
||||
|
||||
GtkWidget* dialog = gtk_window_new();
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), _("Capture key sequence"));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
|
||||
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dialog), 540, 300);
|
||||
g_signal_connect(dialog, "destroy", G_CALLBACK(on_capture_session_destroy), session);
|
||||
|
||||
GtkWidget* outer = gtk_box_new(GTK_ORIENTATION_VERTICAL, 16);
|
||||
gtk_widget_set_margin_top(outer, 20);
|
||||
gtk_widget_set_margin_bottom(outer, 20);
|
||||
gtk_widget_set_margin_start(outer, 20);
|
||||
gtk_widget_set_margin_end(outer, 20);
|
||||
gtk_window_set_child(GTK_WINDOW(dialog), outer);
|
||||
|
||||
GtkWidget* title = gtk_label_new(nullptr);
|
||||
gtk_label_set_markup(GTK_LABEL(title),
|
||||
g_strdup_printf("<span size='large' weight='bold'>%s</span>",
|
||||
_("Capture key sequence")));
|
||||
gtk_label_set_xalign(GTK_LABEL(title), 0.0f);
|
||||
gtk_box_append(GTK_BOX(outer), title);
|
||||
|
||||
GtkWidget* info = gtk_label_new(_("Press keys in order (modifiers like Ctrl, Alt, Shift and Super are recorded too). Click Done to apply or Cancel to discard."));
|
||||
gtk_label_set_wrap(GTK_LABEL(info), TRUE);
|
||||
gtk_label_set_xalign(GTK_LABEL(info), 0.0f);
|
||||
gtk_widget_add_css_class(info, "dim-label");
|
||||
gtk_box_append(GTK_BOX(outer), info);
|
||||
|
||||
session->displayLabel = gtk_label_new(_("No keys recorded yet"));
|
||||
gtk_label_set_xalign(GTK_LABEL(session->displayLabel), 0.0f);
|
||||
gtk_label_set_ellipsize(GTK_LABEL(session->displayLabel), PANGO_ELLIPSIZE_MIDDLE);
|
||||
gtk_widget_add_css_class(session->displayLabel, "monospace");
|
||||
gtk_widget_set_margin_top(session->displayLabel, 12);
|
||||
gtk_widget_set_margin_bottom(session->displayLabel, 12);
|
||||
gtk_widget_set_margin_start(session->displayLabel, 12);
|
||||
gtk_widget_set_margin_end(session->displayLabel, 12);
|
||||
GtkWidget* frame = gtk_frame_new(nullptr);
|
||||
gtk_frame_set_child(GTK_FRAME(frame), session->displayLabel);
|
||||
gtk_widget_set_size_request(frame, -1, 64);
|
||||
gtk_widget_set_vexpand(frame, TRUE);
|
||||
gtk_box_append(GTK_BOX(outer), frame);
|
||||
|
||||
gtk_box_append(GTK_BOX(outer), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
// Buttons: Clear on the left, Cancel/Done grouped on the right.
|
||||
GtkWidget* buttonRow = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_append(GTK_BOX(outer), buttonRow);
|
||||
|
||||
GtkWidget* clearBtn = gtk_button_new_with_label(_("Clear"));
|
||||
gtk_widget_set_size_request(clearBtn, 110, -1);
|
||||
g_signal_connect(clearBtn, "clicked", G_CALLBACK(on_capture_clear_clicked), session);
|
||||
gtk_box_append(GTK_BOX(buttonRow), clearBtn);
|
||||
|
||||
GtkWidget* spacer = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_hexpand(spacer, TRUE);
|
||||
gtk_box_append(GTK_BOX(buttonRow), spacer);
|
||||
|
||||
GtkWidget* endBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_box_append(GTK_BOX(buttonRow), endBox);
|
||||
|
||||
GtkWidget* cancelBtn = gtk_button_new_with_label(_("Cancel"));
|
||||
gtk_widget_set_size_request(cancelBtn, 110, -1);
|
||||
g_signal_connect(cancelBtn, "clicked", G_CALLBACK(on_capture_cancel_clicked), nullptr);
|
||||
gtk_box_append(GTK_BOX(endBox), cancelBtn);
|
||||
|
||||
GtkWidget* doneBtn = gtk_button_new_with_label(_("Done"));
|
||||
gtk_widget_set_size_request(doneBtn, 110, -1);
|
||||
g_signal_connect(doneBtn, "clicked", G_CALLBACK(on_capture_done_clicked), session);
|
||||
gtk_box_append(GTK_BOX(endBox), doneBtn);
|
||||
|
||||
// Key events go to the dialog; buttons must not steal Space/Return.
|
||||
GtkEventController* keyCtrl = gtk_event_controller_key_new();
|
||||
g_signal_connect(keyCtrl, "key-pressed", G_CALLBACK(on_capture_key_pressed), session);
|
||||
g_signal_connect(keyCtrl, "key-released", G_CALLBACK(on_capture_key_released), session);
|
||||
gtk_widget_add_controller(dialog, keyCtrl);
|
||||
gtk_widget_set_focusable(clearBtn, FALSE);
|
||||
gtk_widget_set_focusable(cancelBtn, FALSE);
|
||||
gtk_widget_set_focusable(doneBtn, FALSE);
|
||||
|
||||
gtk_window_present(GTK_WINDOW(dialog));
|
||||
}
|
||||
|
||||
void on_capture_clicked(GtkButton* btn, gpointer userData) {
|
||||
auto* row = static_cast<KeyRow*>(userData);
|
||||
guint sel = gtk_drop_down_get_selected(GTK_DROP_DOWN(row->typeDrop));
|
||||
|
||||
if (sel == 1) {
|
||||
GtkWindow* window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(btn)));
|
||||
if (sel == 1) {
|
||||
pick_command_file(row, window);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sel == 0) {
|
||||
// Placeholder: real key capture will be added in a later version.
|
||||
gtk_editable_set_text(GTK_EDITABLE(row->targetEntry), _("<Press a key...>"));
|
||||
std::cout << "G" << (row->index + 1) << ": waiting for key...\n";
|
||||
open_key_capture_dialog(row, window);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +294,12 @@ static void update_row_state(KeyRow* row) {
|
||||
|
||||
if (sel == 1) {
|
||||
gtk_button_set_label(GTK_BUTTON(row->captureButton), _("Choose file..."));
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(row->targetEntry),
|
||||
_("e.g. /usr/bin/firefox or custom command"));
|
||||
} else {
|
||||
gtk_button_set_label(GTK_BUTTON(row->captureButton), _("Capture"));
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(row->targetEntry),
|
||||
_("e.g. ctrl+c, ctrl+v"));
|
||||
}
|
||||
gtk_widget_set_size_request(row->captureButton, 180, -1);
|
||||
}
|
||||
@@ -215,7 +428,7 @@ static void show_about_dialog(GtkWindow* parent) {
|
||||
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog),
|
||||
_("G-Key mapper for the Logitech G910 (GTK4)."));
|
||||
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "https://rager.dev");
|
||||
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog), "rager.dev");
|
||||
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog), "Thomas Rager - rager.dev");
|
||||
|
||||
std::string iconPath = find_asset("icon.png");
|
||||
GError* error = nullptr;
|
||||
@@ -396,7 +609,7 @@ void build_ui(GtkApplication* app) {
|
||||
|
||||
// Target input (wide: commands and file paths need room)
|
||||
GtkWidget* entry = gtk_entry_new();
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(entry), _("e.g. ctrl+c or ls -la"));
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(entry), _("e.g. ctrl+c, ctrl+v"));
|
||||
gtk_widget_set_size_request(entry, 440, -1);
|
||||
gtk_widget_set_hexpand(entry, TRUE);
|
||||
gtk_grid_attach(GTK_GRID(grid), entry, 2, i + 1, 1, 1);
|
||||
@@ -421,7 +634,9 @@ void build_ui(GtkApplication* app) {
|
||||
gtk_box_append(GTK_BOX(outer), footer);
|
||||
|
||||
GtkWidget* saveBtn = gtk_button_new_with_label(_("Save mappings"));
|
||||
gtk_widget_add_css_class(saveBtn, "suggested-action");
|
||||
// No "suggested-action" class on purpose: it gets a strong accent color
|
||||
// (e.g. Mint-Y green) that clashes with the rest of the layout. The plain
|
||||
// button follows the system theme like everything else.
|
||||
g_signal_connect(saveBtn, "clicked", G_CALLBACK(on_save_clicked), nullptr);
|
||||
gtk_box_append(GTK_BOX(footer), saveBtn);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user