Compare commits

...
Author SHA1 Message Date
aclist 7a6f4a2bb9 feat: immutable decorator 2026-11-11 07:52:05 +09:00
aclist ba92d15085 drop: unused signal logic 2026-11-11 07:50:54 +09:00
aclist 65e04c2fc4 fix: multiple signals being stacked 2026-11-11 07:50:38 +09:00
aclist 0907f5a474 change: immutable dataclass 2026-11-11 07:50:12 +09:00
aclist bfa83c3f94 change: import sort order 2026-11-11 07:15:53 +09:00
aclist aef48e515b fix: failing test 2026-11-11 07:15:28 +09:00
aclist e6ebeaeb5e chore: immutable dataclass 2026-11-11 07:04:25 +09:00
aclist 88c740105a chore: drop unused dataclasses 2026-11-11 07:02:23 +09:00
aclist b98a6f95a6 drop: unused imports 2026-11-11 07:00:17 +09:00
aclist 87d76e83ba chore: update DEVELOPERS.md 2026-11-11 06:57:56 +09:00
aclist a5374d1f1a Merge pull request #526 from aclist/fix/legacy-version-file
Mirror to Codeberg / mirror-to-codeberg (push) Waiting to run
fix: legacy version file
2026-11-11 05:08:14 +09:00
29 changed files with 96 additions and 127 deletions

No files matched your search

+6 -5
View File
@@ -5,7 +5,7 @@
### Fetch submodules
git submodule update --recursive --init
### Install with dev dependencies
### Install into editable venv with dev dependencies
uv pip install -e '.[dev]'
This includes all dependencies for building, linting, testing, and checking in code.
@@ -16,7 +16,7 @@ docs: documentation tools
lint: code linting, fixing, and type checking
test: unit and integration tests
## Miscellaneous
## Build process
### Setting up precommit hooks
pre-commit install
@@ -25,6 +25,7 @@ pre-commit install
sphinx-build -M html source build -a
### Building standalone release binaries
1. Set up the build target: `rustup target add x86_64-unknown-linux-musl`
2. Run `python3 scripts/release.py`
3. Generate a release and tag against the resulting tarfile generated in `dist`
1. Install the applicable system package containing the 'musl-gcc' wrapper
2. Set up the build target: `rustup target add x86_64-unknown-linux-musl`
3. Run `python3 scripts/release.py`
4. Generate a release and tag against the resulting tarfile generated in `dist`
-1
View File
@@ -3,7 +3,6 @@ import logging
import re
from concurrent.futures import ThreadPoolExecutor, wait
from dataclasses import dataclass
from pathlib import Path
from typing import Any
+1 -2
View File
@@ -6,7 +6,6 @@ from importlib import resources
from pathlib import Path
from typing import TYPE_CHECKING
from dzgui.const.constants import (
APP_NAME,
APP_NAME_LOWER,
@@ -107,7 +106,7 @@ def load_steam_icon() -> None:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
from gi.repository import Gtk
try:
traversable = resources.files(APP_NAME_LOWER).joinpath(ICONS_PATH)
+1 -1
View File
@@ -12,7 +12,7 @@ from dzgui.const.constants import (
from dzgui.init.proc import is_sandboxed
@dataclass
@dataclass(slots=True, frozen=True)
class Xdg:
config: Path
columns: Path
+3 -8
View File
@@ -1,11 +1,11 @@
import gi
import logging
import threading
from typing import Any, TYPE_CHECKING, Union
import dzgui.util._json as JSON # noqa
from dzgui.config.userprefs import UserPrefs
from dzgui.const.constants import APP_NAME
from dzgui.const.enum import (
ButtonType,
ContextMenuItem,
@@ -14,9 +14,6 @@ from dzgui.const.enum import (
Preferences,
ServerTab,
)
from dzgui.config.userprefs import UserPrefs
from dzgui.const.constants import APP_NAME
from dzgui.controllers.emitter import Emitter
from dzgui.managers.config import ConfigManager
from dzgui.managers.connection import ConnectionManager
@@ -29,8 +26,6 @@ from dzgui.util.open_links import open_user_workshop, open_workshop_page
from dzgui.views.dialogs.filepicker import FilePicker
from dzgui.views.dialogs.generic import ExceptionDialog
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib, GObject
+1 -1
View File
@@ -34,7 +34,7 @@ LAN_TIMEOUT = 0.5
API_TIMEOUT = 3
@dataclass
@dataclass(slots=True, frozen=True)
class NewPlayerCount:
treeiter: Gtk.TreeIter
players: int
+9
View File
@@ -0,0 +1,9 @@
from dataclasses import dataclass
from typing import Callable
def immutable_dataclass(cls: type | None = None, **kwargs: bool) -> type | Callable[[type], type]:
kwargs["slots"] = True
kwargs["frozen"] = True
if cls is None:
return lambda c: dataclass(c, **kwargs)
return dataclass(cls, **kwargs)
+2 -3
View File
@@ -1,10 +1,10 @@
import a2s
from ipaddress import ip_address
import requests
import shutil
import subprocess
from dataclasses import dataclass
from ipaddress import ip_address
from typing import TYPE_CHECKING
from dzgui.api.servers import Record
@@ -12,12 +12,11 @@ from dzgui.config.ipdb import read_from_table
from dzgui.const.constants import REQUEST_TIMEOUT
from dzgui.const.endpoints import IP_ECHO
if TYPE_CHECKING:
from pathlib import Path
@dataclass
@dataclass(slots=True, frozen=True)
class Coords:
lat: float
lon: float
+3 -3
View File
@@ -1,9 +1,9 @@
from typing import Sequence
import gi
from typing import Sequence
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
from gi.repository import Gtk
class GenericBox(Gtk.Box):
+5 -4
View File
@@ -1,10 +1,11 @@
from typing import Self
from dzgui.util import css
import gi
from typing import Self
from dzgui.util import css
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
from gi.repository import Gtk
# TODO: subclass Gtk.Frame directly
+2 -3
View File
@@ -1,3 +1,4 @@
import gi
from typing import Self
from warnings import deprecated
@@ -8,10 +9,8 @@ from dzgui.strings import options
from dzgui.views.components.box import HBox
from dzgui.views.components.buttons import Icon
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
from gi.repository import Gtk
@deprecated("Client choice is determined at setup time")
+1 -1
View File
@@ -1,7 +1,7 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
from gi.repository import Gtk
class NoOverlayScrolledWindow(Gtk.ScrolledWindow):
+5 -11
View File
@@ -1,13 +1,9 @@
import gi
import sys
from enum import Enum
from typing import Any, Literal, Self, TYPE_CHECKING
# import time
from enum import Enum
from dzgui.views.mixins.colorscheme import ColorAwareApp
# TODO: import dialog titles
from dzgui.api.mods import remove_stale_signatures as remove_stale
from dzgui.config.ipdb import get_ipdb
from dzgui.const.constants import HEX_GREEN, HEX_RED
@@ -20,12 +16,10 @@ from dzgui.util.format import format_exception
from dzgui.util.strings import dialog_header
from dzgui.util.symlink import rebuild_symlinks
from dzgui.views.components.buttons import ClipboardButton
import gi
from dzgui.views.mixins.colorscheme import ColorAwareApp
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk # noqa
from gi.repository import Gtk, GLib, Gdk
if TYPE_CHECKING:
from dzgui.config.xdg import Xdg
+1 -1
View File
@@ -15,7 +15,7 @@ from dzgui.views.dialogs.generic import GenericDialog
from dzgui.views.trees.tree_base import TreeView
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, Pango # noqa
from gi.repository import Gtk, Gdk, Pango
if TYPE_CHECKING:
from dzgui.api.servers import Details
+3 -3
View File
@@ -1,3 +1,5 @@
import gi
from typing import Any
from dzgui.const.constants import (
@@ -7,10 +9,8 @@ from dzgui.const.constants import (
GIO_SETTINGS_VAL,
)
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gio # noqa
from gi.repository import Gtk, Gio
class ColorAwareApp:
+1 -1
View File
@@ -1,7 +1,7 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa
from gi.repository import Gtk, Gdk
class HelpMenuMixin:
+3 -3
View File
@@ -1,10 +1,10 @@
import gi
from dzgui.const.enum import VAdjustment
from dzgui.const.constants import SCROLL_INCREMENT
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa
from gi.repository import Gtk, Gdk
class ScrollableMixin:
+2 -3
View File
@@ -1,3 +1,4 @@
import gi
from pathlib import Path
from typing import Self, TYPE_CHECKING
@@ -8,10 +9,8 @@ from dzgui.views.components.buttons import SteamWorkshopButton
from dzgui.views.components.scrollable import NoOverlayScrolledWindow
from dzgui.views.trees.tree_mods import ModTreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+6 -6
View File
@@ -1,9 +1,10 @@
from __future__ import annotations
import gi
from enum import Enum
from typing import Self, TYPE_CHECKING, Union
from dzgui.util import css
from dzgui.const.icons import ICON_EDIT_DELETE, ICON_FOLDER, ICON_WARNING
from dzgui.const.constants import (
APPID_DAYZ,
APPID_DAYZ_EXP,
@@ -11,8 +12,10 @@ from dzgui.const.constants import (
APPNAME_DAYZ_EXP_HUMAN,
)
from dzgui.const.enum import ContextMenuGroup, NotebookPage
from dzgui.const.icons import ICON_EDIT_DELETE, ICON_FOLDER, ICON_WARNING
from dzgui.managers.offline import OfflineManager
from dzgui.strings import generic, offline
from dzgui.util import css
from dzgui.views.components.box import HBox, VBox
from dzgui.views.components.buttons import Icon, IconTextButton
from dzgui.views.components.eventbox import InfoEventBox
@@ -21,11 +24,8 @@ from dzgui.views.components.scrollable import NoOverlayScrolledWindow
from dzgui.views.components.misc import ErrorPopover
from dzgui.views.trees.tree_mods import OfflineModTreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GObject # noqa
from gi.repository import Gtk, Gdk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+14 -17
View File
@@ -1,9 +1,10 @@
import gi
from pathlib import Path
from typing import Any, Callable, TYPE_CHECKING
from dzgui.api import pefile as PeFile
from dzgui.api.steam import get_last_updated
from dzgui.config import query
from dzgui.const.constants import (
APPID_DAYZ,
@@ -14,12 +15,11 @@ from dzgui.const.constants import (
FLATPAK_SANDBOX,
FLATPAK_STEAM_PATH,
)
from dzgui.const.icons import ICON_VIEW_CONCEAL, ICON_VIEW_REVEAL
from dzgui.const.endpoints import STEAM_API_SETUP
from dzgui.const.enum import Preferences, ServerTab
from dzgui.const.icons import ICON_VIEW_CONCEAL, ICON_VIEW_REVEAL
from dzgui.strings import options
from dzgui.util import strings, css, open_links
from dzgui.views.components.box import ShortHBox, VBox
from dzgui.views.components.eventbox import InfoEventBox
from dzgui.views.components.labels import LeftLabel
@@ -29,11 +29,8 @@ from dzgui.views.components.misc import ErrorPopover
from dzgui.views.dialogs.generic import ExceptionDialog
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa
from gi.repository import Gtk, Gdk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
@@ -233,10 +230,19 @@ class ToggleField(Gtk.Box):
self.pack_start(self.radio1, expand=False, fill=False, padding=0)
self.pack_start(self.radio2, expand=False, fill=False, padding=0)
self.signal_id: int | None = None
def disconnect_signal(self) -> None:
if self.signal_id is not None:
self.radio1.disconnect(self.signal_id)
def set_suboption_active(self, state: bool) -> None:
# NOTE: defer connection of signal until after state is set
self.radio2.set_active(state)
self.radio1.connect("toggled", self._on_radio_toggled, self.context)
self.disconnect_signal()
self.signal_id = self.radio1.connect(
"toggled", self._on_radio_toggled, self.context
)
def _on_radio_toggled(self, button: Gtk.RadioButton, context: Preferences) -> None:
self.controller.toggle_config(context)
@@ -486,14 +492,5 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
start_tab = self.controller.query_config(Preferences.START_TAB)
self.start_tab_combo.set_active(start_tab)
def _suppress_toggles(self, state: bool) -> None:
for toggle in [
self.fullscreen_toggle,
self.distance_toggle,
]:
self.controller.suppress_signal(
self, toggle.get_children()[0], "_on_radio_toggled", state
)
def grab_content_area(self) -> None:
self.grab_focus()
+3 -20
View File
@@ -1,11 +1,12 @@
from dataclasses import dataclass
import gi
from typing import Self, Sequence, TYPE_CHECKING
from dzgui.const.enum import NotebookPage
from dzgui.const.icons import (
ICON_ERROR,
ICON_WARNING,
)
from dzgui.const.enum import NotebookPage
from dzgui.util.css import add_class
from dzgui.util.keys import is_ctrl_mask
from dzgui.util.localize import number
@@ -15,33 +16,15 @@ from dzgui.views.dialogs.generic import DebugDialog
from dzgui.views.components.frame import HeadingFrame
from dzgui.views.trees.tree_server_mods import ServerModTreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gdk, Gtk
if TYPE_CHECKING:
from dzgui.managers.connection import Prerequisites
from dzgui.controllers.mc import Controller
from dzgui.controllers.emitter import Emitter
@dataclass
class Warnings:
passworded: bool
dayz_running: bool
no_steam: bool
wrong_version: bool
@dataclass
class Errors:
no_space: bool
no_dayz_exp: bool
no_dayz: bool
class Placeholder(Gtk.Label):
def __init__(self, text: str) -> None:
super().__init__(
+2 -3
View File
@@ -1,3 +1,4 @@
import gi
import logging
from typing import Any, Optional, TYPE_CHECKING
@@ -6,10 +7,8 @@ from dzgui.const.constants import APP_NAME, SEPARATOR
from dzgui.util.keys import is_ctrl_mask, is_navkey
from dzgui.views.mixins.cursor_mixin import CursorMixin
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
from gi.repository import Gtk, Gdk, GObject
logger = logging.getLogger(APP_NAME)
+1 -1
View File
@@ -10,7 +10,7 @@ from dzgui.views.trees.tree_base import TreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
from gi.repository import Gtk
logger = logging.getLogger(APP_NAME)
+3 -3
View File
@@ -1,4 +1,6 @@
import gi
import logging
from typing import Any, TYPE_CHECKING
from dzgui.const.constants import APP_NAME, HEX_RED
@@ -9,10 +11,8 @@ from dzgui.views.mixins.context_mixin import ContextMixin
from dzgui.views.mixins.mods_mixin import ModsMixin
from dzgui.views.trees.tree_base import TreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
from gi.repository import Gtk, Gdk
if TYPE_CHECKING:
+5 -5
View File
@@ -1,15 +1,15 @@
import gi
from typing import TYPE_CHECKING
from dzgui.const.enum import ContextMenuGroup
from dzgui.model.model_factory import ModelFactory
from dzgui.strings import server_mods
from dzgui.views.mixins.context_mixin import ContextMixin
from dzgui.views.trees.tree_base import TreeView
from typing import TYPE_CHECKING
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, Pango # noqa
from gi.repository import Gtk, Pango
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+4 -8
View File
@@ -1,8 +1,9 @@
import gi
import logging
import threading
from queue import Queue
from typing import Any, Self, Union
from typing import Any, Literal, Self, TYPE_CHECKING, Union
from warnings import deprecated
from dzgui.api.servers import ping, Record
@@ -14,17 +15,11 @@ from dzgui.util import strings
from dzgui.util.dist import CalcDist
from dzgui.util.keys import is_ctrl_mask
from dzgui.views.mixins.context_mixin import ContextMixin
from typing import Literal, TYPE_CHECKING
from dzgui.views.trees.tree_base import TreeView
import dzgui.util._json as JSON # noqa
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
from gi.repository import Gtk, GLib, Gdk, GObject
logger = logging.getLogger(APP_NAME)
@@ -415,6 +410,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
real_model = self.proxy_man.get_control()
from dataclasses import fields
from dzgui.model.proxy_model import ServerRow
key = fields(ServerRow)[col_index].name
value = getattr(real_model[row_index], key)
+5 -5
View File
@@ -1,13 +1,13 @@
import gi
from typing import TYPE_CHECKING, Union
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.model.model_factory import FastInsertListStore
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa
class SimpleTree(Gtk.ScrolledWindow):
"""Simple scrollable 1-column tree"""
+2 -3
View File
@@ -1,13 +1,12 @@
import gi
import pytest
import subprocess
from dzgui.const.constants import GIO_SETTINGS_KEY
from dzgui.views.mixins.colorscheme import ColorAwareApp
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gio, GLib # noqa
from gi.repository import Gtk, GLib
class DummyWidget(ColorAwareApp, Gtk.Button):
+2 -2
View File
@@ -48,5 +48,5 @@ def test_signatures_with_no_ids(monkeypatch, tmp: str, versions: str) -> None:
monkeypatch.setattr("dzgui.api.mods.lookup", mock_lookup)
dzgui.api.mods.remove_stale_signatures(path, path)
with open(tmp, "r") as f:
lines = f.readlines()
assert lines == ["3410710885,1752864732\n", "3739934289,1780855136\n"]
lines = [line.rstrip() for line in f.readlines()]
assert lines == ["3410710885,1752864732", "3739934289,1780855136"]