0.1.0 fixes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ gkeymapper
|
||||
gkeymapper-daemon
|
||||
*.o
|
||||
*.so
|
||||
*.deb
|
||||
|
||||
@@ -22,6 +22,9 @@ live in the daemon, not the GUI. Code is split across `src/` (GUI), `shared/`
|
||||
icon itself is compiled into the binary, so it never depends on these.
|
||||
- `make clean` — deletes the binaries and the generated `locale/` and `build/`
|
||||
trees.
|
||||
- `make deb` — builds a `.deb` package (`gkeymapper_<version>_<arch>.deb`) via
|
||||
`scripts/make-deb.sh`; on install it runs `systemctl --user daemon-reload` and
|
||||
`systemctl --user enable --now gkeymapper-daemon` for the installing user.
|
||||
- No tests and no CI. Verify changes by building and running the app.
|
||||
|
||||
## i18n — easy to get wrong
|
||||
|
||||
8
Makefile
8
Makefile
@@ -32,6 +32,8 @@ DAEMON_HEADERS := $(wildcard $(DAEMON_DIR)/*.h) $(wildcard $(SHARED_DIR)/*.h)
|
||||
GUI_RES := build/gresources.c
|
||||
GUI_RES_SRC := data/icons.gresource.xml
|
||||
PREFIX ?= /usr/local
|
||||
DEB_VERSION ?= 0.1.0
|
||||
DEB_ARCH := $(shell dpkg --print-architecture 2>/dev/null || echo amd64)
|
||||
BINDIR := $(PREFIX)/bin
|
||||
LOCALEDIR := $(PREFIX)/share/locale
|
||||
ASSETS_DIR := $(PREFIX)/share/$(PACKAGE)/assets
|
||||
@@ -51,7 +53,7 @@ LANGS := $(patsubst po/%.po,%,$(PO_FILES))
|
||||
MO_FILES := $(patsubst %,locale/%/LC_MESSAGES/$(PACKAGE).mo,$(LANGS))
|
||||
I18N := $(CURDIR)/scripts/i18n.sh
|
||||
|
||||
.PHONY: all clean run install translations daemon pot i18n-check i18n-status
|
||||
.PHONY: all clean run install translations daemon pot i18n-check i18n-status deb
|
||||
|
||||
all: $(TARGET) translations $(DAEMON)
|
||||
|
||||
@@ -94,6 +96,10 @@ i18n-status:
|
||||
run: $(TARGET) translations
|
||||
GKEYMAPPER_LOCALEDIR=$(CURDIR)/locale GKEYMAPPER_ASSETS_DIR=$(CURDIR)/assets ./$(TARGET)
|
||||
|
||||
deb:
|
||||
$(CURDIR)/scripts/make-deb.sh $(DEB_VERSION) $(DEB_ARCH)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(DAEMON)
|
||||
rm -rf locale build
|
||||
|
||||
24
README.md
24
README.md
@@ -69,6 +69,16 @@ with `make daemon`. The GUI has its icons (`assets/icon.png`, `assets/icon.svg`)
|
||||
compiled in (`data/icons.gresource.xml` → generated `build/gresources.c`), so the
|
||||
window icon works without an installed `assets/` directory.
|
||||
|
||||
A `.deb` package can be built with
|
||||
|
||||
```bash
|
||||
make deb
|
||||
```
|
||||
|
||||
which produces `gkeymapper_<version>_<arch>.deb`. Installing it runs
|
||||
`systemctl --user daemon-reload` and `systemctl --user enable --now gkeymapper-daemon`
|
||||
for the installing user.
|
||||
|
||||
## Rebuild translations
|
||||
|
||||
```bash
|
||||
@@ -296,6 +306,20 @@ so that a `command` action inherits `DISPLAY`/`WAYLAND_DISPLAY`. The unit does
|
||||
not run as root. `make install` reloads the udev rules for you; on a fresh
|
||||
machine replug the keyboard (or reboot) once so the ACL applies.
|
||||
|
||||
## After installation
|
||||
|
||||
If the daemon is not running (the GUI footer says "Daemon: not reachable"):
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now gkeymapper-daemon
|
||||
```
|
||||
|
||||
The daemon needs the user's session for `/dev/uinput` and for the `DISPLAY` a
|
||||
`command` action inherits, so it runs as a **user** service, not a system
|
||||
service. If the commands above fail, check that your user session has systemd
|
||||
running (`systemctl --user status`).
|
||||
|
||||
## Clean
|
||||
|
||||
```bash
|
||||
|
||||
5
po/de.po
5
po/de.po
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-18 20:18+0200\n"
|
||||
"POT-Creation-Date: 2026-10-18 22:01+0200\n"
|
||||
"PO-Revision-Date: 2026-10-18 03:08+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
@@ -131,6 +131,9 @@ msgstr "Fenster schließen"
|
||||
msgid "Daemon: not reachable"
|
||||
msgstr "Daemon: nicht erreichbar"
|
||||
|
||||
msgid "Run: systemctl --user enable --now gkeymapper-daemon"
|
||||
msgstr "Ausführen: systemctl --user enable --now gkeymapper-daemon"
|
||||
|
||||
msgid "Daemon: running"
|
||||
msgstr "Daemon: läuft"
|
||||
|
||||
|
||||
5
po/en.po
5
po/en.po
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-18 20:18+0200\n"
|
||||
"POT-Creation-Date: 2026-10-18 22:01+0200\n"
|
||||
"PO-Revision-Date: 2026-10-18 03:08+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: English\n"
|
||||
@@ -128,6 +128,9 @@ msgstr "Close window"
|
||||
msgid "Daemon: not reachable"
|
||||
msgstr "Daemon: not reachable"
|
||||
|
||||
msgid "Run: systemctl --user enable --now gkeymapper-daemon"
|
||||
msgstr "Run: systemctl --user enable --now gkeymapper-daemon"
|
||||
|
||||
msgid "Daemon: running"
|
||||
msgstr "Daemon: running"
|
||||
|
||||
|
||||
5
po/es.po
5
po/es.po
@@ -4,7 +4,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-18 20:18+0200\n"
|
||||
"POT-Creation-Date: 2026-10-18 22:01+0200\n"
|
||||
"PO-Revision-Date: 2026-10-18 03:08+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
@@ -128,6 +128,9 @@ msgstr "Cerrar ventana"
|
||||
msgid "Daemon: not reachable"
|
||||
msgstr "Demonio: no accesible"
|
||||
|
||||
msgid "Run: systemctl --user enable --now gkeymapper-daemon"
|
||||
msgstr "Ejecutar: systemctl --user enable --now gkeymapper-daemon"
|
||||
|
||||
msgid "Daemon: running"
|
||||
msgstr "Demonio: en ejecución"
|
||||
|
||||
|
||||
5
po/fr.po
5
po/fr.po
@@ -4,7 +4,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gkeymapper 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-18 20:18+0200\n"
|
||||
"POT-Creation-Date: 2026-10-18 22:01+0200\n"
|
||||
"PO-Revision-Date: 2026-10-18 03:08+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
@@ -131,6 +131,9 @@ msgstr "Fermer la fenêtre"
|
||||
msgid "Daemon: not reachable"
|
||||
msgstr "Démon : injoignable"
|
||||
|
||||
msgid "Run: systemctl --user enable --now gkeymapper-daemon"
|
||||
msgstr "Exécuter : systemctl --user enable --now gkeymapper-daemon"
|
||||
|
||||
msgid "Daemon: running"
|
||||
msgstr "Démon : en cours d'exécution"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-10-18 20:18+0200\n"
|
||||
"POT-Creation-Date: 2026-10-18 22:01+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,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/autostart.cpp:97 src/main.cpp:280 src/trayicon.cpp:371
|
||||
#: src/autostart.cpp:97 src/main.cpp:285 src/trayicon.cpp:371
|
||||
msgid "G-Key mapper for the Logitech G910 (GTK4)."
|
||||
msgstr ""
|
||||
|
||||
@@ -111,11 +111,11 @@ msgid ""
|
||||
"along."
|
||||
msgstr ""
|
||||
|
||||
#: src/help.cpp:67 src/help.cpp:86 src/main.cpp:635
|
||||
#: src/help.cpp:67 src/help.cpp:86 src/main.cpp:640
|
||||
msgid "Help"
|
||||
msgstr ""
|
||||
|
||||
#: src/help.cpp:95 src/optionsdialog.cpp:177
|
||||
#: src/help.cpp:95 src/optionsdialog.cpp:178
|
||||
msgid "Close window"
|
||||
msgstr ""
|
||||
|
||||
@@ -123,158 +123,162 @@ msgstr ""
|
||||
msgid "Daemon: not reachable"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:78
|
||||
msgid "Daemon: running"
|
||||
#: src/main.cpp:80
|
||||
msgid "Run: systemctl --user enable --now gkeymapper-daemon"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:83
|
||||
msgid "Daemon: running"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:88
|
||||
msgid "Device: not found"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:86
|
||||
#: src/main.cpp:91
|
||||
#, c-format
|
||||
msgid "Device: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:91 src/optionsdialog.cpp:228
|
||||
#: src/main.cpp:96 src/optionsdialog.cpp:229
|
||||
msgid "Configuration error"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:96
|
||||
#: src/main.cpp:101
|
||||
#, c-format
|
||||
msgid "Last key: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:139
|
||||
#: src/main.cpp:144
|
||||
msgid "Choose file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:142 src/main.cpp:313 src/main.cpp:325
|
||||
#: src/main.cpp:147 src/main.cpp:318 src/main.cpp:330
|
||||
msgid "_Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:143 src/main.cpp:326
|
||||
#: src/main.cpp:148 src/main.cpp:331
|
||||
msgid "_Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:173
|
||||
#: src/main.cpp:178
|
||||
msgid "Choose file..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:175
|
||||
#: src/main.cpp:180
|
||||
msgid "e.g. /usr/bin/firefox or custom command"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:177 src/main.cpp:181 src/main.cpp:726
|
||||
#: src/main.cpp:182 src/main.cpp:186 src/main.cpp:733
|
||||
msgid "Capture"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:179
|
||||
#: src/main.cpp:184
|
||||
msgid "e.g. ctrl+w (held while the G key is held)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:183 src/main.cpp:719
|
||||
#: src/main.cpp:188 src/main.cpp:726
|
||||
msgid "e.g. ctrl+c, ctrl+v"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:198
|
||||
#: src/main.cpp:203
|
||||
#, c-format
|
||||
msgid "Could not save %s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:206
|
||||
#: src/main.cpp:211
|
||||
msgid "Mappings saved to "
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:216
|
||||
#: src/main.cpp:221
|
||||
msgid "Could not export mappings.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:277 src/main.cpp:623 src/trayicon.cpp:370 src/trayicon.cpp:500
|
||||
#: src/main.cpp:282 src/main.cpp:628 src/trayicon.cpp:370 src/trayicon.cpp:500
|
||||
msgid "gKeyMapper"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:310
|
||||
#: src/main.cpp:315
|
||||
msgid "Export configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:314
|
||||
#: src/main.cpp:319
|
||||
msgid "_Save"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:322
|
||||
#: src/main.cpp:327
|
||||
msgid "Import configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:608
|
||||
#: src/main.cpp:613
|
||||
msgid "gKeyMapper – Logitech G910"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:627
|
||||
#: src/main.cpp:632
|
||||
msgid "Export configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:628
|
||||
#: src/main.cpp:633
|
||||
msgid "Import configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:631 src/optionsdialog.cpp:83
|
||||
#: src/main.cpp:636 src/optionsdialog.cpp:83
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:636
|
||||
#: src/main.cpp:641
|
||||
msgid "About"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:642
|
||||
#: src/main.cpp:647
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:656
|
||||
#: src/main.cpp:661
|
||||
msgid "G1 to G9 of the Logitech G910 remapped to keys or commands"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:677
|
||||
#: src/main.cpp:682
|
||||
msgid "G-Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:677
|
||||
#: src/main.cpp:682
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:677
|
||||
#: src/main.cpp:682
|
||||
msgid "Target (Key/Command)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:677
|
||||
#: src/main.cpp:682
|
||||
msgid "Action"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:689
|
||||
#: src/main.cpp:696
|
||||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:689
|
||||
#: src/main.cpp:696
|
||||
msgid "Command"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:689
|
||||
#: src/main.cpp:696
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:690
|
||||
#: src/main.cpp:697
|
||||
msgid "Key (hold)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:761
|
||||
#: src/main.cpp:769
|
||||
msgid "Save mappings"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:768
|
||||
#: src/main.cpp:776
|
||||
msgid "Saved to ~/.config/gKeyMapper/mappings.conf"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cpp:779
|
||||
#: src/main.cpp:787
|
||||
msgid "Daemon: checking..."
|
||||
msgstr ""
|
||||
|
||||
@@ -301,7 +305,7 @@ msgid ""
|
||||
"G keys - the daemon does the work and is the only part that has to run."
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:131 src/optionsdialog.cpp:149
|
||||
#: src/optionsdialog.cpp:131 src/optionsdialog.cpp:150
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
@@ -309,65 +313,65 @@ msgstr ""
|
||||
msgid "System language"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:154
|
||||
#: src/optionsdialog.cpp:155
|
||||
msgid "The interface switches right away, including the tray menu."
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:157
|
||||
#: src/optionsdialog.cpp:158
|
||||
msgid "Daemon status"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:170
|
||||
#: src/optionsdialog.cpp:171
|
||||
msgid "Tray icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:171
|
||||
#: src/optionsdialog.cpp:172
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:172
|
||||
#: src/optionsdialog.cpp:173
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:173
|
||||
#: src/optionsdialog.cpp:174
|
||||
msgid "Device"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:174
|
||||
#: src/optionsdialog.cpp:175
|
||||
msgid "Configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:175
|
||||
#: src/optionsdialog.cpp:176
|
||||
msgid "Last key"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:216
|
||||
#: src/optionsdialog.cpp:217
|
||||
msgid ""
|
||||
"Closing or minimizing the window hides it instead of quitting. The tray icon "
|
||||
"shows it again (Show) and quits the program (Close)."
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:218
|
||||
#: src/optionsdialog.cpp:219
|
||||
msgid "No tray is available on this desktop, so the window cannot be hidden."
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:221
|
||||
#: src/optionsdialog.cpp:222
|
||||
msgid "active"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:221
|
||||
#: src/optionsdialog.cpp:222
|
||||
msgid "not available"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:222
|
||||
#: src/optionsdialog.cpp:223
|
||||
msgid "running"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:222
|
||||
#: src/optionsdialog.cpp:223
|
||||
msgid "not reachable"
|
||||
msgstr ""
|
||||
|
||||
#: src/optionsdialog.cpp:224
|
||||
#: src/optionsdialog.cpp:225
|
||||
msgid "not found"
|
||||
msgstr ""
|
||||
|
||||
|
||||
129
scripts/make-deb.sh
Executable file
129
scripts/make-deb.sh
Executable file
@@ -0,0 +1,129 @@
|
||||
#!/bin/sh
|
||||
# Build a .deb package for gKeyMapper.
|
||||
# Usage: scripts/make-deb.sh [version] [arch]
|
||||
set -e
|
||||
|
||||
VERSION="${1:-0.1.0}"
|
||||
ARCH="${2:-$(dpkg --print-architecture 2>/dev/null || echo amd64)}"
|
||||
PACKAGE="gkeymapper"
|
||||
STAGING="build/deb"
|
||||
DEB_NAME="${PACKAGE}_${VERSION}_${ARCH}.deb"
|
||||
|
||||
# Build everything first.
|
||||
make all translations
|
||||
|
||||
rm -rf "$STAGING"
|
||||
mkdir -p "$STAGING/DEBIAN"
|
||||
|
||||
# Stage files with Debian layout (PREFIX=/usr).
|
||||
make install DESTDIR="$STAGING" PREFIX=/usr
|
||||
|
||||
# Calculate installed size (in KB) for the control file.
|
||||
INSTALLED_SIZE=$(du -sk "$STAGING" | cut -f1)
|
||||
|
||||
# Control file.
|
||||
cat > "$STAGING/DEBIAN/control" <<EOF
|
||||
Package: $PACKAGE
|
||||
Version: $VERSION
|
||||
Section: utils
|
||||
Installed-Size: $INSTALLED_SIZE
|
||||
Priority: optional
|
||||
Architecture: $ARCH
|
||||
Depends: libc6, libgtk-4-1, libusb-1.0-0, libxkbcommon0, libglib2.0-0, systemd, udev
|
||||
Maintainer: gKeyMapper <gkeymapper@rager.dev>
|
||||
Description: Remap G1-G9 keys of the Logitech G910
|
||||
A GTK4 GUI plus a background daemon for remapping the G1-G9 keys
|
||||
of a Logitech G910 keyboard to keys or commands.
|
||||
EOF
|
||||
|
||||
# postinst: reload udev/systemd and enable the user daemon.
|
||||
cat > "$STAGING/DEBIAN/postinst" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
case "$1" in
|
||||
configure)
|
||||
if command -v udevadm >/dev/null 2>&1; then
|
||||
udevadm control --reload-rules 2>/dev/null || true
|
||||
udevadm trigger --subsystem-match=usb 2>/dev/null || true
|
||||
udevadm trigger --subsystem-match=input 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Helper: run a command as a given user with the D-Bus session bus
|
||||
# available. "systemctl --user" needs DBUS_SESSION_BUS_ADDRESS, which
|
||||
# is not set in a plain "su -" login shell.
|
||||
run_as_user() {
|
||||
_user="$1"; shift
|
||||
_uid=$(id -u "$_user" 2>/dev/null) || return 1
|
||||
_bus="unix:path=/run/user/$_uid/bus"
|
||||
runuser -u "$_user" -- env DBUS_SESSION_BUS_ADDRESS="$_bus" "$@" 2>&1
|
||||
}
|
||||
|
||||
_target_user=""
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
_target_user="$SUDO_USER"
|
||||
fi
|
||||
|
||||
if [ -n "$_target_user" ]; then
|
||||
echo "gkeymapper: enabling daemon for user $_target_user ..."
|
||||
if run_as_user "$_target_user" systemctl --user daemon-reload; then
|
||||
echo " daemon-reload: OK"
|
||||
else
|
||||
echo " daemon-reload: FAILED (is the user session running?)"
|
||||
fi
|
||||
if run_as_user "$_target_user" systemctl --user enable --now gkeymapper-daemon; then
|
||||
echo " enable --now gkeymapper-daemon: OK"
|
||||
else
|
||||
echo " enable --now gkeymapper-daemon: FAILED"
|
||||
echo " -> run manually: systemctl --user enable --now gkeymapper-daemon"
|
||||
fi
|
||||
else
|
||||
echo "gkeymapper: no installing user detected (SUDO_USER empty)."
|
||||
echo " Enable the daemon manually with:"
|
||||
echo " systemctl --user daemon-reload"
|
||||
echo " systemctl --user enable --now gkeymapper-daemon"
|
||||
for _user in $(loginctl list-users --no-legend 2>/dev/null | awk '{print $2}'); do
|
||||
_uid=$(id -u "$_user" 2>/dev/null) || continue
|
||||
echo " trying user $_user ..."
|
||||
run_as_user "$_user" systemctl --user daemon-reload >/dev/null 2>&1 || true
|
||||
run_as_user "$_user" systemctl --user enable --now gkeymapper-daemon >/dev/null 2>&1 || true
|
||||
done
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
chmod 755 "$STAGING/DEBIAN/postinst"
|
||||
|
||||
# postrm: disable the user daemon on removal.
|
||||
cat > "$STAGING/DEBIAN/postrm" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
case "$1" in
|
||||
remove|purge)
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
su - "$SUDO_USER" -c "systemctl --user disable --now gkeymapper-daemon" >/dev/null 2>&1 || true
|
||||
su - "$SUDO_USER" -c "systemctl --user daemon-reload" >/dev/null 2>&1 || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
EOF
|
||||
chmod 755 "$STAGING/DEBIAN/postrm"
|
||||
|
||||
# Fix ownership (files must be owned by root in a .deb).
|
||||
# Strip debug symbols from binaries.
|
||||
strip "$STAGING/usr/bin/gkeymapper" "$STAGING/usr/bin/gkeymapper-daemon" 2>/dev/null || true
|
||||
|
||||
# Remove generated cache files (they are regenerated on the target).
|
||||
rm -f "$STAGING/usr/share/applications/mimeinfo.cache"
|
||||
rm -f "$STAGING/usr/share/icons/hicolor/icon-theme.cache"
|
||||
# Fix file permissions.
|
||||
chmod 644 "$STAGING"/usr/share/applications/* 2>/dev/null || true
|
||||
chmod 755 "$STAGING"/usr/bin/* 2>/dev/null || true
|
||||
|
||||
# Build the .deb.
|
||||
dpkg-deb --root-owner-group --build "$STAGING" "$DEB_NAME"
|
||||
|
||||
echo ""
|
||||
echo "Built: $DEB_NAME"
|
||||
18
src/main.cpp
18
src/main.cpp
@@ -74,7 +74,12 @@ static void refresh_footer() {
|
||||
std::string text;
|
||||
if (!daemonView.reachable) {
|
||||
text = _("Daemon: not reachable");
|
||||
// Hint for users who installed the package but did not (or could not)
|
||||
// enable the daemon service during installation.
|
||||
gtk_widget_set_tooltip_text(daemonLabel,
|
||||
_("Run: systemctl --user enable --now gkeymapper-daemon"));
|
||||
} else {
|
||||
gtk_widget_set_tooltip_text(daemonLabel, nullptr);
|
||||
text = _("Daemon: running");
|
||||
text += " · ";
|
||||
if (daemonView.device.empty()) {
|
||||
@@ -685,14 +690,16 @@ void build_ui(GtkApplication* app, bool show) {
|
||||
|
||||
// GTK draws the check mark of the selected entry right behind the text of a
|
||||
// dropdown row, so every entry carries a trailing space. The catalogs keep
|
||||
// the bare words; the space is added here, where the model is built.
|
||||
// the bare words; the space is added here, where the model is built. The
|
||||
// strings are copied by gtk_drop_down_new_from_strings, so the array can be
|
||||
// freed once every dropdown has been created.
|
||||
const char* typeOptions[] = { _("Key"), _("Command"), _("Disabled"),
|
||||
_("Key (hold)"), nullptr };
|
||||
g_autoptr(GtkStringList) typeModel = gtk_string_list_new(nullptr);
|
||||
char** typeShown = g_new(char*, 5);
|
||||
for (int i = 0; typeOptions[i] != nullptr; ++i) {
|
||||
g_autofree gchar* shown = g_strconcat(typeOptions[i], " ", nullptr);
|
||||
gtk_string_list_append(typeModel, shown);
|
||||
typeShown[i] = g_strconcat(typeOptions[i], " ", nullptr);
|
||||
}
|
||||
typeShown[4] = nullptr;
|
||||
|
||||
rows.resize(kNumKeys);
|
||||
for (int i = 0; i < kNumKeys; ++i) {
|
||||
@@ -706,7 +713,7 @@ void build_ui(GtkApplication* app, bool show) {
|
||||
rows[i].keyLabel = keyLabel;
|
||||
|
||||
// Type dropdown (fixed width so rows don't jump between languages)
|
||||
GtkWidget* drop = gtk_drop_down_new(G_LIST_MODEL(typeModel), nullptr);
|
||||
GtkWidget* drop = gtk_drop_down_new_from_strings((const char* const*)typeShown);
|
||||
gtk_drop_down_set_selected(GTK_DROP_DOWN(drop), 0);
|
||||
gtk_widget_set_size_request(drop, 150, -1);
|
||||
gtk_grid_attach(GTK_GRID(grid), drop, 1, i + 1, 1, 1);
|
||||
@@ -731,6 +738,7 @@ void build_ui(GtkApplication* app, bool show) {
|
||||
|
||||
update_row_state(&rows[i]);
|
||||
}
|
||||
g_strfreev(typeShown);
|
||||
|
||||
// Start from the rows the replaced instance had on screen, or - when this is
|
||||
// the only instance - from the saved mappings. Without either the rows are
|
||||
|
||||
@@ -136,12 +136,13 @@ void OptionsDialog::show(GtkWindow* parent, const OptionsState& state, ToggleFn
|
||||
// check mark of the selected entry right behind the text.
|
||||
const char* languageOptions[] = { _("System language"), "Deutsch", "English", "Español",
|
||||
"Français", nullptr };
|
||||
g_autoptr(GtkStringList) languageModel = gtk_string_list_new(nullptr);
|
||||
char** languageShown = g_new(char*, 6);
|
||||
for (int i = 0; languageOptions[i] != nullptr; ++i) {
|
||||
g_autofree gchar* shown = g_strconcat(languageOptions[i], " ", nullptr);
|
||||
gtk_string_list_append(languageModel, shown);
|
||||
languageShown[i] = g_strconcat(languageOptions[i], " ", nullptr);
|
||||
}
|
||||
languageDrop_ = gtk_drop_down_new(G_LIST_MODEL(languageModel), nullptr);
|
||||
languageShown[5] = nullptr;
|
||||
languageDrop_ = gtk_drop_down_new_from_strings((const char* const*)languageShown);
|
||||
g_strfreev(languageShown);
|
||||
// Right-aligned like the switches above: the GUI's own controls sit on one
|
||||
// line along the right edge, the text explains them on the left.
|
||||
gtk_widget_set_halign(languageDrop_, GTK_ALIGN_END);
|
||||
|
||||
Reference in New Issue
Block a user