Compare commits

...
Author SHA1 Message Date
aclist f97be9352d fix: typo 2026-10-26 17:21:10 +09:00
aclist b092a809f4 fix: capitalization 2026-10-26 17:20:28 +09:00
aclist 2cc7710807 fix: handle sandboxed mode 2026-10-26 17:20:14 +09:00
aclist 5fb10d9758 change: suppress missing shortcuts message 2026-10-26 17:19:56 +09:00
aclist 100cb43afc Merge pull request #502 from aclist/fix/check-granular-client
fix: check granular client
2026-10-26 16:15:47 +09:00
aclist 7e2a585812 chore: drop unused imports 2026-10-26 16:14:57 +09:00
aclist c1181435b3 chore: formatting 2026-10-26 16:13:56 +09:00
aclist 22a7814ce4 fix: check actual client command 2026-10-26 16:13:42 +09:00
aclist b030da5c65 Merge pull request #498 from aclist/fix/refresh-on-timeout
fix: refresh on timeout
2026-10-26 15:56:51 +09:00
aclist 3c0acdd068 Merge pull request #501 from aclist/fix/symbolic-svg
fix: symbolic svg
2026-10-26 15:56:16 +09:00
aclist 25ae2052e4 Merge branch 'dzgui7' into fix/symbolic-svg
Mirror to Codeberg / mirror-to-codeberg (push) Waiting to run
2026-10-26 15:55:37 +09:00
aclist 1b1777117f Merge pull request #497 from aclist/feat/dynamic-flatpak-toggle
feat: dynamic flatpak toggle
2026-10-26 15:51:18 +09:00
aclist 97ee2b7307 chore: update attribution 2026-10-23 13:07:38 +09:00
aclist ff6edb6181 fix: light mode symbolic icon 2026-10-23 13:05:20 +09:00
aclist 4c22263fb5 Merge branch 'dzgui7' of github.com:aclist/dztui into dzgui7 2026-10-23 13:04:09 +09:00
aclist 141f96fb9f fix: allow using refresh button after timeout events (#484) 2026-10-22 15:59:05 +09:00
10 changed files with 46 additions and 32 deletions

No files matched your search

+3 -1
View File
@@ -17,7 +17,7 @@ DZGUI follows a specific set of guidelines, enumerated below:
- Provide a free and open-source tool under GPL
- Do not use undocumented, third-party servers to aggregate data; no central "DZGUI" server
- All connections go to Steam and DayZ servers directly; the tool should function in perpetuity without intermediary endpoints
- Target Linux desktop and Steam deck specifically; not a cross-platform tool
- Target Linux desktop and Steam Deck specifically; not a cross-platform tool
## Setup and usage
@@ -35,6 +35,8 @@ Geolocation records from [DB-IP](https://db-ip.com) under [CC 4.0 license](https
Executable versions of DZGUI published as release binaries ship with various runtime dependencies and the Python interpreter built in.
Users wishing to review the licenses to these components can inspect the `LICENSE` file located in the release tarball.
Steam and the Steam logo are trademarks and/or registered trademarks of Valve Corporation in the U.S. and/or other countries.
## Disclaimer
DZGUI is beta-quality software and is provided as-is.
+6 -5
View File
@@ -173,11 +173,12 @@ class Shortcuts:
self.save_shortcuts()
def save_shortcuts(self) -> None:
try:
backup = self.shortcuts_path.with_suffix(".vdf.bak")
shutil.copy(self.shortcuts_path, backup)
except Exception as e:
logger.critical(e)
if self.shortcuts_path.is_file():
try:
backup = self.shortcuts_path.with_suffix(".vdf.bak")
shutil.copy(self.shortcuts_path, backup)
except Exception as e:
logger.critical(e)
try:
with open(self.shortcuts_path, "wb") as f:
vdf.binary_dump(self.shortcuts, f)
+3 -5
View File
@@ -13,7 +13,7 @@ from warnings import deprecated
from dzgui.api.acf import ACF
from dzgui.init.prereqs import has_any_client
from dzgui.init.proc import has_cmd
from dzgui.init.prereqs import has_flatpak_client, has_steam_client
from dzgui.const.constants import (
APPID_DAYZ,
APPID_DAYZ_EXP,
@@ -23,11 +23,9 @@ from dzgui.const.constants import (
DEBIAN_STEAM_PATH,
DEFAULT_STEAM_PATH,
DOWNLOADS_PATH,
FLATPAK_CMD,
FLATPAK_STEAM_PATH,
LIBRARYFOLDERS_PATH,
REQUEST_TIMEOUT,
STEAM_CMD,
UBUNTU_STEAM_PATH,
VDF_PATH,
)
@@ -85,9 +83,9 @@ def get_steam_paths() -> list[tuple[Path, str]]:
}
for path in DEFAULT_PATH, FLATPAK_PATH, UBUNTU_PATH, DEBIAN_PATH:
if path is FLATPAK_PATH and has_cmd(FLATPAK_CMD) is False:
if path is FLATPAK_PATH and has_flatpak_client() is False:
continue
if path is not FLATPAK_PATH and has_cmd(STEAM_CMD) is False:
if path is not FLATPAK_PATH and has_steam_client() is False:
continue
if path.joinpath(VDF_PATH).is_file():
paths.append((path, human[path]))
+11 -15
View File
@@ -2,16 +2,16 @@ import logging
import os
import shutil
from importlib import resources
from pathlib import Path
from typing import TYPE_CHECKING
from warnings import deprecated
from dzgui.const.constants import (
APP_NAME,
APP_NAME_LOWER,
FLATPAK_ROOT_PATH,
STEAM_ICON,
STEAM_ICONS_PATH,
ICONS_PATH,
)
from dzgui.const.enum import Preferences
from dzgui.config.query import lookup
@@ -31,7 +31,7 @@ from dzgui.util.dirs import make_parents
from dzgui.util.localize import set_locale
from dzgui.util.map_count import test_map_count
from dzgui.util.redact import RedactionFilter, REDACTION_PATTERNS
from dzgui.util.strings import init, steam_icon_missing
from dzgui.util.strings import init
from dzgui.views.base import App
from dzgui.views.dialogs.boot import BootWindow
@@ -104,26 +104,21 @@ def copy_bare_configs(config: "Path", resolution: "Path") -> tuple[bool, bool]:
return (config_changed, state_changed)
@deprecated("Currently unused")
def load_steam_icon(config: Path) -> None:
def load_steam_icon() -> None:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
default = lookup(config, Preferences.DEFAULT)
icon_path = Path(default).joinpath(STEAM_ICONS_PATH)
try:
traversable = resources.files(APP_NAME_LOWER).joinpath(ICONS_PATH)
icons = Path(str(traversable))
theme = Gtk.IconTheme.get_default()
paths = theme.get_search_path()
theme.set_search_path(paths + [str(icon_path)])
paths = theme.get_search_path()
icons = theme.list_icons(None)
if STEAM_ICON not in icons:
logger.warning(steam_icon_missing)
theme.set_search_path(paths + [str(icons)])
except Exception as e:
print(e)
logger.warning(e)
logger.critical(e)
def load_gui(version: str, is_debug: bool) -> None:
@@ -189,5 +184,6 @@ def load_gui(version: str, is_debug: bool) -> None:
use_miles=use_miles,
)
print(boot.all_ok)
load_steam_icon()
app = App(prefs)
app.run(None)
+2 -2
View File
@@ -51,7 +51,7 @@ INPUT_KEYBOARD = "input-keyboard-symbolic"
LIST_ADD = "list-add-symbolic"
REFRESH_ICON = "view-refresh-symbolic"
SEARCH_ICON = "system-search-symbolic"
STEAM_ICON = "steam_tray_mono"
STEAM_ICON = "steam-tray-symbolic"
VIEW_CONCEAL = "view-conceal-symbolic"
VIEW_REVEAL = "view-reveal-symbolic"
WARNING = "dialog-warning-symbolic"
@@ -80,6 +80,7 @@ DEBUG_LOG = f"{APP_NAME}_DEBUG.LOG"
SYSTEM_LOG = f"{APP_NAME}_SYSTEM.LOG"
CHANGELOG_PATH = "data/CHANGELOG.md"
IMAGES_PATH = "data/images"
ICONS_PATH = "data/images/gtk"
HERO_PATH = "data/images/_hero.png"
CSS_PATH = "data/app.css"
@@ -89,7 +90,6 @@ FLATPAK_ROOT_PATH = ".var/app/com.valvesoftware.Steam"
FLATPAK_STEAM_PATH = FLATPAK_ROOT_PATH + "/data/Steam"
UBUNTU_STEAM_PATH = ".steam/steam"
DEBIAN_STEAM_PATH = ".steam/debian-installation"
STEAM_ICONS_PATH = "public"
LOG_FILTERS = ("CRITICAL", "WARNING", "INFO", "DEBUG")
+4
View File
@@ -111,6 +111,10 @@ class Emitter(GObject.GObject):
def check_toggled(self, label: str, state: bool) -> None:
pass
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
def servers_timed_out(self) -> None:
pass
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,))
def servers_loaded(self, tag: "ServerTab") -> None:
pass
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M568 320C568 457 456.8 568 319.6 568C205.8 568 110 491.7 80.6 387.6L175.8 426.9C182.2 459 210.7 483.3 244.7 483.3C283.9 483.3 316.6 450.9 314.9 409.8L399.4 349.6C451.5 350.9 495.2 308.7 495.2 256.1C495.2 204.5 453.2 162.6 401.5 162.6C349.8 162.6 307.8 204.6 307.8 256.1L307.8 257.3L248.6 343C233.1 342.1 217.9 346.4 205.1 355.1L72 300.1C82.2 172.4 189.1 72 319.6 72C456.8 72 568 183 568 320zM227.7 448.3L197.2 435.7C202.8 447.3 212.5 456.5 224.4 461.5C251.3 472.7 282.2 459.9 293.4 433.1C298.8 420.1 298.9 405.8 293.5 392.8C288.1 379.8 278 369.6 265 364.2C252.1 358.8 238.3 359 226.1 363.6L257.6 376.6C277.4 384.8 286.8 407.5 278.5 427.3C270.2 447.2 247.5 456.5 227.7 448.3zM401.5 193.8C435.9 193.8 463.8 221.7 463.8 256.1C463.8 290.5 435.9 318.4 401.5 318.4C367.1 318.4 339.2 290.5 339.2 256.1C339.2 221.7 367.1 193.8 401.5 193.8zM401.6 302.8C427.4 302.8 448.4 281.8 448.4 256C448.4 230.2 427.4 209.2 401.6 209.2C375.8 209.2 354.8 230.2 354.8 256C354.8 281.8 375.8 302.8 401.6 302.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+3
View File
@@ -3,11 +3,14 @@ import shutil
import subprocess
from dzgui.const.constants import APP_NAME, FLATPAK_APPID, FLATPAK_CMD, STEAM_CMD
from dzgui.init.proc import is_sandboxed
logger = logging.getLogger(APP_NAME)
def has_flatpak_client() -> bool:
if is_sandboxed():
return True
try:
res = subprocess.run(
[FLATPAK_CMD, "list", "--columns=application"],
+3
View File
@@ -92,6 +92,7 @@ class ServerModelManager:
job = Servers.query_api
params = Servers.params
servers = []
with ThreadPoolExecutor() as executor:
futures = [executor.submit(job, key, APPID_DAYZ, param) for param in params]
for future in as_completed(futures):
@@ -414,6 +415,8 @@ class ServerModelManager:
# TODO: disable map, keyword, and filter widgets if model is None
# signal driven (servers_empty, servers_failed_to_load)
self.emitter.emit("servers_timed_out")
if self.preserve_on_fail is False:
self.tv.set_model(None)
filter_man = self.tv.get_filter_man()
+10 -4
View File
@@ -163,18 +163,24 @@ class RefreshButton(IconTextButton):
self.set_tooltip_text(atomic_buttons.refresh_tooltip)
self.connect("clicked", self._on_refresh_clicked)
emitter.connect("servers_loaded", self.start_decrement)
emitter.connect("servers_loaded", self._on_load)
emitter.connect("servers_timed_out", self._on_timeout)
def _on_timeout(self, emitter: "Emitter") -> None:
self.is_clicked = True
self.start_decrement()
def _on_load(self, emitter: "Emitter", tab: "ServerTab") -> None:
self.start_decrement()
def _on_refresh_clicked(self, button: Self) -> None:
"""Spawned in a thread"""
if self.controller.get_active_treeview().is_loaded() is False:
return
self.is_clicked = True
self.controller.refresh_tree()
# TODO: get server tab enum
# if LAN tab, reload existing entries in place
def start_decrement(self, emitter: "Emitter", tab: "ServerTab") -> None:
def start_decrement(self) -> None:
if self.is_clicked is False:
return
if self.loading: