feat(settings): Flatpak/Snap sandbox section with copyable permission commands

Tauri parity (the sections did not survive the Slint port): a Settings
section shown only on sandboxed installs holding the one-time permission
commands with copy-to-clipboard buttons. Flatpak: exclusive-DAC D-Bus
reservation override (the user-side fix for #641's exclusive-mode failure
— the Flathub manifest cannot carry the wildcard own-name past its linter,
so the user grants it locally) and NAS/external-drive filesystem access.
Snap: the audio interface connections (qbz-player:alsa/pulseaudio/
pipewire/mpris) plus optional removable-media. New SandboxState global
seeded from qbz_app::diagnostics install_method; 14 msgids across all 8
bundled locales.

km
This commit is contained in:
vicrodh committed 2026-07-20 13:47:24 -06:00
1 parent a5242435e0
commit 9353ed700d
13 files changed
+556 -2

No files matched your search

@@ -4660,3 +4660,45 @@ msgstr "Titel auswählen"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuz weist Anfragen vorübergehend ab – kurze Pause. Bitte gleich erneut versuchen."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "FLATPAK-SANDBOX"
msgid "SNAP SANDBOX"
msgstr "SNAP-SANDBOX"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ läuft in einer Flatpak-Sandbox. Manche Funktionen brauchen einmalige Berechtigungen — führe die Befehle in einem Terminal aus und starte QBZ danach neu. Die Berechtigungen bleiben über Updates hinweg erhalten."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ läuft in einer Snap-Sandbox. Manche Audio-Schnittstellen müssen einmalig verbunden werden — führe diese Befehle in einem Terminal aus und starte QBZ danach neu."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Exklusiver DAC-Zugriff (Bit-perfekt)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Empfohlen für den exklusiven Modus: QBZ kann PipeWire bitten, den DAC sauber zu übergeben (D-Bus-Gerätereservierung)."
msgid "Music on NAS or external drives"
msgstr "Musik auf NAS oder externen Laufwerken"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Gibt Zugriff auf einen Ordner außerhalb der Sandbox. Wiederhole den Befehl für jeden Ordner, den du brauchst."
msgid "Required audio connections"
msgstr "Erforderliche Audio-Verbindungen"
msgid "Optional — external drives & NAS"
msgstr "Optional — externe Laufwerke & NAS"
msgid "Copy"
msgstr "Kopieren"
msgid "Copied!"
msgstr "Kopiert!"
@@ -453,3 +453,45 @@ msgstr "Select tracks"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "FLATPAK SANDBOX"
msgid "SNAP SANDBOX"
msgstr "SNAP SANDBOX"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Exclusive DAC access (bit-perfect)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgid "Music on NAS or external drives"
msgstr "Music on NAS or external drives"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgid "Required audio connections"
msgstr "Required audio connections"
msgid "Optional — external drives & NAS"
msgstr "Optional — external drives & NAS"
msgid "Copy"
msgstr "Copy"
msgid "Copied!"
msgstr "Copied!"
@@ -4690,3 +4690,45 @@ msgstr "Seleccionar pistas"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuz está rechazando solicitudes temporalmente; esperando un momento. Intenta de nuevo en breve."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "SANDBOX DE FLATPAK"
msgid "SNAP SANDBOX"
msgstr "SANDBOX DE SNAP"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ se está ejecutando dentro de un sandbox de Flatpak. Algunas funciones necesitan permisos que se otorgan una sola vez: ejecuta los comandos en una terminal y reinicia QBZ. Los permisos se conservan entre actualizaciones."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ se está ejecutando dentro de un sandbox de Snap. Algunas interfaces de audio necesitan conectarse una sola vez: ejecuta estos comandos en una terminal y reinicia QBZ."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Acceso exclusivo al DAC (bit-perfect)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Recomendado para el modo exclusivo: permite que QBZ le pida a PipeWire que entregue el DAC limpiamente (reserva de dispositivo por D-Bus)."
msgid "Music on NAS or external drives"
msgstr "Música en NAS o discos externos"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Da acceso a una carpeta fuera del sandbox. Repite el comando por cada carpeta que necesites."
msgid "Required audio connections"
msgstr "Conexiones de audio requeridas"
msgid "Optional — external drives & NAS"
msgstr "Opcional — discos externos y NAS"
msgid "Copy"
msgstr "Copiar"
msgid "Copied!"
msgstr "¡Copiado!"
@@ -4660,3 +4660,45 @@ msgstr "Sélectionner des pistes"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuz refuse temporairement les requêtes — pause en cours. Réessayez dans un instant."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "SANDBOX FLATPAK"
msgid "SNAP SANDBOX"
msgstr "SANDBOX SNAP"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ s'exécute dans un sandbox Flatpak. Certaines fonctions nécessitent des autorisations à accorder une seule fois — exécutez les commandes dans un terminal, puis redémarrez QBZ. Les autorisations sont conservées après les mises à jour."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ s'exécute dans un sandbox Snap. Certaines interfaces audio doivent être connectées une seule fois — exécutez ces commandes dans un terminal, puis redémarrez QBZ."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Accès exclusif au DAC (bit-perfect)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Recommandé pour le mode exclusif : permet à QBZ de demander à PipeWire de céder le DAC proprement (réservation de périphérique D-Bus)."
msgid "Music on NAS or external drives"
msgstr "Musique sur NAS ou disques externes"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Donne accès à un dossier hors du sandbox. Répétez la commande pour chaque dossier nécessaire."
msgid "Required audio connections"
msgstr "Connexions audio requises"
msgid "Optional — external drives & NAS"
msgstr "Optionnel — disques externes et NAS"
msgid "Copy"
msgstr "Copier"
msgid "Copied!"
msgstr "Copié !"
@@ -4648,3 +4648,45 @@ msgstr "トラックを選択"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuzが一時的にリクエストを拒否しています。少し待って再試行してください。"
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "FLATPAK サンドボックス"
msgid "SNAP SANDBOX"
msgstr "SNAP サンドボックス"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ は Flatpak サンドボックス内で動作しています。一部の機能には一度だけの権限付与が必要です。コマンドをターミナルで実行してから QBZ を再起動してください。権限はアップデート後も保持されます。"
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ は Snap サンドボックス内で動作しています。一部のオーディオインターフェースは一度だけ接続する必要があります。これらのコマンドをターミナルで実行してから QBZ を再起動してください。"
msgid "Exclusive DAC access (bit-perfect)"
msgstr "DAC 排他アクセス(ビットパーフェクト)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "排他モードに推奨:PipeWire に DAC のクリーンな引き渡しを要求できます(D-Bus デバイス予約)。"
msgid "Music on NAS or external drives"
msgstr "NAS や外部ドライブの音楽"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "サンドボックス外のフォルダへのアクセスを許可します。必要なフォルダごとにコマンドを繰り返してください。"
msgid "Required audio connections"
msgstr "必須のオーディオ接続"
msgid "Optional — external drives & NAS"
msgstr "任意 — 外部ドライブと NAS"
msgid "Copy"
msgstr "コピー"
msgid "Copied!"
msgstr "コピーしました!"
@@ -4672,3 +4672,45 @@ msgstr "Nummers selecteren"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuz weigert tijdelijk verzoeken — even pauzeren. Probeer het zo opnieuw."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "FLATPAK-SANDBOX"
msgid "SNAP SANDBOX"
msgstr "SNAP-SANDBOX"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ draait in een Flatpak-sandbox. Sommige functies hebben eenmalige rechten nodig — voer de commando's in een terminal uit en herstart daarna QBZ. De rechten blijven na updates behouden."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ draait in een Snap-sandbox. Sommige audio-interfaces moeten eenmalig worden gekoppeld — voer deze commando's in een terminal uit en herstart daarna QBZ."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Exclusieve DAC-toegang (bit-perfect)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Aanbevolen voor de exclusieve modus: laat QBZ PipeWire vragen de DAC netjes vrij te geven (D-Bus-apparaatreservering)."
msgid "Music on NAS or external drives"
msgstr "Muziek op NAS of externe schijven"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Geeft toegang tot een map buiten de sandbox. Herhaal het commando voor elke map die je nodig hebt."
msgid "Required audio connections"
msgstr "Vereiste audiokoppelingen"
msgid "Optional — external drives & NAS"
msgstr "Optioneel — externe schijven & NAS"
msgid "Copy"
msgstr "Kopiëren"
msgid "Copied!"
msgstr "Gekopieerd!"
@@ -4660,3 +4660,45 @@ msgstr "Selecionar faixas"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "O Qobuz está recusando solicitações temporariamente — aguardando. Tente novamente em breve."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "SANDBOX FLATPAK"
msgid "SNAP SANDBOX"
msgstr "SANDBOX SNAP"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "O QBZ está a correr dentro de uma sandbox Flatpak. Algumas funcionalidades precisam de permissões concedidas uma única vez — execute os comandos num terminal e reinicie o QBZ. As permissões mantêm-se entre atualizações."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "O QBZ está a correr dentro de uma sandbox Snap. Algumas interfaces de áudio precisam de ser ligadas uma única vez — execute estes comandos num terminal e reinicie o QBZ."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Acesso exclusivo ao DAC (bit-perfect)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Recomendado para o modo exclusivo: permite ao QBZ pedir ao PipeWire que entregue o DAC de forma limpa (reserva de dispositivo via D-Bus)."
msgid "Music on NAS or external drives"
msgstr "Música em NAS ou discos externos"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Concede acesso a uma pasta fora da sandbox. Repita o comando para cada pasta necessária."
msgid "Required audio connections"
msgstr "Ligações de áudio obrigatórias"
msgid "Optional — external drives & NAS"
msgstr "Opcional — discos externos e NAS"
msgid "Copy"
msgstr "Copiar"
msgid "Copied!"
msgstr "Copiado!"
@@ -4674,3 +4674,45 @@ msgstr "Выбрать треки"
msgid "Qobuz is temporarily refusing requests — backing off. Try again shortly."
msgstr "Qobuz временно отклоняет запросы — пауза. Повторите попытку чуть позже."
msgid "Flatpak"
msgstr "Flatpak"
msgid "Snap"
msgstr "Snap"
msgid "FLATPAK SANDBOX"
msgstr "ПЕСОЧНИЦА FLATPAK"
msgid "SNAP SANDBOX"
msgstr "ПЕСОЧНИЦА SNAP"
msgid "QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates."
msgstr "QBZ работает внутри песочницы Flatpak. Некоторым функциям нужны разрешения, выдаваемые один раз, — выполните команды в терминале и перезапустите QBZ. Разрешения сохраняются между обновлениями."
msgid "QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ."
msgstr "QBZ работает внутри песочницы Snap. Некоторые аудиоинтерфейсы нужно подключить один раз — выполните эти команды в терминале и перезапустите QBZ."
msgid "Exclusive DAC access (bit-perfect)"
msgstr "Эксклюзивный доступ к ЦАП (bit-perfect)"
msgid "Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation)."
msgstr "Рекомендуется для эксклюзивного режима: позволяет QBZ попросить PipeWire корректно освободить ЦАП (резервирование устройства через D-Bus)."
msgid "Music on NAS or external drives"
msgstr "Музыка на NAS или внешних дисках"
msgid "Grants access to a folder outside the sandbox. Repeat the command for each folder you need."
msgstr "Даёт доступ к папке вне песочницы. Повторите команду для каждой нужной папки."
msgid "Required audio connections"
msgstr "Необходимые аудиоподключения"
msgid "Optional — external drives & NAS"
msgstr "Опционально — внешние диски и NAS"
msgid "Copy"
msgstr "Копировать"
msgid "Copied!"
msgstr "Скопировано!"
+1 -1
View File
@@ -31,7 +31,7 @@ export { ThemeState } from "foundation/theme-state.slint";
export { Typography } from "foundation/typography.slint";
// Re-export the state globals so the Rust layer can populate them.
export { HomeState, HomeActions, RecentAlbumsState, DiscoverState, DiscoverActions, SectionDescriptor, ConfigRow, DiscoverBrowseState, DiscoverBrowseActions, PlaylistBrowseState, PlaylistBrowseActions, ForYouState, PinnedItem, PinnedState, PinnedActions, ExternalRecoState, ExternalRecoActions, MixState, GenreFilterState, GenreFilterActions, AlbumState, ArtistState, NavState, ShellState, SessionState, SettingsState, AlbumActions, ArtistActions, ArtworkActions, NowPlayingState, QueueState, LyricsState, LyricsLineItem, SearchState, SearchActions, NetworkSidebarState, NetworkSidebarActions, MusicianState, MusicianActions, LabelState, LabelActions, AwardState, AwardActions, AwardEntry, ArtistReleasesState, ArtistReleasesActions, LocationViewState, LocationViewActions, FavoritesState, FavoritesActions, LibraryFeedItem, LibraryAllState, LibraryAllActions, PlaylistPickerState, PlaylistPickerActions, DuplicateConfirmState, DuplicateConfirmActions, PlaylistState, PlaylistActions, SidebarState, SidebarActions, SidebarFolderPopupState, CreatePlaylistState, CreatePlaylistActions, EditPlaylistState, EditPlaylistActions, CreateFolderState, CreateFolderActions, SettingsExportState, SettingsExportActions, MyQbzCreateState, MyQbzCreateActions, DragState, DragActions, PlaylistManagerState, PlaylistManagerActions, OfflineManagerState, OfflineManagerActions, BlacklistState, BlacklistActions, BlacklistedArtistItem, MyQbzState, MyQbzActions, MixtapeCardItem, MyQbzAddState, MyQbzAddActions, MyQbzAddRow, MyQbzDetailState, MyQbzDetailActions, MixtapeDetailItem, MyQbzEditState, MyQbzEditActions, MyQbzMixState, MyQbzMixActions, DiscoBuilderState, DiscoBuilderActions, DiscoGroup, DiscoCandidate, LocalLibraryState, LocalLibraryActions, LibraryFoldersState, LibFolderEditState, LibraryManageActions, LibraryScanState, LibAlbumFilterState, LocalAlbumState, LocalAlbumActions, TagEditorState, TagEditorActions, FolderEditState, FolderEditActions, ToastState, TextUtil, QconnectDevState, QconnectDevice, CastState, CastDevice, CastActions, AppearanceState, MyQbzBrandingState, EphemeralPlayChoiceState, EphemeralPlayChoiceActions, PlexSettingsState, PlexAuthActions, PlexSectionItem, ScrobbleState, ScrobbleActions, DiscordState, OfflineState, LoginState, OfflineModeActions, OfflineFavoritesState, OfflineFavoritesActions, ImportLogEntry, PlaylistImportState, PlaylistImportActions, DacWizardState, DacWizardActions, DacCandidateRow, RemediationRow, DacConfigRow, InfoCreditRow, InfoCreditPair, AlbumCreditPerformer, AlbumCreditTrack, TrackInfoState, TrackInfoActions, AlbumInfoState, AlbumInfoActions, BookletState, BookletActions, SuggestionsState, SuggestionsActions, SuggestionCard, PlaylistSuggestionsState, PlaylistSuggestionsActions, PlaylistSuggestionRow, VisualizerState, ImmersiveState, ImmersiveSearchActions, ImmersiveActions, MiniPlayerState, WindowControlActions, PurchasesState, PurchasesActions, PurchaseAlbumItem, PurchaseTrackItem, PurchaseAlbumGroup, PurchaseTrackGroup, PurchaseFormatItem, PurchaseDetailState, PurchaseDetailActions, PurchaseDetailTrack, KeybindingRow, KeybindingCategoryGroup, KeybindingsState, KeybindingsActions, KeyboardShortcutsState, LinkResolverState, LinkResolverActions, UiFocusState, UiScale, SleepTimerState, SleepTimerActions, LogRow, LogViewerState, DiagRow, DiagnosticsState, ReportIssueState, ReportIssueActions, AboutState, AboutActions, AboutContributorRow, AboutContributorGroup, WhatsNewState, WhatsNewActions, WhatsNewBlock, WhatsNewTocEntry } from "state.slint";
export { HomeState, HomeActions, RecentAlbumsState, DiscoverState, DiscoverActions, SectionDescriptor, ConfigRow, DiscoverBrowseState, DiscoverBrowseActions, PlaylistBrowseState, PlaylistBrowseActions, ForYouState, PinnedItem, PinnedState, PinnedActions, ExternalRecoState, ExternalRecoActions, MixState, GenreFilterState, GenreFilterActions, AlbumState, ArtistState, NavState, ShellState, SessionState, SettingsState, AlbumActions, ArtistActions, ArtworkActions, NowPlayingState, QueueState, LyricsState, LyricsLineItem, SearchState, SearchActions, NetworkSidebarState, NetworkSidebarActions, MusicianState, MusicianActions, LabelState, LabelActions, AwardState, AwardActions, AwardEntry, ArtistReleasesState, ArtistReleasesActions, LocationViewState, LocationViewActions, FavoritesState, FavoritesActions, LibraryFeedItem, LibraryAllState, LibraryAllActions, PlaylistPickerState, PlaylistPickerActions, DuplicateConfirmState, DuplicateConfirmActions, PlaylistState, PlaylistActions, SidebarState, SidebarActions, SidebarFolderPopupState, CreatePlaylistState, CreatePlaylistActions, EditPlaylistState, EditPlaylistActions, CreateFolderState, CreateFolderActions, SettingsExportState, SettingsExportActions, SandboxState, MyQbzCreateState, MyQbzCreateActions, DragState, DragActions, PlaylistManagerState, PlaylistManagerActions, OfflineManagerState, OfflineManagerActions, BlacklistState, BlacklistActions, BlacklistedArtistItem, MyQbzState, MyQbzActions, MixtapeCardItem, MyQbzAddState, MyQbzAddActions, MyQbzAddRow, MyQbzDetailState, MyQbzDetailActions, MixtapeDetailItem, MyQbzEditState, MyQbzEditActions, MyQbzMixState, MyQbzMixActions, DiscoBuilderState, DiscoBuilderActions, DiscoGroup, DiscoCandidate, LocalLibraryState, LocalLibraryActions, LibraryFoldersState, LibFolderEditState, LibraryManageActions, LibraryScanState, LibAlbumFilterState, LocalAlbumState, LocalAlbumActions, TagEditorState, TagEditorActions, FolderEditState, FolderEditActions, ToastState, TextUtil, QconnectDevState, QconnectDevice, CastState, CastDevice, CastActions, AppearanceState, MyQbzBrandingState, EphemeralPlayChoiceState, EphemeralPlayChoiceActions, PlexSettingsState, PlexAuthActions, PlexSectionItem, ScrobbleState, ScrobbleActions, DiscordState, OfflineState, LoginState, OfflineModeActions, OfflineFavoritesState, OfflineFavoritesActions, ImportLogEntry, PlaylistImportState, PlaylistImportActions, DacWizardState, DacWizardActions, DacCandidateRow, RemediationRow, DacConfigRow, InfoCreditRow, InfoCreditPair, AlbumCreditPerformer, AlbumCreditTrack, TrackInfoState, TrackInfoActions, AlbumInfoState, AlbumInfoActions, BookletState, BookletActions, SuggestionsState, SuggestionsActions, SuggestionCard, PlaylistSuggestionsState, PlaylistSuggestionsActions, PlaylistSuggestionRow, VisualizerState, ImmersiveState, ImmersiveSearchActions, ImmersiveActions, MiniPlayerState, WindowControlActions, PurchasesState, PurchasesActions, PurchaseAlbumItem, PurchaseTrackItem, PurchaseAlbumGroup, PurchaseTrackGroup, PurchaseFormatItem, PurchaseDetailState, PurchaseDetailActions, PurchaseDetailTrack, KeybindingRow, KeybindingCategoryGroup, KeybindingsState, KeybindingsActions, KeyboardShortcutsState, LinkResolverState, LinkResolverActions, UiFocusState, UiScale, SleepTimerState, SleepTimerActions, LogRow, LogViewerState, DiagRow, DiagnosticsState, ReportIssueState, ReportIssueActions, AboutState, AboutActions, AboutContributorRow, AboutContributorGroup, WhatsNewState, WhatsNewActions, WhatsNewBlock, WhatsNewTocEntry } from "state.slint";
// Which top-level screen is shown. The app starts on `splash` while it
// restores a saved session, then resolves to `shell` or `login`.
@@ -0,0 +1,172 @@
// Settings > Sandbox — the one-time permission commands for sandboxed
// installs (Tauri parity: the old Settings > Flatpak / Snap sections).
// Shown only when the app runs inside Flatpak or Snap (SandboxState.
// install-method); hidden on native/dev installs.
//
// Flatpak rows: exclusive-DAC D-Bus reservation (the user-side fix for
// discussion #641 — the Flathub manifest can't carry the wildcard own-name,
// so the user grants it locally via `flatpak override`) and filesystem
// access for NAS/external music libraries. Discord's IPC override stays in
// Integrations (already there). Snap rows: the audio interface connections
// from the Tauri section (snap name is `qbz-player`).
//
// Commands are plain strings (never translated); surrounding copy goes
// through @tr. Copy feedback is local UI state (Copied! for 1.5 s); the
// clipboard write itself is SandboxState.copy-command → share::copy_to_clipboard.
import { Theme } from "../foundation/semantic-colors.slint";
import { Typography } from "../foundation/typography.slint";
import { Radius } from "../foundation/radius.slint";
import { SandboxState } from "../state.slint";
component GroupHeader inherits Text {
color: Theme.text-muted;
font-size: 11px;
letter-spacing: 1.5px;
font-weight: Typography.semibold;
}
component RowTitle inherits Text {
color: Theme.text-primary;
font-size: Typography.body;
font-weight: Typography.medium;
wrap: word-wrap;
}
component RowNote inherits Text {
color: Theme.text-muted;
font-size: Typography.legal;
wrap: word-wrap;
}
// Matches AudioSettings/OfflineSettings' SecondaryButton.
component SecondaryButton inherits Rectangle {
in property <string> label;
callback clicked();
// 160px floor keeps the settings right-edge grid; longer translations grow.
width: Math.max(label-txt.preferred-width + 32px, 160px);
height: 34px;
border-radius: Radius.sm;
border-width: 1px;
border-color: Theme.border-subtle;
background: ta.has-hover ? Theme.surface-hover : Theme.surface-elevated;
label-txt := Text {
width: 100%;
height: 100%;
text: root.label;
color: Theme.text-secondary;
font-size: Typography.body;
font-weight: Typography.medium;
horizontal-alignment: center;
vertical-alignment: center;
}
ta := TouchArea {
mouse-cursor: pointer;
clicked => {
root.clicked();
}
}
}
// Full-width shell-command row with copy-to-clipboard feedback. `command`
// may hold several lines; the whole block copies as one clipboard payload.
component CommandBlock inherits Rectangle {
in property <string> command;
property <bool> copied: false;
border-radius: Radius.sm;
border-width: 1px;
border-color: Theme.border-subtle;
background: Theme.surface-elevated;
height: cmd-layout.preferred-height;
cmd-layout := HorizontalLayout {
padding: 10px;
spacing: 12px;
Text {
text: root.command;
color: Theme.text-primary;
font-family: "monospace";
font-size: Typography.legal;
wrap: word-wrap;
horizontal-stretch: 1;
vertical-alignment: center;
}
VerticalLayout {
alignment: center;
SecondaryButton {
label: root.copied ? @tr("Copied!") : @tr("Copy");
clicked => {
SandboxState.copy-command(root.command);
root.copied = true;
copied-timer.restart();
}
}
}
}
copied-timer := Timer {
running: false;
interval: 1500ms;
triggered => {
root.copied = false;
copied-timer.stop();
}
}
}
export component SandboxSettings inherits VerticalLayout {
spacing: 4px;
alignment: start;
// --- FLATPAK ---------------------------------------------------------
if SandboxState.install-method == "flatpak": VerticalLayout {
spacing: 4px;
alignment: start;
GroupHeader { text: @tr("FLATPAK SANDBOX"); }
RowNote {
text: @tr("QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates.");
}
Rectangle { height: 8px; }
RowTitle { text: @tr("Exclusive DAC access (bit-perfect)"); }
RowNote {
text: @tr("Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation).");
}
CommandBlock {
command: "flatpak override --user --own-name=org.freedesktop.ReserveDevice1.* com.blitzfc.qbz";
}
Rectangle { height: 8px; }
RowTitle { text: @tr("Music on NAS or external drives"); }
RowNote {
text: @tr("Grants access to a folder outside the sandbox. Repeat the command for each folder you need.");
}
CommandBlock {
command: "flatpak override --user --filesystem=/path/to/your/music com.blitzfc.qbz";
}
}
// --- SNAP ------------------------------------------------------------
if SandboxState.install-method == "snap": VerticalLayout {
spacing: 4px;
alignment: start;
GroupHeader { text: @tr("SNAP SANDBOX"); }
RowNote {
text: @tr("QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ.");
}
Rectangle { height: 8px; }
RowTitle { text: @tr("Required audio connections"); }
CommandBlock {
command: "sudo snap connect qbz-player:alsa\nsudo snap connect qbz-player:pulseaudio\nsudo snap connect qbz-player:pipewire\nsudo snap connect qbz-player:mpris";
}
Rectangle { height: 8px; }
RowTitle { text: @tr("Optional — external drives & NAS"); }
CommandBlock {
command: "sudo snap connect qbz-player:removable-media";
}
}
}
+21 -1
View File
@@ -8,7 +8,7 @@
import { Theme } from "../foundation/semantic-colors.slint";
import { Typography } from "../foundation/typography.slint";
import { Radius } from "../foundation/radius.slint";
import { NavState, ContentView, SettingsState, LogViewerState } from "../state.slint";
import { NavState, ContentView, SettingsState, LogViewerState, SandboxState } from "../state.slint";
import { QbzIcon } from "../primitives/QbzIcon.slint";
import { NavButtons } from "../shell/NavButtons.slint";
import { AudioSettings } from "AudioSettings.slint";
@@ -19,6 +19,7 @@ import { LocalLibrarySettings } from "LocalLibrarySettings.slint";
import { ContentFilteringSettings } from "ContentFilteringSettings.slint";
import { IntegrationsSettings } from "IntegrationsSettings.slint";
import { DeveloperSettings } from "DeveloperSettings.slint";
import { SandboxSettings } from "SandboxSettings.slint";
import { ScrollView } from "std-widgets.slint";
import { ListScrollbar } from "../primitives/ListScrollbar.slint";
@@ -180,6 +181,24 @@ export component SettingsView inherits Rectangle {
SettingsState.section = 5;
}
}
// Sandbox (Flatpak/Snap) — only on sandboxed installs;
// holds the one-time permission commands (Tauri parity).
if SandboxState.install-method == "flatpak": SubNavItem {
icon: @image-url("../assets/icons/lock.svg");
label: @tr("Flatpak");
active: SettingsState.section == 8;
clicked => {
SettingsState.section = 8;
}
}
if SandboxState.install-method == "snap": SubNavItem {
icon: @image-url("../assets/icons/lock.svg");
label: @tr("Snap");
active: SettingsState.section == 8;
clicked => {
SettingsState.section = 8;
}
}
// Absorbs the leftover height so the log affordance below
// pins to the bottom of the sub-nav column.
Rectangle { }
@@ -277,6 +296,7 @@ export component SettingsView inherits Rectangle {
}
}
if !SettingsState.loading && SettingsState.section == 5: DeveloperSettings { }
if !SettingsState.loading && SettingsState.section == 8: SandboxSettings { }
}
}
ListScrollbar {
+13
View File
@@ -5709,6 +5709,19 @@ export global DacWizardActions {
callback toggle-config(int); // collapse/expand one DAC's config accordion
}
// ============================================================================
// Sandbox (Flatpak/Snap) — Settings section holding the one-time permission
// commands for sandboxed installs (Tauri parity: Settings > Flatpak / Snap).
// The section is only shown when install-method is "flatpak" or "snap".
// ============================================================================
export global SandboxState {
// "flatpak" | "snap" | anything else (section hidden). Seeded once at
// startup from qbz_app::diagnostics::system_info().install_method.
in property <string> install-method: "";
callback copy-command(string); // → crate::share::copy_to_clipboard
}
// ============================================================================
// Keyboard shortcuts (hotkeys) — port of the Tauri keybindings system.
// ============================================================================