Skip to content

ability to only run specified Stream Decks instead of all attached decks - #227

Draft
violet4 wants to merge 2 commits into
StreamController:mainfrom
violet4:only_attach_specified_decks
Draft

ability to only run specified Stream Decks instead of all attached decks#227
violet4 wants to merge 2 commits into
StreamController:mainfrom
violet4:only_attach_specified_decks

Conversation

@violet4

@violet4 violet4 commented Sep 9, 2024

Copy link
Copy Markdown

this is achieved by adding --list and --paths command line arguments.

  • --list lists all the attached Stream Deck devices with some basic information, including their "paths", and exits
  • --paths takes 1 or more paths (found via --list) and filters out paths not specified before initializing the devices

if anyone cares about this change enough to want to merge it, but it's terrible or doesn't match the project requirements, please point me in the correct direction and i'd be happy to improve it and make it acceptable. however, at the moment, this makes it so i can use this software with one of my stream decks and my own program with my other stream deck simultaneously.

…cks. achieved by adding `--list` and `--paths` command line arguments.

`--list` lists all the attached	Stream Deck devices with some basic information, including their "paths", and exits
`--paths` takes	1 or more paths	(found via `--list`) and filters out paths not specified before	initializing the devices
@Core447

Core447 commented Sep 9, 2024

Copy link
Copy Markdown
Member

Nice work! In the future we can maybe even add an option to the settings for this. The only problem I'm encountering is that if I instance is already running and --list is used it shows the window of the running instance and doesn't print the available decks.

@violet4

violet4 commented Sep 16, 2024

Copy link
Copy Markdown
Author

tl;dr go ahead and close this PR when you see my message and i'll eventually submit a better one that handles more cases.

also my PR doesn't work so great if the externally managed stream deck is connected while StreamController is already running, since StreamController seems to watch new stream deck connections and attach to them automatically.

so clearly, this naïve/lazy PR isn't going to work for most use cases and i'm gonna have to put some more work into making it more robust and generally acceptable.

i'm not in any rush to make this super fully integrated and handle all cases, but i'm thinking this PR should be closed and i can use my own branch for a while over the course of a period of time and make small fixes until it's been a while since i've seen any issues. i can continuously rebase from this repo so it stays in sync and eventually make a PR when i've fixed all (currently unhandled) cases i've encountered (plus the one you mentioned).

i'll let you see this message, feel free to close the PR and i'll (slowly) work on improving it on my branch. at the moment my main concern is ensuring compatibility with my own awful stream deck implementation that i depend upon daily until i get the functionality moved over to StreamController.

((for example, i'll have to learn how the plugin system works so i can port my cute little stream deck calculator app.))

thank you for your time and patience!

@violet4

violet4 commented Sep 16, 2024

Copy link
Copy Markdown
Author

also i created a ticket for myself to keep track of specific needed fixes violet4#2

@Core447

Core447 commented Sep 18, 2024

Copy link
Copy Markdown
Member

port my cute little stream deck calculator app

Sounds nice!

@violet4 I'll convert this PR to a draft so that you don't have to create a new one (which you can ofc also do if you want).

@Core447
Core447 marked this pull request as draft September 18, 2024 15:41
nazbert added a commit to nazbert/Deckard that referenced this pull request Aug 9, 2026
Brings src/windows/** from 254 mypy errors to 0. Type-only apart from the
genuine defects below, each of which mypy surfaced.

Bugs fixed (behaviour changes):
- AssetManager/CustomAssets/Chooser.py: gl.asset_manager.set_cursor_from_name
  was called unguarded, but AssetManager.on_close nulls gl.asset_manager -- a
  drop or file-dialog callback landing after the window closed raised
  AttributeError. Guarded; the files are still added.
- mainWindow.py: get_active_page() returned gl.page_manager.dummy_page, an
  attribute that exists nowhere, so the no-deck-selected path raised
  AttributeError. Returns None (the widened contract) instead.
- ActionMissing/OutdatedActionRow.py: passed coords= to a MissingRow that
  takes identifier=, so every outdated-action row raised TypeError. Signature
  realigned with the sibling MissingActionButtonRow and its call site.
- Sidebar/Sidebar.py: KeyEditorKeyBox.load_for_key called
  ActionManager.load_for_coords, which lives on ActionGroup -> AttributeError.
- ActionManager.py: ActionRow.update_comment wrote to a comment_row that has
  never existed (comment_label does). set_label_toggled referenced an
  on_allow_label_toggled handler on no class; disabled alongside its
  already-commented call site.
- ActionConfigurator.py: select_event dereferenced a None event_assigner when
  the model's first item was not the "None" entry.
- StreamDeckUI/code_conv.py: a bare `# type: ignore` hid an undefined
  _DELAY_KEYSYM, so any imported hotkey with a delay token raised NameError
  into the importer's except and silently dropped the whole hotkey. Delay
  tokens are now rejected explicitly.
- Store/InfoPage.py: set_stargazer drove a row commented out in build();
  disabled with it.
- Settings/Settings.py: CustomContentEntry assigned url/branch strings that
  the EntryRow widgets overwrote two statements later; dead stores removed.

Contract corrections: MainWindow.get_active_controller/get_active_page,
DeckStack.remove_page/get_page_attributes, PageSelector.sort_func,
OnboardingWindow.set_button_status, Store preview setters and
ImageEditor.update_values (annotated KeyLabel, handed an ImageLayout) all
declared types their bodies contradict.

Forwarded guards: ActionChooser's get_arrow_image() call sites (MR 2) and
PluginSettingsPage's ActionRow title (MR 3).

24 pinned ignores (12 gi stub, 6 late-init, 6 cross-MR forwards), 1 bare
ignore removed. Total mypy errors 949 -> 679; no new out-of-scope errors
(StoreBackend drops 16 via the StoreData widening MR 6 asked for).
nazbert added a commit to nazbert/Deckard that referenced this pull request Aug 9, 2026
Review round on the previous commit.

10th defect, directly under the earlier edit: EventAssignerUI.
change_assignment_for_event called self.action.set_event_assignments, which
exists on no class (ActionCore only has the singular set_event_assignment,
ActionCore.py:591). Its one call site sat after an unconditional return in
EventAssignerRow.on_changed, so the whole tail was dead -- and the comment
added last round ("the persisted map is keyed and valued by the events'
string names") was wrong twice over: persisted VALUES are event_assigner.id
strings (Page.py:572), not event names. Deleted the dead method and the dead
tail of on_changed instead of type-annotating fiction; the live part of
on_changed (get_event_assigner_by_id -> set_event_assignment) is untouched.

Guard asymmetry corrected: last round guarded gl.app in the DEAD _on_close
while the live on_close (:83) still dereferenced gl.app unguarded for
GLib.idle_add(gl.app.on_quit). gl.app is honestly Optional, so the live path
is now guarded too.

Honesty corrections to the previous commit message:
- Sidebar.py KeyEditorKeyBox.load_for_key: the load_for_coords ->
  load_for_identifier fix is correct, but KeyEditorKeyBox is instantiated
  nowhere, so this was dead code, not a live AttributeError. The same method
  also passes key.coords where an InputIdentifier is expected (hidden by an
  unannotated return type) -- left for the residual sweep.
- Store/Icons/IconPage.py: the guarded get_custom_translation block is dead
  -- the next line unconditionally overwrites `description` from
  short_description/description. Pre-existing; the guard is still correct for
  the day that line goes.
- The three FlowBox super().__init__(base_class=...) -> positional changes
  are no-ops today: every construction goes through FLOW_BOX_CLASS(preview,
  chooser) with an empty *args.

Gates unchanged: src/windows/** 0 errors, total 679, 24 pinned ignores,
ruff clean, harness 174/174.
nazbert added a commit to nazbert/Deckard that referenced this pull request Aug 9, 2026
…roller#227)

Rebased onto gitlab/main (86db4f9, MRs StreamController#222/StreamController#223/StreamController#225/StreamController#226 landed). Eleven
in-scope errors appeared, all from StreamController#225's honest widening; re-zeroed.

Absorbed (11):
- LabelEditor.py (10) -- KeyLabel.text/color/outline_width/outline_color/
  alignment/font_name/font_size/style/font_weight are all `| None` now.
  _update_values_locked treats an unset text as "", and the four LabelRow
  setters take `| None` and no-op rather than being handed a None (which
  color_values_to_gdk / set_value would have raised on). The font
  description needs all four properties, so an incompletely composed label
  leaves the chooser alone instead of calling Pango with None.
- ImageEditor.py (1) -- ImageLayout.size is `| None`; the spinner keeps its
  value when unset instead of evaluating None*100.

Stale ignores removed (4): StreamController#225 fixed both root causes this branch forwarded,
so the two color_values_to_gdk arg-type ignores in LabelEditor and the two
InputIdentifier.Events attr-defined ignores in ActionConfigurator are gone.
Verified with a --warn-unused-ignores diagnostic run: no stale ignores remain
in src/windows (config untouched).

Ignores: 24 -> 20 (12 gi stub, 6 late-init, 2 cross-MR).

Both surviving cross-MR forwards outlived StreamController#226, which zeroed those files
without widening the two signatures (their only offending callers live in
src/windows, so StreamController#226 never saw the errors) -- for the residual sweep:
- PageManagerBackend.set_default_page:309 `path: str`, but None is the
  documented "clear the default" value.
- AssetManagerBackend.add_custom_media_set_by_ui:333 `path: str`, whose first
  branch is `if path is None and url is not None`.

Gates on the rebased tree: src/windows/** 0 errors, total 228 (all in
DeckController.py 227 + ActionCore.py 1, i.e. StreamController#224's scope), ruff clean,
harness 175/175.
nazbert pushed a commit to nazbert/Deckard that referenced this pull request Aug 9, 2026
types(7/8): windows/ to zero mypy errors

Closes StreamController#227

See merge request naz/Deckard!116
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.

2 participants