mirror of
https://github.com/aclist/dztui.git
synced 2026-10-30 22:52:42 +01:00
feat: raise window (WIP)
This commit is contained in:
1 parent
90a1740bf0
commit
2b10fcaaad
10 files changed
+95
-46
No files matched your search
+4
-1
@@ -49,7 +49,6 @@ def get_local_mods(workshop_path: Path) -> list[Path]:
|
|||||||
return mods
|
return mods
|
||||||
|
|
||||||
|
|
||||||
# TODO: TEST: mock bad meta files with fixtures and skip them
|
|
||||||
def parse_meta(file: Path) -> ModMeta:
|
def parse_meta(file: Path) -> ModMeta:
|
||||||
mod = file / "meta.cpp"
|
mod = file / "meta.cpp"
|
||||||
if mod.exists() is False:
|
if mod.exists() is False:
|
||||||
@@ -163,6 +162,10 @@ def find_stale_mods(config: Path) -> list[int]:
|
|||||||
|
|
||||||
|
|
||||||
def get_mod_dir_size(path: Path) -> int:
|
def get_mod_dir_size(path: Path) -> int:
|
||||||
|
"""
|
||||||
|
This is not a guarantee of parity, as user may adjusted contents of local mods,
|
||||||
|
so upstream epoch time is still used
|
||||||
|
"""
|
||||||
size = 0
|
size = 0
|
||||||
for i in Path(path).iterdir():
|
for i in Path(path).iterdir():
|
||||||
if i.is_file():
|
if i.is_file():
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ def query_direct(ip: str, qport: int, timeout: float = 3.0) -> dict[str, Any] |
|
|||||||
info = a2s.info((ip, qport), timeout)
|
info = a2s.info((ip, qport), timeout)
|
||||||
return source_info_to_dict(ip, qport, info)
|
return source_info_to_dict(ip, qport, info)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.critical(e)
|
logger.warning(e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from dzgui.config.xdg import Xdg
|
from typing import TYPE_CHECKING, Union
|
||||||
from dzgui.util.ip import Coords
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from dzgui.config.xdg import Xdg
|
||||||
|
from dzgui.util.ip import Coords
|
||||||
|
|
||||||
|
|
||||||
# NOTE: mutable dataclass, 'use_miles' key changes on demand
|
# NOTE: mutable dataclass, 'use_miles' key changes on demand
|
||||||
@@ -9,8 +12,9 @@ class UserPrefs:
|
|||||||
is_steam_deck: bool
|
is_steam_deck: bool
|
||||||
is_game_mode: bool
|
is_game_mode: bool
|
||||||
is_debug: bool
|
is_debug: bool
|
||||||
coords: Coords | None
|
coords: Union["Coords", None]
|
||||||
version: str
|
version: str
|
||||||
allow_updates: bool
|
allow_updates: bool
|
||||||
paths: Xdg
|
paths: "Xdg"
|
||||||
use_miles: bool
|
use_miles: bool
|
||||||
|
foreground_cmd: str | None
|
||||||
@@ -65,3 +65,4 @@ CHANGELOG_PATH = "data/CHANGELOG.md"
|
|||||||
CSS_PATH = "data/app.css"
|
CSS_PATH = "data/app.css"
|
||||||
|
|
||||||
LOG_FILTERS = ("CRITICAL", "WARNING", "INFO", "DEBUG")
|
LOG_FILTERS = ("CRITICAL", "WARNING", "INFO", "DEBUG")
|
||||||
|
FOREGROUND_CMDS = ("wmctrlu", "xdotool")
|
||||||
@@ -470,8 +470,8 @@ class Controller(GObject.GObject):
|
|||||||
ind = self.config_man.get_start_tab()
|
ind = self.config_man.get_start_tab()
|
||||||
self.get_servers().notebook.set_current_page(ind)
|
self.get_servers().notebook.set_current_page(ind)
|
||||||
|
|
||||||
def update_and_connect(self) -> None:
|
def update_and_connect(self, raise_window: bool) -> None:
|
||||||
self.connection_man.update_and_connect()
|
self.connection_man.update_and_connect(raise_window)
|
||||||
|
|
||||||
def update_status(self, mod: str, mark_finished: bool = False) -> None:
|
def update_status(self, mod: str, mark_finished: bool = False) -> None:
|
||||||
self.mediator.preconnect.update_mod(mod, mark_finished)
|
self.mediator.preconnect.update_mod(mod, mark_finished)
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
import psutil
|
import psutil
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from dzgui.const.constants import DAYZ_BINARY, STEAM_CMD
|
from dzgui.const.constants import DAYZ_BINARY, STEAM_CMD
|
||||||
from dzgui.views.dialogs.early_alert import EarlyAlertDialog
|
from dzgui.views.dialogs.early_alert import EarlyAlertDialog
|
||||||
from dzgui.util.strings import init
|
from dzgui.util.strings import init
|
||||||
|
|
||||||
|
# TODO: move to util.proc
|
||||||
|
|
||||||
|
|
||||||
# TODO: simplify
|
# TODO: simplify
|
||||||
def is_dayz_running(dialog: bool = False) -> bool | None:
|
def is_dayz_running(dialog: bool = False) -> bool | None:
|
||||||
@@ -29,3 +33,18 @@ def is_running(proc: str) -> bool:
|
|||||||
if process.info["name"] == proc:
|
if process.info["name"] == proc:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def has_cmd(cmd: str) -> bool:
|
||||||
|
if shutil.which(cmd) is not None:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def foreground(cmd: str, pid: int) -> None:
|
||||||
|
if cmd == "wmctrl":
|
||||||
|
# TODO: convert wid from hexadecimal
|
||||||
|
args = [cmd, "-a", "DZGUI"]
|
||||||
|
elif cmd == "xdotool":
|
||||||
|
args = [cmd, "search", "--onlyvisible", "--name", "DZGUI", "windowactivate"]
|
||||||
|
subprocess.Popen([*args])
|
||||||
+24
-10
@@ -7,7 +7,7 @@ import warnings
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from dzgui.api.mods import remove_stale_signatures
|
from dzgui.api.mods import remove_stale_signatures
|
||||||
from dzgui.const.constants import APP_NAME
|
from dzgui.const.constants import APP_NAME, FOREGROUND_CMDS
|
||||||
from dzgui.const.enum import Preferences
|
from dzgui.const.enum import Preferences
|
||||||
from dzgui.config.ipdb import get_ipdb
|
from dzgui.config.ipdb import get_ipdb
|
||||||
from dzgui.config.query import lookup
|
from dzgui.config.query import lookup
|
||||||
@@ -25,7 +25,7 @@ from dzgui.init.migrate import (
|
|||||||
)
|
)
|
||||||
from dzgui.init.prefix import get_version
|
from dzgui.init.prefix import get_version
|
||||||
from dzgui.init.prereqs import has_steam_client
|
from dzgui.init.prereqs import has_steam_client
|
||||||
from dzgui.init.proc import is_dayz_running, is_steam_running
|
from dzgui.init.proc import has_cmd, is_dayz_running, is_steam_running
|
||||||
from dzgui.init.update import allow_updates, check_updates
|
from dzgui.init.update import allow_updates, check_updates
|
||||||
|
|
||||||
from dzgui.util.map_count import get_map_count
|
from dzgui.util.map_count import get_map_count
|
||||||
@@ -142,15 +142,29 @@ def main() -> None:
|
|||||||
local_coords = get_local_coords(XDG.ips)
|
local_coords = get_local_coords(XDG.ips)
|
||||||
use_miles = lookup(XDG.config, Preferences.DIST)
|
use_miles = lookup(XDG.config, Preferences.DIST)
|
||||||
|
|
||||||
|
tool = None
|
||||||
|
for cmd in FOREGROUND_CMDS:
|
||||||
|
if has_cmd(cmd) is True:
|
||||||
|
tool = cmd
|
||||||
|
break
|
||||||
|
|
||||||
|
print(os.getpid())
|
||||||
|
# TODO: try getting pid on demand later
|
||||||
|
# pid = os.getpid()
|
||||||
|
|
||||||
|
# TODO: push is_game_mode to preconnect dialog
|
||||||
prefs = UserPrefs(
|
prefs = UserPrefs(
|
||||||
_is_steam_deck,
|
is_steam_deck=_is_steam_deck,
|
||||||
_is_game_mode,
|
is_game_mode=_is_game_mode,
|
||||||
args.debug,
|
is_debug=args.debug,
|
||||||
local_coords,
|
coords=local_coords,
|
||||||
version,
|
version=version,
|
||||||
allow,
|
allow_updates=allow,
|
||||||
XDG,
|
paths=XDG,
|
||||||
use_miles,
|
use_miles=use_miles,
|
||||||
|
foreground_cmd=tool,
|
||||||
)
|
)
|
||||||
|
# TODO: drop allow updates
|
||||||
|
# TODO: strings
|
||||||
print("All OK. Loading UI...")
|
print("All OK. Loading UI...")
|
||||||
App(prefs)
|
App(prefs)
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ from dzgui.const.constants import (
|
|||||||
APPNAME_DAYZ_EXP,
|
APPNAME_DAYZ_EXP,
|
||||||
)
|
)
|
||||||
from dzgui.const.enum import Preferences
|
from dzgui.const.enum import Preferences
|
||||||
from dzgui.init.proc import is_dayz_running, is_steam_running
|
from dzgui.init.proc import foreground, is_dayz_running, is_steam_running
|
||||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||||
from dzgui.util.format import format_mib
|
from dzgui.util.format import format_mib
|
||||||
from dzgui.util.strings import dialog, server_timeout, checkmark
|
from dzgui.util.strings import dialog, server_timeout, checkmark
|
||||||
@@ -60,6 +61,7 @@ class Prerequisites:
|
|||||||
dayz_running: bool
|
dayz_running: bool
|
||||||
steam_running: bool
|
steam_running: bool
|
||||||
mods: list[str]
|
mods: list[str]
|
||||||
|
foreground_cmd: str | None
|
||||||
|
|
||||||
|
|
||||||
class ConnectionManager:
|
class ConnectionManager:
|
||||||
@@ -141,6 +143,8 @@ class ConnectionManager:
|
|||||||
dayz_running = is_dayz_running()
|
dayz_running = is_dayz_running()
|
||||||
steam_running = is_steam_running()
|
steam_running = is_steam_running()
|
||||||
|
|
||||||
|
self.foreground_cmd = self.controller.get_prefs().foreground_cmd
|
||||||
|
|
||||||
prereqs = Prerequisites(
|
prereqs = Prerequisites(
|
||||||
name=info.server_name,
|
name=info.server_name,
|
||||||
appid=info.game_id,
|
appid=info.game_id,
|
||||||
@@ -154,6 +158,7 @@ class ConnectionManager:
|
|||||||
dayz_running=dayz_running,
|
dayz_running=dayz_running,
|
||||||
steam_running=steam_running,
|
steam_running=steam_running,
|
||||||
mods=remote_mods,
|
mods=remote_mods,
|
||||||
|
foreground_cmd=self.foreground_cmd, # TODO: change to bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func = StoredFunc(self.controller.open_connection_assistant, prereqs)
|
func = StoredFunc(self.controller.open_connection_assistant, prereqs)
|
||||||
@@ -227,7 +232,7 @@ class ConnectionManager:
|
|||||||
# TODO: add to history file and list store
|
# TODO: add to history file and list store
|
||||||
|
|
||||||
@call_on_thread("Waiting for Steam to update mods")
|
@call_on_thread("Waiting for Steam to update mods")
|
||||||
def update_mods(self) -> None:
|
def update_mods(self, raise_window: bool) -> None:
|
||||||
# NOTE: fast enqueue all mods in auto mode
|
# NOTE: fast enqueue all mods in auto mode
|
||||||
for title, mod, stamp, size in self.missing_mods:
|
for title, mod, stamp, size in self.missing_mods:
|
||||||
# TODO: boolean cancel button on threadman dialog sets event inside threadman
|
# TODO: boolean cancel button on threadman dialog sets event inside threadman
|
||||||
@@ -235,6 +240,10 @@ class ConnectionManager:
|
|||||||
enqueue_mod(mod, self.appid)
|
enqueue_mod(mod, self.appid)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
|
if self.foreground_cmd is not None and raise_window is True:
|
||||||
|
pid = os.getpid()
|
||||||
|
foreground(self.foreground_cmd, pid)
|
||||||
|
|
||||||
for title, mod, stamp, size in self.missing_mods:
|
for title, mod, stamp, size in self.missing_mods:
|
||||||
mod_path = self.workshop / mod
|
mod_path = self.workshop / mod
|
||||||
|
|
||||||
@@ -258,8 +267,8 @@ class ConnectionManager:
|
|||||||
)
|
)
|
||||||
self.thread_man.set_cleanup_func(func)
|
self.thread_man.set_cleanup_func(func)
|
||||||
|
|
||||||
def update_and_connect(self) -> None:
|
def update_and_connect(self, raise_window: bool) -> None:
|
||||||
if len(self.missing_mods) > 0:
|
if len(self.missing_mods) > 0:
|
||||||
self.update_mods()
|
self.update_mods(raise_window)
|
||||||
else:
|
else:
|
||||||
self.connect_steam()
|
self.connect_steam()
|
||||||
@@ -43,7 +43,7 @@ class NoteDialog(GenericDialog):
|
|||||||
self.entry.set_text(note)
|
self.entry.set_text(note)
|
||||||
if len(note) > 0:
|
if len(note) > 0:
|
||||||
delete_button.set_sensitive(True)
|
delete_button.set_sensitive(True)
|
||||||
self.format_secondary_text(f"Current note: {note}")
|
self.format_secondary_text(f"Current note: '{note}'")
|
||||||
elif len(note) == 0:
|
elif len(note) == 0:
|
||||||
self.ok.set_sensitive(False)
|
self.ok.set_sensitive(False)
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
has_tooltip=True,
|
has_tooltip=True,
|
||||||
sensitive=False,
|
sensitive=False,
|
||||||
tooltip_text="This option is available if wmctrl or xdotool is installed on the system",
|
tooltip_text="This option is available if wmctrl or xdotool is installed on the system",
|
||||||
|
active=True,
|
||||||
)
|
)
|
||||||
self.button_box = Gtk.Box(
|
self.button_box = Gtk.Box(
|
||||||
orientation=Gtk.Orientation.VERTICAL,
|
orientation=Gtk.Orientation.VERTICAL,
|
||||||
@@ -142,20 +143,18 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
margin_top=10,
|
margin_top=10,
|
||||||
margin_bottom=10,
|
margin_bottom=10,
|
||||||
)
|
)
|
||||||
self.spinner = Gtk.Spinner()
|
|
||||||
self.progress_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=15)
|
self.progress_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=15)
|
||||||
self.progress_box.add(self.mod_count)
|
self.progress_box.add(self.mod_count)
|
||||||
self.progress_box.add(self.spinner)
|
# self.cancel = Gtk.Button(
|
||||||
self.cancel = Gtk.Button(
|
# label=preconnect.cancel,
|
||||||
label=preconnect.cancel,
|
# halign=Gtk.Align.START,
|
||||||
halign=Gtk.Align.START,
|
# hexpand=True,
|
||||||
hexpand=True,
|
# margin_bottom=5,
|
||||||
margin_bottom=5,
|
# margin_top=5,
|
||||||
margin_top=5,
|
# )
|
||||||
)
|
# self.progress_box.add(self.cancel)
|
||||||
self.progress_box.add(self.cancel)
|
# self.cancel.connect("clicked", self._on_cancel_clicked)
|
||||||
self.cancel.connect("clicked", self._on_cancel_clicked)
|
# self.cancel.set_visible(False)
|
||||||
self.cancel.set_visible(False)
|
|
||||||
|
|
||||||
# TODO: live count of remaining downloads
|
# TODO: live count of remaining downloads
|
||||||
# "Steam is downloading: {mod_name}"
|
# "Steam is downloading: {mod_name}"
|
||||||
@@ -219,8 +218,7 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
# TODO: enable button if wmctrl or xdotool is available
|
# TODO: enable button if wmctrl or xdotool is available
|
||||||
# TODO: check this at boot time and pass in via connection manager
|
# TODO: check this at boot time and pass in via connection manager
|
||||||
|
self.raise_window.set_sensitive(False)
|
||||||
self.cancel.set_visible(False)
|
|
||||||
self.ok.set_sensitive(True)
|
self.ok.set_sensitive(True)
|
||||||
self.ok.set_label(preconnect.update_mods)
|
self.ok.set_label(preconnect.update_mods)
|
||||||
|
|
||||||
@@ -228,8 +226,8 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
if event.keyval == Gdk.KEY_Escape:
|
if event.keyval == Gdk.KEY_Escape:
|
||||||
self.back.emit("clicked")
|
self.back.emit("clicked")
|
||||||
|
|
||||||
def _on_cancel_clicked(self, button: Gtk.Button) -> None:
|
# def _on_cancel_clicked(self, button: Gtk.Button) -> None:
|
||||||
print("user canceled")
|
# print("user canceled")
|
||||||
|
|
||||||
def _on_ok_clicked(self, button: Gtk.Button) -> None:
|
def _on_ok_clicked(self, button: Gtk.Button) -> None:
|
||||||
# TODO: cancel mod downloads
|
# TODO: cancel mod downloads
|
||||||
@@ -237,11 +235,10 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
if self.mod_count.get_visible():
|
if self.mod_count.get_visible():
|
||||||
# TODO: set ready mode
|
# TODO: set ready mode
|
||||||
# TODO: strings
|
# TODO: strings
|
||||||
self.mod_count.set_label("Enqueuing downloads")
|
# self.mod_count.set_label("Enqueuing downloads")
|
||||||
self.spinner.start()
|
# self.cancel.set_visible(True)
|
||||||
self.cancel.set_visible(True)
|
|
||||||
self.ok.set_label(preconnect.connect)
|
self.ok.set_label(preconnect.connect)
|
||||||
self.controller.update_and_connect()
|
self.controller.update_and_connect(self.raise_window.get_active())
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _on_back_clicked(self, button: Gtk.Button) -> None:
|
def _on_back_clicked(self, button: Gtk.Button) -> None:
|
||||||
@@ -295,6 +292,9 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
name = prereqs.name
|
name = prereqs.name
|
||||||
self.title.set_text(name)
|
self.title.set_text(name)
|
||||||
|
|
||||||
|
if prereqs.foreground_cmd is not None:
|
||||||
|
self.raise_window.set_sensitive(True)
|
||||||
|
|
||||||
if total_mods < 1:
|
if total_mods < 1:
|
||||||
self.scrolled.set_visible(False)
|
self.scrolled.set_visible(False)
|
||||||
self.progress_box.set_visible(False)
|
self.progress_box.set_visible(False)
|
||||||
@@ -318,9 +318,8 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
def update_mod(self, text: str, mark_finished: bool = False) -> None:
|
def update_mod(self, text: str, mark_finished: bool = False) -> None:
|
||||||
self.mod_count.set_label(text)
|
self.mod_count.set_label(text)
|
||||||
if mark_finished:
|
# if mark_finished:
|
||||||
self.cancel.set_visible(False)
|
# self.cancel.set_visible(False)
|
||||||
self.spinner.stop()
|
|
||||||
|
|
||||||
def add_errors(self, errors: list[str]) -> None:
|
def add_errors(self, errors: list[str]) -> None:
|
||||||
self.error_tree.extend(errors)
|
self.error_tree.extend(errors)
|
||||||
|
|||||||
Reference in new issue
Block a user