mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-10-14 19:27:09 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39b0b32198 |
No files matched your search
@@ -1,5 +1,10 @@
|
||||
#!/usr/bin/python3
|
||||
"""Initialize Steam's own Gamescope UI scale once; subsequent choices belong to Steam."""
|
||||
"""Initialize Steam's own Gamescope display settings once; subsequent choices belong to Steam.
|
||||
|
||||
The UI scale, and native resolution: the client treats our gamescope as an external display and,
|
||||
unless "Enable Native Resolution on External Displays" is on, draws itself at 1920x1080 on any
|
||||
larger output - a 2340x1080 session came up as 16:9 with bars. The session's size is already the
|
||||
user's Resolution choice, so the client should use all of it."""
|
||||
import math
|
||||
import os
|
||||
from pathlib import Path
|
||||
@@ -9,6 +14,7 @@ import tempfile
|
||||
|
||||
|
||||
DISPLAY = "External: gamescope|||Windowed"
|
||||
NATIVE_RESOLUTION = "EnableSteamNativeExternalResolution"
|
||||
TOKEN = re.compile(r'\s+|//[^\n]*|"(?:\\.|[^"\\])*"|[{}]')
|
||||
|
||||
|
||||
@@ -102,6 +108,25 @@ def seed_text(text, scale):
|
||||
return text[:at] + insertion + text[at:], True
|
||||
|
||||
|
||||
def seed_native_resolution(text):
|
||||
root = parse(text).get('InstallConfigStore')
|
||||
if not isinstance(root, Block):
|
||||
raise ValueError("missing InstallConfigStore")
|
||||
gamescope = root.get('Gamescope')
|
||||
if gamescope is not None and not isinstance(gamescope, Block):
|
||||
raise ValueError("invalid Gamescope settings")
|
||||
if gamescope is not None and gamescope.get(NATIVE_RESOLUTION) is not None:
|
||||
return text, False
|
||||
entry = f'"{NATIVE_RESOLUTION}" "1"'
|
||||
if gamescope is not None:
|
||||
at, indent = gamescope.end, 2
|
||||
else:
|
||||
entry = '"Gamescope"\n{\n' + entry + '\n}'
|
||||
at, indent = root.end, 1
|
||||
insertion = '\n' + '\n'.join('\t' * indent + line for line in entry.splitlines()) + '\n'
|
||||
return text[:at] + insertion + text[at:], True
|
||||
|
||||
|
||||
def atomic_write(path, text):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
fd, temporary = tempfile.mkstemp(prefix='.' + path.name, dir=path.parent)
|
||||
@@ -128,9 +153,30 @@ def initialize(steam_root, width, height):
|
||||
return changed
|
||||
|
||||
|
||||
def initialize_native_resolution(steam_root):
|
||||
config = Path(steam_root) / 'config/config.vdf'
|
||||
marker = config.with_name('droiddeck-native-resolution-initialized')
|
||||
if marker.exists():
|
||||
return False
|
||||
text = config.read_text() if config.exists() else '"InstallConfigStore"\n{\n}\n'
|
||||
updated, changed = seed_native_resolution(text)
|
||||
if changed:
|
||||
atomic_write(config, updated)
|
||||
print('== steam: native resolution on the session display')
|
||||
atomic_write(marker, '1\n')
|
||||
return changed
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
status = 0
|
||||
try:
|
||||
initialize(sys.argv[1], int(sys.argv[2]), int(sys.argv[3]))
|
||||
except (OSError, ValueError, RecursionError) as error:
|
||||
print('== steam: left UI scale unchanged: ' + str(error), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
status = 1
|
||||
try:
|
||||
initialize_native_resolution(sys.argv[1])
|
||||
except (OSError, ValueError, RecursionError) as error:
|
||||
print('== steam: left native resolution unchanged: ' + str(error), file=sys.stderr)
|
||||
status = 1
|
||||
sys.exit(status)
|
||||
@@ -11,6 +11,9 @@ seed_text = MODULE['seed_text']
|
||||
parse = MODULE['parse']
|
||||
initial_scale = MODULE['initial_scale']
|
||||
DISPLAY = MODULE['DISPLAY']
|
||||
seed_native_resolution = MODULE['seed_native_resolution']
|
||||
initialize_native_resolution = MODULE['initialize_native_resolution']
|
||||
NATIVE_RESOLUTION = MODULE['NATIVE_RESOLUTION']
|
||||
|
||||
|
||||
class SteamUiScaleTest(unittest.TestCase):
|
||||
@@ -96,3 +99,55 @@ class SteamUiScaleTest(unittest.TestCase):
|
||||
initialize(self.root, 0, 720)
|
||||
self.assertFalse(self.config.exists())
|
||||
self.assertFalse(self.marker.exists())
|
||||
|
||||
|
||||
class SteamNativeResolutionTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.temp.cleanup)
|
||||
self.root = Path(self.temp.name)
|
||||
self.config = self.root / 'config/config.vdf'
|
||||
self.config.parent.mkdir()
|
||||
self.marker = self.config.with_name('droiddeck-native-resolution-initialized')
|
||||
|
||||
def native(self, text):
|
||||
return parse(text).get('InstallConfigStore').get('Gamescope').get(NATIVE_RESOLUTION)
|
||||
|
||||
def test_fresh_client_renders_at_the_session_size(self):
|
||||
self.assertTrue(initialize_native_resolution(self.root))
|
||||
self.assertEqual('1', self.native(self.config.read_text()))
|
||||
self.assertTrue(self.marker.exists())
|
||||
|
||||
def test_existing_client_gets_it_once_beside_its_settings(self):
|
||||
text = '"InstallConfigStore"\n{\n\t"Gamescope"\n\t{\n\t\t"HDREnabled"\t\t"1"\n\t}\n}\n'
|
||||
self.config.write_text(text)
|
||||
self.assertTrue(initialize_native_resolution(self.root))
|
||||
updated = self.config.read_text()
|
||||
self.assertEqual('1', self.native(updated))
|
||||
self.assertEqual('1', parse(updated).get('InstallConfigStore').get('Gamescope').get('HDREnabled'))
|
||||
|
||||
def test_users_choice_is_kept(self):
|
||||
text = f'"InstallConfigStore" {{ "Gamescope" {{ "{NATIVE_RESOLUTION}" "0" }} }}'
|
||||
self.assertEqual((text, False), seed_native_resolution(text))
|
||||
|
||||
def test_turning_it_off_after_initialization_survives_restart(self):
|
||||
initialize_native_resolution(self.root)
|
||||
text = self.config.read_text().replace('"1"', '"0"')
|
||||
self.config.write_text(text)
|
||||
self.assertFalse(initialize_native_resolution(self.root))
|
||||
self.assertEqual(text, self.config.read_text())
|
||||
|
||||
def test_ui_scale_and_native_resolution_seed_the_same_config(self):
|
||||
initialize(self.root, 2340, 1080)
|
||||
initialize_native_resolution(self.root)
|
||||
text = self.config.read_text()
|
||||
self.assertEqual('1', self.native(text))
|
||||
self.assertIsNotNone(parse(text).get('InstallConfigStore').get('UI').get('display').get(DISPLAY))
|
||||
|
||||
def test_invalid_config_is_never_rewritten_or_marked_initialized(self):
|
||||
for text in ('"InstallConfigStore" {', '"InstallConfigStore" { "Gamescope" "bad" }'):
|
||||
self.config.write_text(text)
|
||||
with self.assertRaises(ValueError):
|
||||
initialize_native_resolution(self.root)
|
||||
self.assertEqual(text, self.config.read_text())
|
||||
self.assertFalse(self.marker.exists())
|
||||
Reference in new issue
Block a user