Compare commits

..

26 Commits

Author SHA1 Message Date
aclist
c0015c05ec
Merge pull request #434 from aclist/fix/maximize-after-realize
Some checks are pending
Mirror to Codeberg / mirror-to-codeberg (push) Waiting to run
fix: test maximizing after widget and children are fully realized
2026-08-05 00:24:08 +09:00
aclist
682b5bb4c0 chore: rename method 2026-08-05 00:23:10 +09:00
aclist
3551877192 chore: test maximizing after widget and children are fully realized 2026-08-05 00:22:12 +09:00
aclist
b22aba8593
Merge pull request #433 from aclist/fix/set-default-before-maximize
chore: test setting default size before maximizing
2026-08-05 00:06:09 +09:00
aclist
f85f1ef2a5 chore: test setting default size before maximizing 2026-08-05 00:04:21 +09:00
aclist
010d7984b6
Merge pull request #432 from aclist/fix/set-default-size
chore: test using default dimensions defined in wizard
2026-08-04 23:57:50 +09:00
aclist
70e1e9e740 Merge branch 'fix/set-default-size' of github.com:aclist/dztui into fix/set-default-size 2026-08-04 23:57:06 +09:00
aclist
734af7cf22 chore: test using default dimensions defined in wizard 2026-08-04 23:56:56 +09:00
aclist
d8f4977ffe chore: use default dimensiontest usingefined in wizard 2026-08-04 23:55:54 +09:00
aclist
c9fd00f938
Merge pull request #431 from aclist/fix/defer-maximize
chore: test deferring maximize call until after widget is realized
2026-08-04 23:38:30 +09:00
aclist
f4db1484d8 chore: test deferring maximize call until after widget is realized 2026-08-04 23:36:08 +09:00
aclist
99ef9a31b9
Merge pull request #430 from aclist/fix/steam-deck-fs
fix: maximize UI on Steam Deck
2026-08-04 23:16:44 +09:00
aclist
4c392dc571 chore: bump version 2026-08-04 23:15:22 +09:00
aclist
155ffea15d chore: more idiomatic syntax 2026-08-04 23:15:01 +09:00
aclist
57d231331d fix: trigger maximize on steam deck (#426) 2026-08-04 23:14:20 +09:00
aclist
d5fe3c35dc
Merge pull request #429 from aclist/fix/scrollable-key-nav
fix: repack certain pages to support keybindings
2026-08-04 23:12:07 +09:00
aclist
3cf547e903 chore: backport changes from dzgui7 branch
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2026-08-04 23:09:54 +09:00
aclist
bd0bfcb03d
Merge pull request #428 from aclist/fix/invalid-mod-manifest
fix: handle invalid mods on server
2026-08-04 23:06:05 +09:00
aclist
4f6c583294 chore: add comment
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2026-08-04 23:05:12 +09:00
aclist
5e5a6b4eaf chore: more generic warning message 2026-08-04 23:04:47 +09:00
aclist
ff59d6dc35 chore: clear typehinting errors 2026-08-04 18:04:22 +09:00
aclist
1c154a709d fix: repack certain pages to support mixins 2026-08-04 18:03:14 +09:00
aclist
fb47564618 chore: trigger checks
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2026-07-31 23:13:03 +09:00
aclist
30e309442b chore: trigger checks 2026-07-30 20:45:58 +09:00
aclist
3e4ed95908 chore: trigger checks 2026-07-30 20:37:14 +09:00
aclist
93edbac5b0 fix: handle invalid mods on server 2026-07-30 20:35:23 +09:00
9 changed files with 58 additions and 19 deletions

View File

@ -139,6 +139,9 @@ def get_remote_signatures(mods: list[str]) -> list[tuple[str, str, int, int]]:
j = r.json()
rows = j["response"]["publishedfiledetails"]
for row in rows:
# NOTE: not a valid published file
if row["result"] == 9:
continue
title = str(row["title"])
_id = str(row["publishedfileid"])
time = int(row["time_updated"])
@ -205,9 +208,11 @@ def launch_offline(
proc = subprocess.run([*client_args, *params])
return proc.returncode
def find_loginusers(path: Path) -> Path:
return path / "config" / "loginusers.vdf"
def find_user_id(path: Path) -> str | None:
resolved_path = find_loginusers(path)
try:
@ -226,7 +231,6 @@ def find_user_id(path: Path) -> str | None:
return None
def find_user_id_32(path: Path) -> int:
uid = find_user_id(path)
if uid is None:

View File

@ -86,6 +86,7 @@ class Prerequisites:
mods: list[list[str]]
game_mode: bool
is_last_server: bool
invalid_mods: list[tuple[str, str]]
allows_downloads: tuple[bool, str]
@ -191,6 +192,9 @@ class ConnectionManager:
is_last = self.is_last_server()
# TODO: strings
invalid_mods = [(mod[0], mod[1]) for mod in remote_mods if mod[2] == "Invalid mod"]
prereqs = Prerequisites(
name=info.server_name,
appid=info.game_id,
@ -206,6 +210,7 @@ class ConnectionManager:
mods=remote_mods,
game_mode=game_mode,
is_last_server=is_last,
invalid_mods=invalid_mods,
allows_downloads=allows_downloads,
)
@ -261,6 +266,11 @@ class ConnectionManager:
for mod in alpha_mods:
if any(mod[1] in tuple for tuple in missing_mods):
mod[2] = resync
for mod in alpha_mods:
# NOTE: if the mod is neither synched or out of date, it is a malformed mod
if mod[2] == "":
# TODO: strings
mod[2] = "Invalid mod"
return alpha_mods, missing_mods

View File

@ -2,7 +2,7 @@ import logging
import signal
import warnings
from typing import TYPE_CHECKING, Literal
from typing import TYPE_CHECKING, Literal, Self
from dzgui.const.constants import APP_NAME, APP_NAME_LOWER, STEAM_ICON
from dzgui.const.enum import NotebookPage
@ -54,10 +54,12 @@ class OuterWindow(Gtk.Window):
MainController.register_widget("window", self)
# NOTE: steam deck taskbar may occlude elements
if MainController.get_prefs().is_steam_deck is False:
self.is_deck = MainController.get_prefs().is_steam_deck
if not self.is_deck:
self.set_titlebar(self.hb)
self.connect("delete-event", self._on_delete_event)
self.connect("realize", self._on_realize)
self.grid = Grid()
self.add(self.grid)
@ -73,6 +75,10 @@ class OuterWindow(Gtk.Window):
MainController.loaded = True
MainController.populate_model(MainController.get_active_treeview())
def _on_realize(self, window: Self) -> None:
if self.is_deck:
self.maximize()
def _on_delete_event(self, window: "OuterWindow", event: Gdk.EventKey) -> None:
self.halt_proc_and_quit()

View File

@ -37,7 +37,11 @@ class CursorMixin:
end = len(model) - 1
else:
return False
cur_row = self.get_focused_row_index() # type: ignore
try:
cur_row = self.get_focused_row_index() # type: ignore
except Exception:
return False
if position == CursorPosition.DOWN:
if cur_row == end:

View File

@ -103,4 +103,4 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
return grid
def grab_content_area(self) -> None:
self.box.grab_focus()
self.grab_focus()

View File

@ -521,3 +521,6 @@ class OfflineLoader(Gtk.Box):
self.mission_frame.present_folder_changed(mission)
return
self.offline_man.launch(appid, mission, local_mods, custom_folder, custom_mods)
def grab_content_area(self) -> None:
self.local_frame.tree.grab_focus()

View File

@ -20,11 +20,13 @@ from dzgui.const.enum import Preferences, ServerTab
from dzgui.strings import errors, options
from dzgui.util import strings, css, open_links
from dzgui.views.components.box import VBox
from dzgui.views.components.labels import LeftLabel
from dzgui.views.components.buttons import WebButton
from dzgui.views.components.frame import HeadingFrame
from dzgui.views.components.misc import ClientCombo
from dzgui.views.dialogs.generic import ExceptionDialog
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
import gi
@ -44,10 +46,9 @@ class ShortHBox(Gtk.Box):
self.pack_start(widget, NO_EXPAND, NO_FILL, NO_PADDING)
class Options(Gtk.Box):
class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
def __init__(self, controller: "Controller"):
super().__init__(
orientation=Gtk.Orientation.VERTICAL,
margin_start=10,
margin_end=10,
)
@ -60,11 +61,6 @@ class Options(Gtk.Box):
self.DEFAULT_WIDTH = 1
self.DEFAULT_HEIGHT = 1
label = Gtk.Label(label=strings.options.header)
label.set_halign(Gtk.Align.CENTER)
css.add_class(label, "page-heading")
self.add(label)
self.steam_entry: Gtk.Entry
self.steam = WebButton(label=strings.options.steam_web)
@ -165,9 +161,16 @@ class Options(Gtk.Box):
grid.attach(frame, col, row, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT)
row += 1
self.scrollable = Gtk.ScrolledWindow(vexpand=True)
self.scrollable.add(grid)
self.add(self.scrollable)
label = Gtk.Label(label=strings.options.header)
label.set_halign(Gtk.Align.CENTER)
css.add_class(label, "page-heading")
box = VBox()
box.add(label)
box.add(grid)
self.add(box)
self.connect("key-press-event", self._on_keypress)
def get_client_name(self) -> str:
model = self.client_combo.get_model()
@ -442,4 +445,4 @@ class Options(Gtk.Box):
widget.set_visibility(state)
def grab_content_area(self) -> None:
return
self.grab_focus()

View File

@ -239,6 +239,15 @@ class PreConnectionAssistant(Gtk.Box):
)
"""Errors"""
if len(prereqs.invalid_mods) > 0:
pairs = [": ".join(sub) for sub in prereqs.invalid_mods]
lines = "\n".join(pairs)
msg = (
"Server has invalid mods that are not recognized by Steam.\n"
"Contact the server owner and include these mod IDs in your report:\n"
f"{lines}"
)
errors.append(msg)
if prereqs.binary_missing:
errors.append(
f"Remote server is running the build '{prereqs.build}', but it is not installed.\n{resync_msg}"
@ -275,10 +284,10 @@ class PreConnectionAssistant(Gtk.Box):
allows_dl, running_app = prereqs.allows_downloads
if len(prereqs.mods) > 0 and allows_dl is False:
msg = (
f"The game '{running_app}' is currently running in Steam, but background downloads are not enabled.\n"
f"The app '{running_app}' is currently running in Steam, but background downloads are not enabled.\n"
"Either stop the game first, or update your global Steam settings or the game's local settings.\n"
"Otherwise, mods may be queued for download but never update."
)
)
warnings.append(msg)
self.add_warnings(warnings)

View File

@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
authors = [
{name = "aclist"}
]
version = "7.0.0b20"
version = "7.0.0b21"
license = "GPL-3.0-or-later"
license-files = ["LICENSE"]
readme = "README.md"