From 68fc88b3f49f2bdc8290cac63771b14c7cd03a93 Mon Sep 17 00:00:00 2001 From: Loren Eteval Date: Fri, 21 Aug 2026 16:05:33 +0800 Subject: [PATCH] Refine Hysteria2 editor field layout Signed-off-by: Loren Eteval --- Furious/Backends/Hysteria2/Editor.py | 7 +++-- tests/test_hysteria2_compatibility.py | 41 ++++++++++++++++++--------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Furious/Backends/Hysteria2/Editor.py b/Furious/Backends/Hysteria2/Editor.py index 8a41a06..cddae5e 100644 --- a/Furious/Backends/Hysteria2/Editor.py +++ b/Furious/Backends/Hysteria2/Editor.py @@ -241,6 +241,8 @@ class GuiHy2FormBindings(EditorWidgetBinding): def __init__(self, *bindings: EditorWidgetBinding, **kwargs): """Create one persistent form containing the supplied bindings.""" + topMargin = kwargs.pop('topMargin', 0) + super().__init__(**kwargs) self.bindings = tuple(bindings) @@ -252,7 +254,7 @@ class GuiHy2FormBindings(EditorWidgetBinding): ) layout = QFormLayout(self._widget) - layout.setContentsMargins(0, 0, 0, 0) + layout.setContentsMargins(0, topMargin, 0, 0) layout.setFormAlignment(QtCore.Qt.AlignmentFlag.AlignLeft) layout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow) @@ -859,6 +861,7 @@ class GuiHy2GroupBoxProxyBandwidth(GuiEditorWidgetQGroupBox): path=('bandwidth', 'down'), translatable=False, ), + topMargin=20, ), GuiHy2NestedSwitch( title='bandwidth.disableLossCompensation', @@ -1042,7 +1045,7 @@ class GuiHy2GroupBoxAdvanced(GuiEditorWidgetQGroupBox): self.chromeParrotItem, self.mimicEnabledItem = ( GuiHy2NestedSwitch( - title='disableChromeParrot', + title='quic.disableChromeParrot', path=('quic', 'disableChromeParrot'), translatable=False, ), diff --git a/tests/test_hysteria2_compatibility.py b/tests/test_hysteria2_compatibility.py index 7464e96..41091c8 100644 --- a/tests/test_hysteria2_compatibility.py +++ b/tests/test_hysteria2_compatibility.py @@ -217,7 +217,11 @@ class Hysteria2CompatibilityTest(unittest.TestCase): ) self.assertEqual( tuple(binding._title.text() for binding in advanced.toggleRow.bindings), - ('disableChromeParrot', 'mimic.enabled'), + ('quic.disableChromeParrot', 'mimic.enabled'), + ) + self.assertEqual( + proxyBandwidth.bandwidthFields._widget.layout().contentsMargins().top(), + 20, ) editor.show() @@ -418,7 +422,7 @@ class Hysteria2CompatibilityTest(unittest.TestCase): 'bandwidth', 'disableLossCompensation', ): 'bandwidth.disableLossCompensation', - ('quic', 'disableChromeParrot'): 'disableChromeParrot', + ('quic', 'disableChromeParrot'): 'quic.disableChromeParrot', ('realm', 'ipMode'): 'ipMode', ('mimic', 'enabled'): 'mimic.enabled', } @@ -482,8 +486,8 @@ class Hysteria2CompatibilityTest(unittest.TestCase): editor.close() - def testUnknownCompactEditorValuesRoundTripUntouched(self): - """Display and preserve future enum and tagged-union values verbatim.""" + def testUnknownCompactEditorValuesNormalizeToKnownDefaults(self): + """Normalize unsupported represented values while preserving other data.""" profile = self.profile( { 'server': 'example.com:443', @@ -514,29 +518,40 @@ class Hysteria2CompatibilityTest(unittest.TestCase): self.assertEqual(profile.connection, original) self.assertEqual( self.binding(editor, ('realm', 'ipMode')).text(), - 'future-mode', + 'dual', ) self.assertEqual( editor.basicGroup._containers[3].bindings[0].text(), - 'future-congestion', + '', ) self.assertEqual( editor.basicGroup._containers[3].bindings[1].text(), - 'future-profile', + '', ) self.assertEqual( editor.advancedGroup.obfsItem.page( editor.advancedGroup.obfsItem.currentIndex() ).obfsTypeText(), - 'future-obfs', + '', ) - self.assertFalse(editor.inputToFactory(profile)) - self.assertEqual(profile.connection, original) + self.assertTrue(editor.inputToFactory(profile)) + self.assertEqual( + profile.connection['realm'], + { + 'ipMode': 'dual', + 'futureRealmField': {'preserve': True}, + }, + ) + self.assertEqual( + profile.connection['congestion'], + {'futureCongestionField': 7}, + ) + self.assertNotIn('obfs', profile.connection) editor.close() - def testClearingCongestionFieldPreservesUnknownSiblings(self): - """Remove only the represented congestion leaf when clearing it.""" + def testSavingCongestionNormalizesUnknownRepresentedSiblings(self): + """Clear unsupported represented values while preserving JSON-only data.""" profile = self.profile( { 'server': 'example.com:443', @@ -555,7 +570,7 @@ class Hysteria2CompatibilityTest(unittest.TestCase): self.assertTrue(editor.inputToFactory(profile)) self.assertNotIn('type', profile.connection['congestion']) - self.assertEqual(profile.connection['congestion']['bbrProfile'], 'fast') + self.assertNotIn('bbrProfile', profile.connection['congestion']) self.assertEqual( profile.connection['congestion']['futureCongestionField'], {'preserve': True},