From e0d62a9e54e29b08ebc45ce96903ae3747d64c20 Mon Sep 17 00:00:00 2001 From: ChuckBuilds Date: Fri, 7 Aug 2026 16:05:28 -0400 Subject: [PATCH] fix(vegas): stop capping plugin width by default Vegas plugins read as "cut off early" or "starting in the middle". That was the per-plugin width budget, not the scroll engine: overflow_mode=rotate is designed to resume mid-content on each appearance, so the symptom was the feature working as specified. Measured over a 17-plugin fleet on a 512px panel, the cap was a bad trade. Only four plugins were ever wide enough to hit the 3.0 default -- leaderboard 11,518px, news 10,021px, odds-ticker 4,643px, hockey 1,508px. Weather is 650px and flights 512px; the cap never touched them or the other eleven. So it bought nothing on thirteen plugins while costing two visible faults on four: content entering mid-item (a news ticker started at column 6027 of its own strip), and a final rotation window of whatever happened to be left -- 348px of an 1,840px stocks ticker, seven seconds of panel time. Default max_plugin_width_ratio to 0 (uncapped), so every plugin contributes all of its content and is always entered at its beginning. The cap remains available, and vegas_max_width_screens still caps an individual plugin -- which is where the knob belongs, since a genuinely long ticker is a property of that plugin rather than of the fleet. Verified on a live 512px device: 327 budget crops in the preceding six hours, none after. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5 --- config/config.template.json | 2 +- docs/CONFIG_REFERENCE.md | 2 +- src/vegas_mode/config.py | 22 ++++++++++++++----- test/test_vegas_density.py | 6 +++++ .../templates/v3/partials/display.html | 4 ++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/config/config.template.json b/config/config.template.json index 433039f7..9edbec18 100644 --- a/config/config.template.json +++ b/config/config.template.json @@ -149,7 +149,7 @@ "min_plugin_width": 8, "lead_in_width": 0, "plugins_per_cycle": 6, - "max_plugin_width_ratio": 3.0, + "max_plugin_width_ratio": 0.0, "overflow_mode": "rotate", "dynamic_duration_enabled": true, "min_cycle_duration": 60, diff --git a/docs/CONFIG_REFERENCE.md b/docs/CONFIG_REFERENCE.md index a7bd81df..ff623439 100644 --- a/docs/CONFIG_REFERENCE.md +++ b/docs/CONFIG_REFERENCE.md @@ -127,7 +127,7 @@ Read by `src/vegas_mode/config.py` (`VegasScrollConfig.from_config`). See | `min_plugin_width` | int, `8` | | `lead_in_width` | int, `0` | | `plugins_per_cycle` | int, `6` | -| `max_plugin_width_ratio` | float, `3.0` | +| `max_plugin_width_ratio` | float, `0.0` | | `overflow_mode` | string, `"rotate"` | | `dynamic_duration_enabled` | bool, `true` | | `min_cycle_duration` | int, `60` | diff --git a/src/vegas_mode/config.py b/src/vegas_mode/config.py index 14786481..551da4d8 100644 --- a/src/vegas_mode/config.py +++ b/src/vegas_mode/config.py @@ -104,10 +104,22 @@ class VegasModeConfig: overflow_mode: str = "rotate" # Cap on one plugin's share of a cycle, as a multiple of display width. - # A single ticker returning 7,000px would otherwise hold the panel for over - # two minutes. Overflow is deferred to later cycles rather than discarded. - # 0 disables the cap. - max_plugin_width_ratio: float = 3.0 + # 0 (the default) disables the cap, so every plugin contributes all of its + # content and is always entered at its beginning. + # + # Capping was the default until it proved to cost more than it bought. + # Measured over a 17-plugin fleet on a 512px panel, only four plugins were + # ever wide enough to hit a 3.0 cap; for those four it produced two visible + # faults. Content resumed mid-item on each appearance (a news ticker entered + # at column 6027 of its own strip), and the final window of a rotation was + # whatever happened to be left — 348px of a 1840px stocks ticker, seven + # seconds of panel time. Both read as the display being broken rather than + # as deferral working. + # + # A wide plugin does hold the panel for a long time uncapped: set the cap + # per plugin with vegas_max_width_screens where that matters, rather than + # globally where it mostly hurts plugins that were never the problem. + max_plugin_width_ratio: float = 0.0 # Plugin management plugin_order: List[str] = field(default_factory=list) @@ -159,7 +171,7 @@ class VegasModeConfig: lead_in_width=int(vegas_config.get('lead_in_width', 0)), plugins_per_cycle=int(vegas_config.get('plugins_per_cycle', 6)), max_plugin_width_ratio=float( - vegas_config.get('max_plugin_width_ratio', 3.0)), + vegas_config.get('max_plugin_width_ratio', 0.0)), overflow_mode=str(vegas_config.get('overflow_mode', 'rotate')), plugin_order=list(vegas_config.get('plugin_order', [])), excluded_plugins=set(vegas_config.get('excluded_plugins', [])), diff --git a/test/test_vegas_density.py b/test/test_vegas_density.py index f0c1fd72..a5cde000 100644 --- a/test/test_vegas_density.py +++ b/test/test_vegas_density.py @@ -781,6 +781,12 @@ class TestNewConfigKeys: assert cfg.render_width_pct == 100 assert cfg.min_content_separation == 24 + def test_width_cap_is_off_by_default(self): + # Capping made wide plugins resume mid-content on every appearance and + # emit runt final windows; it is now opt-in per plugin instead. + assert VegasModeConfig().max_plugin_width_ratio == 0.0 + assert VegasModeConfig.from_config({}).max_plugin_width_ratio == 0.0 + @pytest.mark.parametrize('overrides,bad_key', [ ({'render_width_pct': 5}, 'render_width_pct'), ({'render_width_pct': 101}, 'render_width_pct'), diff --git a/web_interface/templates/v3/partials/display.html b/web_interface/templates/v3/partials/display.html index 2fa31027..1e2c423a 100644 --- a/web_interface/templates/v3/partials/display.html +++ b/web_interface/templates/v3/partials/display.html @@ -556,11 +556,11 @@
- +