Skip to content

streamcontroller cleanup pass#588

Draft
Core447 wants to merge 20 commits into
mainfrom
cursor/streamcontroller-cleanup-pass-5fdc
Draft

streamcontroller cleanup pass#588
Core447 wants to merge 20 commits into
mainfrom
cursor/streamcontroller-cleanup-pass-5fdc

Conversation

@Core447

@Core447 Core447 commented Apr 26, 2026

Copy link
Copy Markdown
Member

Splits 14 oversized files into focused per-class/per-feature modules under sibling subpackages, with re-export shims so existing public import paths keep working. Plugin-facing modules (DeckController.py, GtkHelper.py) are kept as shims with __all__ enumerating their public surface so external plugins continue to import the same class objects.

What changed

File splits

  • src/backend/DeckManagement/DeckController.py → split into Subclasses/MediaPlayer.py, Background.py, KeyGIF.py, InputStateManagers.py, ControllerInput.py, ControllerKey.py, ControllerDial.py, ControllerTouchScreen.py. The original file keeps the DeckController class plus a top-level re-export block (with __all__ listing all 20 class names) so from src.backend.DeckManagement.DeckController import BackgroundImage, DeckController, ... keeps resolving for plugins.
  • src/backend/trayicon.pysrc/backend/trayicon/ package with DBusService.py, DBusTrayIcon.py, DBusMenu.py and an __init__.py shim.
  • src/windows/Settings/Settings.pyPages/ subfolder (UIPage.py, DevPage.py, GeneralPage.py, StorePage.py, PerformancePage.py, SystemPage.py).
  • src/windows/mainWindow/elements/Sidebar/Sidebar.pyParts/ subfolder (KeyEditor.py, PageEditor.py, Pages.py).
  • src/windows/mainWindow/elements/Sidebar/elements/ActionManager.pyActionManagerParts/.
  • src/windows/mainWindow/elements/Sidebar/elements/ActionChooser.pyActionChooserParts/.
  • src/windows/mainWindow/elements/Sidebar/elements/ActionConfigurator.pyActionConfiguratorParts/.
  • src/windows/mainWindow/elements/Sidebar/elements/LabelEditor.pyLabelEditorParts/.
  • src/windows/mainWindow/elements/KeyGrid.py → extracted KeyButton.py and KeyButtonContextMenu.py.
  • src/windows/mainWindow/DeckPlus/DialBox.py → extracted Dial.py and DialContextMenu.py.
  • src/windows/Onboarding/OnboardingWindow.pyScreens/ subfolder; the file keeps OnboardingWindow and re-exports SupportAppOnboardingScreen (used by DonateWindow.py).
  • src/windows/mainWindow/elements/DeckSettings/DeckGroup.pyDeckGroupParts/ (Rotation, Brightness, Screensaver).
  • src/windows/mainWindow/elements/PageSettings/DeckGroup.pyDeckGroupParts/ (Brightness, Screensaver).
  • src/windows/PageManager/elements/PageEditor.pyPageEditorParts/; PageEditorGroup base class kept in PageEditorBase.py.
  • GtkHelper/GtkHelper.py → widget classes moved to GtkHelper/widgets/. The original keeps all free functions plus the local ComboRow/ScaleRow (which collide with the sibling GtkHelper/ComboRow.py / GtkHelper/ScaleRow.py files), and re-exports every other widget class so from GtkHelper.GtkHelper import BetterExpander, ... keeps resolving to the same class objects.
  • main.py → CLI helpers extracted to src/cli/list_devices.py, src/cli/list_pages.py, src/cli/dispatcher.py. Runtime init extracted to src/runtime/init.py. main.py keeps the patcher init, top-level imports, the Main class, load(), main().

Cleanup pass (touched files only)

  • Dropped unused imports and obviously obsolete commented-out code (e.g. # gl.tray_icon.run_detached(), # self.show_donate(), # return image.copy().rotate(self.deck.get_rotation())).
  • Replaced 27 occurrences of bare except: with except Exception: across the project so KeyboardInterrupt / SystemExit propagate (the plan estimated 18, the actual count is higher).

Bug fix

  • src/app.py App.on_change_page: moved the if page_path is None: continue guard so it runs immediately after gl.page_manager.find_matching_page_path(...), instead of after os.path.abspath(page_path) and gl.page_manager.get_page(page_path, controller) (where it was previously a no-op for the failing path).

Stretch: plugin import hang resilience

  • src/backend/PluginManager/PluginManager.py load_plugins now imports each plugin's main module on a daemon worker thread with a join(timeout=...) (15s by default, configurable via STREAMCONTROLLER_PLUGIN_IMPORT_TIMEOUT). If a plugin hangs at import time, it is logged and skipped so app startup continues. Exceptions raised inside the worker thread are captured and re-logged on the main thread, preserving the existing behaviour for normal failures.

Plugin compatibility

  • All files plugins import from (DeckController.py, GtkHelper.py, Page.py, InputIdentifier.py, ImageHelpers.py, PluginBase.py, ActionBase.py, ActionCore.py, ActionHolder.py, ActionInputSupport.py, EventAssigner.py, EventHolder.py, InputBases.py, PluginSettings/Asset.py, Signals.py, GtkHelper/ComboRow.py, GtkHelper/ItemListComboRow.py, GtkHelper/GenerativeUI/*) keep working unchanged.
  • For the two split-and-plugin-imported files (DeckController.py, GtkHelper.py), the public surface is enumerated with explicit __all__ and re-exported as the same class objects (verified by an is-identity check).

Verification

  • Module-import smoke test (every touched top-level module + key shims): PASS.
  • Plugin-style import smoke test (every from GtkHelper... / from src... line scanned across the bundled plugins, including the is-identity check for the two split shim modules): PASS.
  • Live launch: python main.py --devel --data data reaches Finished loading app and the process stays alive (StreamController PID confirmed). The only Traceback in the log is a pre-existing libadwaita 1.5 vs 1.6 incompatibility (Adw.ButtonRow) that exists on main and is unrelated to this PR.

Out of scope

  • Refactoring or shortening of any function/method body.
  • Type-hint additions or signature changes.
  • Code formatting beyond what relocation requires.
  • Renaming of classes/methods/variables.
Open in Web Open in Cursor 

cursoragent and others added 16 commits April 26, 2026 19:15
@gensyn

gensyn commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

I can run this branch without noticing any difference. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants