Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76790e0321 | ||
|
|
c3d34a2788 | ||
|
|
4711ef5532 | ||
|
|
c384df7cac |
No files matched your search
@@ -101,7 +101,10 @@ temperature source (Tctl vs Tccd).
|
||||
send/sample interval — saved to `~/.config/gamemax-report/config.json`
|
||||
- **Clear mode indicators**: green "showing sensor data" / orange "blank (zeros)" /
|
||||
grey "sending stopped", dimmed tray icon and a desktop notification per change
|
||||
- **Autostart** via a systemd user unit (equivalent of the vendor's Task Scheduler trick)
|
||||
- **Autostart** at login: a systemd user unit for the sender **and** an XDG autostart entry that
|
||||
starts the tray app with `--tray-only` (no window pops up; open it from the tray menu). The
|
||||
*Mulai otomatis saat login* checkbox manages both, and disables any other autostart entry that
|
||||
would launch the same AppImage with a window.
|
||||
- **Plug and play**: the service waits for the device, streams while present and keeps
|
||||
waiting through unplug/replug; a udev rule grants access to the logged-in user
|
||||
- **Single instance**: launching the app again just raises the running window
|
||||
@@ -109,7 +112,8 @@ temperature source (Tctl vs Tccd).
|
||||
- **Donate / GitHub buttons** in the app (window and tray menu)
|
||||
- **AppImage build** script (`packaging/build_appimage.sh`, PySide6 bundled)
|
||||
|
||||
The GUI labels are in Indonesian.
|
||||
The GUI labels are in Indonesian. The app itself is named **IceBurg LCD** (no vendor brand in
|
||||
the UI); the repository keeps the hardware and brand name only to describe what it supports.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -123,6 +127,16 @@ The GUI labels are in Indonesian.
|
||||
|
||||
## Install
|
||||
|
||||
One command (downloads the latest release, verifies its SHA-256, installs the app, the
|
||||
systemd user unit, the menu entry and the udev rule):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/oxpoe/Gamemax-linux-apps/main/install.sh | bash
|
||||
# uninstall: bash install.sh --uninstall (add --remove-data to drop settings too)
|
||||
```
|
||||
|
||||
Manual steps, if you prefer to see every command:
|
||||
|
||||
```bash
|
||||
# 1. device access for the logged-in user (once, needs root)
|
||||
sudo cp packaging/70-gamemax.rules /etc/udev/rules.d/
|
||||
|
||||
Executable
+194
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env bash
|
||||
# GAMEMAX LCD — pemasangan / pelepasan satu perintah.
|
||||
#
|
||||
# curl -fsSL https://raw.githubusercontent.com/oxpoe/Gamemax-linux-apps/main/install.sh | bash
|
||||
#
|
||||
# Opsi:
|
||||
# --uninstall lepaskan pemasangan (layanan, aplikasi, config, ikon, entri menu)
|
||||
# --no-service pasang aplikasi saja, jangan aktifkan layanan/autostart
|
||||
# --version vX.Y.Z pasang versi rilis tertentu (default: rilis terbaru)
|
||||
# --remove-data saat --uninstall: hapus juga ~/.config/gamemax-report
|
||||
#
|
||||
# UdeV: aturan izin device dipasang dengan sudo. Kalau skrip dijalankan lewat pipa
|
||||
# (curl | bash) dan sudo butuh kata sandi, perintahnya dicetak untuk dijalankan manual.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="oxpoe/Gamemax-linux-apps"
|
||||
ASSET="GAMEMAX-LCD-x86_64.AppImage"
|
||||
RAW="https://raw.githubusercontent.com/$REPO/main"
|
||||
|
||||
OPT_DIR="$HOME/.local/opt/gamemax-lcd"
|
||||
APP="$OPT_DIR/GAMEMAX-LCD.AppImage"
|
||||
DATA_DIR="$HOME/.local/share/gamemax-report"
|
||||
UNIT="$HOME/.config/systemd/user/gamemax-report.service"
|
||||
DESKTOP_DIR="$HOME/.local/share/applications"
|
||||
ICON_DIR="$HOME/.local/share/icons/hicolor/128x128/apps"
|
||||
RULE=/etc/udev/rules.d/70-gamemax.rules
|
||||
SERVICE="gamemax-report.service"
|
||||
|
||||
UNINSTALL=0 WITH_SERVICE=1 REMOVE_DATA=0 VERSION="latest"
|
||||
|
||||
say() { printf '%s\n' "$*"; }
|
||||
die() { printf 'galat: %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--uninstall) UNINSTALL=1 ;;
|
||||
--no-service) WITH_SERVICE=0 ;;
|
||||
--remove-data) REMOVE_DATA=1 ;;
|
||||
--version) shift; VERSION="${1:?--version butuh nilai seperti v1.3.0}" ;;
|
||||
-h|--help) sed -n '2,14p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) die "opsi tidak dikenal: $1" ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
need() { command -v "$1" >/dev/null 2>&1 || die "perintah '$1' tidak tersedia"; }
|
||||
|
||||
# ---------------------------------------------------------------- uninstall
|
||||
if [ "$UNINSTALL" = 1 ]; then
|
||||
say "== melepaskan GAMEMAX LCD =="
|
||||
command -v systemctl >/dev/null 2>&1 && systemctl --user disable --now "$SERVICE" 2>/dev/null || true
|
||||
rm -f "$UNIT"
|
||||
command -v systemctl >/dev/null 2>&1 && { systemctl --user daemon-reload 2>/dev/null || true; \
|
||||
systemctl --user reset-failed "$SERVICE" 2>/dev/null || true; }
|
||||
rm -rf "$OPT_DIR" "$DATA_DIR"
|
||||
rm -f "$DESKTOP_DIR/gamemax-lcd.desktop" "$ICON_DIR/gamemax-lcd.png"
|
||||
rm -f "$HOME/.config/autostart/iceburg-lcd.desktop"
|
||||
[ "$REMOVE_DATA" = 1 ] && rm -rf "$HOME/.config/gamemax-report"
|
||||
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true
|
||||
if [ -f "$RULE" ]; then
|
||||
if sudo -n rm -f "$RULE" 2>/dev/null; then
|
||||
sudo -n udevadm control --reload 2>/dev/null || true
|
||||
say " aturan udev dihapus"
|
||||
else
|
||||
say " aturan udev masih ada (butuh sudo): sudo rm -f $RULE && sudo udevadm control --reload"
|
||||
fi
|
||||
fi
|
||||
say "selesai. Aplikasi, layanan, dan berkas pendukung sudah dilepas."
|
||||
say "catatan: konfigurasi ~/.config/gamemax-report hanya dihapus dengan --remove-data."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------- install
|
||||
need curl
|
||||
need sha256sum
|
||||
command -v systemctl >/dev/null 2>&1 || die "systemd (systemctl) dibutuhkan untuk layanan"
|
||||
|
||||
if [ "$VERSION" = "latest" ]; then
|
||||
BASE="https://github.com/$REPO/releases/latest/download"
|
||||
else
|
||||
BASE="https://github.com/$REPO/releases/download/$VERSION"
|
||||
fi
|
||||
|
||||
say "== GAMEMAX LCD: pemasangan ($VERSION) =="
|
||||
mkdir -p "$OPT_DIR" "$DATA_DIR" "$DESKTOP_DIR" "$ICON_DIR" "$HOME/.config/systemd/user"
|
||||
|
||||
say "1/6 mengunduh aplikasi …"
|
||||
curl -fsSL -o "$APP.part" "$BASE/$ASSET"
|
||||
curl -fsSL -o "$APP.sha256" "$BASE/$ASSET.sha256"
|
||||
|
||||
say "2/6 memverifikasi checksum …"
|
||||
EXPECTED="$(awk '{print $1}' "$APP.sha256")"
|
||||
ACTUAL="$(sha256sum "$APP.part" | awk '{print $1}')"
|
||||
[ "$EXPECTED" = "$ACTUAL" ] || { rm -f "$APP.part"; die "checksum tidak cocok — unduhan dibatalkan"; }
|
||||
say " ok: ${ACTUAL:0:16}…"
|
||||
|
||||
mv -f "$APP.part" "$APP"
|
||||
chmod +x "$APP"
|
||||
rm -f "$APP.sha256"
|
||||
|
||||
say "3/6 mengambil sender + ikon dari bundel …"
|
||||
TMP="$(mktemp -d)"
|
||||
( cd "$TMP" && "$APP" --appimage-extract >/dev/null 2>&1 ) || true
|
||||
INTERNAL="$TMP/squashfs-root/usr/bin/_internal"
|
||||
if [ -f "$INTERNAL/gamemax_report.py" ]; then
|
||||
cp "$INTERNAL/gamemax_report.py" "$DATA_DIR/gamemax_report.py"
|
||||
else
|
||||
say " ! sender tidak ditemukan di bundel — unduh dari repo"
|
||||
curl -fsSL -o "$DATA_DIR/gamemax_report.py" "$RAW/src/gamemax_report.py"
|
||||
fi
|
||||
[ -f "$INTERNAL/icon.png" ] && cp "$INTERNAL/icon.png" "$ICON_DIR/gamemax-lcd.png" \
|
||||
|| curl -fsSL -o "$ICON_DIR/gamemax-lcd.png" "$RAW/src/icon.png"
|
||||
rm -rf "$TMP"
|
||||
|
||||
say "4/6 memasang layanan systemd (autostart + plug and play) …"
|
||||
cat > "$UNIT" <<EOF
|
||||
[Unit]
|
||||
Description=IceBurg LCD — HID sensor display bridge (Linux)
|
||||
After=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python3 $DATA_DIR/gamemax_report.py --wait --interval 0.5 --sample 0.5
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
systemctl --user daemon-reload
|
||||
if [ "$WITH_SERVICE" = 1 ]; then
|
||||
systemctl --user enable --now "$SERVICE"
|
||||
sleep 2
|
||||
say " layanan: $(systemctl --user is-active "$SERVICE") / $(systemctl --user is-enabled "$SERVICE")"
|
||||
else
|
||||
say " dilewati (--no-service)"
|
||||
fi
|
||||
|
||||
say "5/6 memasang entri menu, ikon, dan autostart tray …"
|
||||
cat > "$DESKTOP_DIR/gamemax-lcd.desktop" <<EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=IceBurg LCD
|
||||
GenericName=Kontrol LCD AIO
|
||||
Comment=Status, nyala/mati, pemantauan, dan pengaturan LCD AIO IceBurg Digital
|
||||
Exec="$APP"
|
||||
Icon=gamemax-lcd
|
||||
Terminal=false
|
||||
Categories=System;Utility;
|
||||
EOF
|
||||
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true
|
||||
command -v gtk-update-icon-cache >/dev/null 2>&1 && \
|
||||
gtk-update-icon-cache -f -t "$HOME/.local/share/icons/hicolor" 2>/dev/null || true
|
||||
mkdir -p "$HOME/.config/autostart"
|
||||
cat > "$HOME/.config/autostart/iceburg-lcd.desktop" <<EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=IceBurg LCD (tray)
|
||||
Comment=Layar LCD AIO — berjalan di tray saat login (tanpa jendela)
|
||||
Exec="$APP" --tray-only
|
||||
Icon=iceburg-lcd
|
||||
Terminal=false
|
||||
X-GNOME-Autostart-enabled=true
|
||||
EOF
|
||||
say " autostart tray: ~/.config/autostart/iceburg-lcd.desktop (--tray-only)"
|
||||
|
||||
say "6/6 aturan udev (izin device) …"
|
||||
RULE_TMP="$(mktemp)"
|
||||
curl -fsSL -o "$RULE_TMP" "$RAW/packaging/70-gamemax.rules"
|
||||
if [ -f "$RULE" ] && cmp -s "$RULE" "$RULE_TMP"; then
|
||||
say " sudah terpasang"
|
||||
elif sudo -n install -m 644 "$RULE_TMP" "$RULE" 2>/dev/null; then
|
||||
sudo -n udevadm control --reload 2>/dev/null || true
|
||||
sudo -n udevadm trigger --subsystem-match=hidraw 2>/dev/null || true
|
||||
say " terpasang"
|
||||
elif [ -t 0 ]; then
|
||||
sudo install -m 644 "$RULE_TMP" "$RULE" && sudo udevadm control --reload && \
|
||||
sudo udevadm trigger --subsystem-match=hidraw && say " terpasang"
|
||||
else
|
||||
say " ! butuh sudo — jalankan sekali:"
|
||||
say " sudo install -m 644 $RULE_TMP $RULE && sudo udevadm control --reload && sudo udevadm trigger --subsystem-match=hidraw"
|
||||
fi
|
||||
rm -f "$RULE_TMP"
|
||||
|
||||
say
|
||||
say "== selesai =="
|
||||
say " aplikasi : $APP"
|
||||
say " sender : $DATA_DIR/gamemax_report.py"
|
||||
say " menu : GAMEMAX IceBurg LCD"
|
||||
say " layanan : systemctl --user status $SERVICE"
|
||||
say " log : journalctl --user -u $SERVICE -f"
|
||||
say
|
||||
say "buka aplikasinya untuk mengatur slot kipas/sumber suhu, atau:"
|
||||
say " $APP --window"
|
||||
@@ -42,9 +42,9 @@ cp "$ROOT_DIR/src/icon.png" "$APPDIR/gamemax-lcd.png"
|
||||
cat > "$APPDIR/gamemax-lcd.desktop" <<'EOF'
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=GAMEMAX IceBurg LCD
|
||||
GenericName=AI LCD controller
|
||||
Comment=Status, on/off, monitor, and settings for the GAMEMAX IceBurg AIO LCD
|
||||
Name=IceBurg LCD
|
||||
GenericName=Kontrol LCD AIO
|
||||
Comment=Status, nyala/mati, pemantauan, dan pengaturan LCD AIO IceBurg Digital
|
||||
Exec=gamemax-lcd
|
||||
Icon=gamemax-lcd
|
||||
Terminal=false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Unit]
|
||||
Description=GAMEMAX HID sensor display bridge (PcInfoMonitorPro replacement)
|
||||
Description=IceBurg LCD — HID sensor display bridge (Linux)
|
||||
Documentation=file:///mnt/SSD/Work/REVERSE-EGENERING/analysis/01-recon.md
|
||||
After=graphical-session.target
|
||||
|
||||
|
||||
+76
-13
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""GAMEMAX IceBurg LCD — GUI tray: status, nyala/mati, pemantauan beranimasi, pengaturan.
|
||||
"""IceBurg LCD — GUI tray: status, nyala/mati, pemantauan beranimasi, pengaturan.
|
||||
|
||||
Streaming tetap dijalankan oleh layanan systemd (gamemax-report.service); GUI ini
|
||||
mengendalikannya dan memakai gamemax_report.py sebagai pengirim.
|
||||
@@ -8,6 +8,7 @@ mengendalikannya dan memakai gamemax_report.py sebagai pengirim.
|
||||
gamemax_gui.py --tray-only # tanpa jendela
|
||||
gamemax_gui.py --selftest # uji muat tanpa tampilan (untuk build AppImage)
|
||||
"""
|
||||
import glob
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
@@ -32,7 +33,8 @@ from PySide6.QtWidgets import (
|
||||
)
|
||||
from PySide6.QtNetwork import QLocalServer, QLocalSocket
|
||||
|
||||
APP_VERSION = "1.3.0"
|
||||
APP_VERSION = "1.3.3"
|
||||
APP_NAME = "IceBurg LCD"
|
||||
REPO = "oxpoe/Gamemax-linux-apps"
|
||||
RELEASES_API = f"https://api.github.com/repos/{REPO}/releases/latest"
|
||||
UPDATE_ASSET = "GAMEMAX-LCD-x86_64.AppImage"
|
||||
@@ -48,9 +50,11 @@ CONFIG_PATH = gr.CONFIG_PATH
|
||||
INSTALL_DIR = os.path.expanduser("~/.local/share/gamemax-report")
|
||||
UNIT_PATH = os.path.expanduser(f"~/.config/systemd/user/{SERVICE}")
|
||||
RULE_PATH = "/etc/udev/rules.d/70-gamemax.rules"
|
||||
AUTOSTART_DIR = os.path.expanduser("~/.config/autostart")
|
||||
AUTOSTART_FILE = os.path.join(AUTOSTART_DIR, "iceburg-lcd.desktop")
|
||||
|
||||
UNIT_TEMPLATE = """[Unit]
|
||||
Description=GAMEMAX HID sensor display bridge (PcInfoMonitorPro replacement)
|
||||
Description=IceBurg LCD — HID sensor display bridge (Linux)
|
||||
After=graphical-session.target
|
||||
|
||||
[Service]
|
||||
@@ -162,6 +166,63 @@ def open_link(url, parent=None):
|
||||
parent.log(f"tidak bisa membuka tautan: {url}")
|
||||
|
||||
|
||||
def other_autostart_entries(appimage):
|
||||
"""Entri autostart lain yang menjalankan AppImage yang sama (mis. buatan tool integrasi)."""
|
||||
found = []
|
||||
for path in glob.glob(os.path.join(AUTOSTART_DIR, "*.desktop")):
|
||||
if path == AUTOSTART_FILE:
|
||||
continue
|
||||
try:
|
||||
text = open(path).read()
|
||||
except OSError:
|
||||
continue
|
||||
if appimage and appimage in text:
|
||||
found.append(path)
|
||||
return found
|
||||
|
||||
|
||||
def set_tray_autostart(enable, appimage):
|
||||
"""Autostart ikon tray saat login, tersembunyi (tanpa jendela)."""
|
||||
if not appimage:
|
||||
return "tidak berjalan dari AppImage — autostart tray dilewati"
|
||||
os.makedirs(AUTOSTART_DIR, exist_ok=True)
|
||||
notes = []
|
||||
if enable:
|
||||
with open(AUTOSTART_FILE, "w") as fh:
|
||||
fh.write(f"""[Desktop Entry]
|
||||
Type=Application
|
||||
Name={APP_NAME} (tray)
|
||||
Comment=Layar LCD AIO — berjalan di tray saat login (tanpa jendela)
|
||||
Exec="{appimage}" --tray-only
|
||||
Icon=iceburg-lcd
|
||||
Terminal=false
|
||||
X-GNOME-Autostart-enabled=true
|
||||
""")
|
||||
notes.append("autostart tray dibuat (--tray-only, tanpa jendela)")
|
||||
for path in other_autostart_entries(appimage):
|
||||
try:
|
||||
text = open(path).read()
|
||||
if "Hidden=true" not in text:
|
||||
with open(path, "a") as fh:
|
||||
fh.write("\nHidden=true\n")
|
||||
notes.append(f"entri autostart lain dinonaktifkan: {os.path.basename(path)}")
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
if os.path.exists(AUTOSTART_FILE):
|
||||
os.unlink(AUTOSTART_FILE)
|
||||
notes.append("autostart tray dihapus")
|
||||
for path in other_autostart_entries(appimage):
|
||||
try:
|
||||
lines = [l for l in open(path).read().splitlines() if l.strip() != "Hidden=true"]
|
||||
with open(path, "w") as fh:
|
||||
fh.write("\n".join(lines) + "\n")
|
||||
notes.append(f"entri autostart lain diaktifkan kembali: {os.path.basename(path)}")
|
||||
except OSError:
|
||||
pass
|
||||
return "; ".join(notes) or "tidak ada perubahan autostart tray"
|
||||
|
||||
|
||||
def systemctl(*args):
|
||||
return subprocess.run(["systemctl", "--user", *args], capture_output=True, text=True)
|
||||
|
||||
@@ -331,7 +392,7 @@ class Window(QWidget):
|
||||
super().__init__()
|
||||
self.tray = tray
|
||||
self.prev_stat = gr.stat_snapshot()
|
||||
self.setWindowTitle(f"GAMEMAX IceBurg LCD v{APP_VERSION}")
|
||||
self.setWindowTitle(f"{APP_NAME} v{APP_VERSION}")
|
||||
self.setWindowIcon(QIcon(icon_path()))
|
||||
self.setMinimumWidth(640)
|
||||
root = QVBoxLayout(self)
|
||||
@@ -341,7 +402,7 @@ class Window(QWidget):
|
||||
if isinstance(geom, list) and len(geom) == 4:
|
||||
self.setGeometry(*[int(g) for g in geom])
|
||||
|
||||
hint = QLabel("Kontrol layar LCD AIO GAMEMAX. Pilih slot kipas/sumber suhu di "
|
||||
hint = QLabel("Kontrol layar LCD AIO IceBurg Digital. Pilih slot kipas/sumber suhu di "
|
||||
"<b>Pengaturan</b> lalu klik <b>Simpan & terapkan</b>.")
|
||||
hint.setObjectName("hint")
|
||||
hint.setWordWrap(True)
|
||||
@@ -563,7 +624,7 @@ class Window(QWidget):
|
||||
return
|
||||
|
||||
box = QMessageBox(self)
|
||||
box.setWindowTitle("Tutup GAMEMAX LCD")
|
||||
box.setWindowTitle(f"Tutup {APP_NAME}")
|
||||
box.setText("Sembunyikan ke tray atau keluar sepenuhnya?")
|
||||
box.setInformativeText("Selama tersembunyi di tray, data sensor tetap dikirim ke layar.")
|
||||
remember = QCheckBox("Ingat pilihan ini")
|
||||
@@ -687,8 +748,10 @@ class Window(QWidget):
|
||||
systemctl("daemon-reload")
|
||||
res = systemctl("enable" if checked else "disable", SERVICE)
|
||||
state = service_enabled()
|
||||
note = set_tray_autostart(checked, installed_appimage())
|
||||
return (f"mulai otomatis saat login: {'AKTIF' if state else 'nonaktif'}"
|
||||
+ ("" if res.returncode == 0 else f" ({res.stderr.strip()})"))
|
||||
+ ("" if res.returncode == 0 else f" ({res.stderr.strip()})")
|
||||
+ f" | {note}")
|
||||
except Exception as exc: # noqa: BLE001
|
||||
return f"galat autostart: {exc}"
|
||||
|
||||
@@ -846,7 +909,7 @@ class Window(QWidget):
|
||||
"kosong": "Layar dikosongkan (nilai nol)",
|
||||
"berhenti": "Pengiriman data dihentikan"}
|
||||
if mode != "normal" or getattr(self, "_mode_seen", False):
|
||||
subprocess.run(["notify-send", "-a", "GAMEMAX LCD", "Status layar",
|
||||
subprocess.run(["notify-send", "-a", APP_NAME, "Status layar",
|
||||
labels[mode]], capture_output=True)
|
||||
self._mode_seen = True
|
||||
dot = "🟢" if active else "⚪"
|
||||
@@ -945,7 +1008,7 @@ class Tray:
|
||||
blank = bool(gr.load_config(CONFIG_PATH).get("blank"))
|
||||
state = ("layar kosong (nilai nol)" if blank and active
|
||||
else ("pengiriman dihentikan" if not active else "normal"))
|
||||
self.icon.setToolTip(f"GAMEMAX LCD: {state}")
|
||||
self.icon.setToolTip(f"{APP_NAME}: {state}")
|
||||
base = icon_path()
|
||||
self.icon.setIcon(dimmed_icon(base) if state != "normal" else QIcon(base))
|
||||
window = getattr(self, "window", None)
|
||||
@@ -959,7 +1022,7 @@ class Tray:
|
||||
self.window.raise_()
|
||||
self.window.activateWindow()
|
||||
if QSystemTrayIcon.isSystemTrayAvailable():
|
||||
self.icon.showMessage("GAMEMAX LCD", "Jendela dibuka dari permintaan kedua.",
|
||||
self.icon.showMessage(APP_NAME, "Jendela dibuka dari permintaan kedua.",
|
||||
QSystemTrayIcon.Information, 3000)
|
||||
|
||||
|
||||
@@ -976,7 +1039,7 @@ def main():
|
||||
|
||||
def _main():
|
||||
app = QApplication(sys.argv)
|
||||
app.setApplicationName("GAMEMAX LCD")
|
||||
app.setApplicationName(APP_NAME)
|
||||
app.setStyleSheet(APP_QSS)
|
||||
app.setQuitOnLastWindowClosed(False)
|
||||
|
||||
@@ -986,10 +1049,10 @@ def _main():
|
||||
if probe.waitForConnected(400):
|
||||
probe.write(b"raise")
|
||||
probe.waitForBytesWritten(400)
|
||||
print("GAMEMAX LCD sudah berjalan — instance pertama diminta membuka jendelanya.")
|
||||
print(f"{APP_NAME} sudah berjalan — instance pertama diminta membuka jendelanya.")
|
||||
# Beri tahu lewat notifikasi desktop juga, karena keluarnya proses kedua bisa
|
||||
# terlihat seperti crash saat diluncurkan dari menu.
|
||||
subprocess.run(["notify-send", "-a", "GAMEMAX LCD", "Sudah berjalan",
|
||||
subprocess.run(["notify-send", "-a", APP_NAME, "Sudah berjalan",
|
||||
"Aplikasi sudah aktif — jendelanya dibuka, cek taskbar/tray."],
|
||||
capture_output=True)
|
||||
return 0
|
||||
|
||||
@@ -423,9 +423,10 @@ def main():
|
||||
signal.signal(signal.SIGTERM, lambda *_: stop.set())
|
||||
signal.signal(signal.SIGINT, lambda *_: stop.set())
|
||||
print(f"menunggu {VID:#06x}:{PID:#06x} (Ctrl-C atau SIGTERM untuk berhenti)", flush=True)
|
||||
last_message = None
|
||||
while not stop.is_set():
|
||||
if not find_device():
|
||||
stop.wait(2)
|
||||
stop.wait(1)
|
||||
continue
|
||||
try:
|
||||
result = stream(a, overrides)
|
||||
@@ -433,8 +434,11 @@ def main():
|
||||
sent, dt = result
|
||||
print(f"perangkat terlepas setelah {sent} report ({sent / dt:.1f}/detik), menunggu lagi", flush=True)
|
||||
except OSError as exc:
|
||||
print(f"galat perangkat ({exc}), menunggu lagi", flush=True)
|
||||
stop.wait(2)
|
||||
message = f"galat perangkat ({exc}), menunggu lagi"
|
||||
if message != last_message: # ACL udev baru aktif setelah sesi login
|
||||
print(message, flush=True)
|
||||
last_message = message
|
||||
stop.wait(1)
|
||||
print("berhenti")
|
||||
return 0
|
||||
|
||||
|
||||
Reference in new issue
Block a user