flea-qml 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +511 -2
- package/THIRD-PARTY-NOTICES.md +29 -0
- package/demos/App.java +5 -0
- package/demos/Dockerfile +4 -0
- package/demos/Main.kt +3 -0
- package/demos/Program.cs +1 -0
- package/demos/README.md +12 -0
- package/demos/app.dart +3 -0
- package/demos/app.deb +0 -0
- package/demos/app.js +1 -0
- package/demos/backup.tar +0 -0
- package/demos/budget.xlsx +0 -0
- package/demos/build.sh +2 -0
- package/demos/bundle.zip +0 -0
- package/demos/clip.mp4 +0 -0
- package/demos/data.sqlite +0 -0
- package/demos/disk.iso +0 -0
- package/demos/engine.cpp +5 -0
- package/demos/firmware.bin +0 -0
- package/demos/flake.nix +4 -0
- package/demos/folder/inside.txt +1 -0
- package/demos/font.ttf +0 -0
- package/demos/index.html +5 -0
- package/demos/index.php +2 -0
- package/demos/init.lua +1 -0
- package/demos/letter.docx +0 -0
- package/demos/lib.rs +3 -0
- package/demos/main.c +6 -0
- package/demos/main.h +3 -0
- package/demos/math-and-diagrams.md +200 -0
- package/demos/notes.tar.gz +0 -0
- package/demos/notes.txt +3 -0
- package/demos/photo.png +0 -0
- package/demos/program +2 -0
- package/demos/report.pdf +32 -0
- package/demos/script.py +1 -0
- package/demos/server.go +7 -0
- package/demos/settings.json +4 -0
- package/demos/slides.pptx +0 -0
- package/demos/song.mp3 +0 -0
- package/demos/style.css +4 -0
- package/demos/tool.rb +1 -0
- package/demos/types.ts +2 -0
- package/docs/pele.md +23 -0
- package/docs/protocol.md +3420 -0
- package/docs/temml.md +63 -0
- package/index.js +107 -0
- package/package.json +34 -4
- package/src/archive.js +407 -0
- package/src/archiveops.js +728 -0
- package/src/backend.js +369 -0
- package/src/bulkrename.js +95 -0
- package/src/clip-host.js +76 -0
- package/src/clip.js +462 -0
- package/src/code.js +168 -0
- package/src/compare.js +74 -0
- package/src/create.js +128 -0
- package/src/dirsize.js +147 -0
- package/src/figure-svg.js +530 -0
- package/src/figure-thread.js +23 -0
- package/src/figure.js +132 -0
- package/src/find.js +55 -0
- package/src/flea.js +39 -0
- package/src/fsinfo.js +39 -0
- package/src/highlight.js +141 -0
- package/src/html.js +52 -0
- package/src/kinds.js +89 -0
- package/src/listing.js +130 -0
- package/src/markdown-html.js +317 -0
- package/src/mathml.js +186 -0
- package/src/menu.js +180 -0
- package/src/meta.js +135 -0
- package/src/office.js +810 -0
- package/src/order.js +100 -0
- package/src/peek.js +49 -0
- package/src/pele-wrapper.js +695 -0
- package/src/permissions.js +180 -0
- package/src/places.js +313 -0
- package/src/preview-language.js +10 -0
- package/src/terminal-server.js +95 -0
- package/src/terminal-shell.js +26 -0
- package/src/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +327 -0
- package/src/uistate.js +393 -0
- package/src/uistore.js +168 -0
- package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
- package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
- package/src/vendor/LICENSES/MIT-katex.txt +21 -0
- package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
- package/src/vendor/LICENSES/MIT-pele.txt +40 -0
- package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
- package/src/vendor/LICENSES/MIT-temml.txt +21 -0
- package/src/vendor/pele.js +145 -0
- package/src/vendor/temml.mjs +14708 -0
- package/src/watch.js +98 -0
- package/src/wayland/client.js +109 -0
- package/src/wayland/protocol.js +55 -0
- package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
- package/src/wayland/protocols/wayland.xml +3248 -0
- package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
- package/src/wayland/resource-io.js +6 -0
- package/src/wayland/socket-discovery.js +26 -0
- package/src/wayland/transport-posix.js +120 -0
- package/src/wayland/transport-win32.js +11 -0
- package/src/wayland/transport.js +3 -0
- package/src/wayland/win32-resources.js +80 -0
- package/src/wayland/win32-wire.js +62 -0
- package/test/archive.test.js +80 -0
- package/test/bench-markdown-scroll.mjs +190 -0
- package/test/clip-host.test.js +113 -0
- package/test/code-preview.test.js +35 -0
- package/test/compare-ui-paths.test.js +24 -0
- package/test/compare.test.js +54 -0
- package/test/delete-trash.test.js +67 -0
- package/test/dirsize.test.js +138 -0
- package/test/file-ops.test.js +307 -0
- package/test/file-url.test.js +24 -0
- package/test/find-contents.test.js +161 -0
- package/test/find-input.test.js +66 -0
- package/test/fixtures/pele-parity.json +1006 -0
- package/test/highlight-launcher.test.js +35 -0
- package/test/html-preview.test.js +22 -0
- package/test/input.test.js +15 -0
- package/test/keymap.test.js +26 -0
- package/test/language-icons.test.js +36 -0
- package/test/launcher.test.js +51 -0
- package/test/manual-archive-here-ui.mjs +47 -0
- package/test/manual-code-scroll.mjs +28 -0
- package/test/manual-column-scroll.mjs +24 -0
- package/test/manual-compare-ui.mjs +20 -0
- package/test/manual-find-status.mjs +37 -0
- package/test/manual-folder-focus.mjs +63 -0
- package/test/manual-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -0
- package/test/manual-terminal-lifecycle.mjs +42 -0
- package/test/manual-terminal-navigation.mjs +48 -0
- package/test/manual-terminal-ui.mjs +47 -0
- package/test/manual-trash-ui.mjs +86 -0
- package/test/markdown-diagrams.test.js +93 -0
- package/test/markdown-html.test.js +105 -0
- package/test/mathml.test.js +92 -0
- package/test/menu-transfer.test.js +57 -0
- package/test/office-preview.test.js +154 -0
- package/test/pele-parity.test.js +28 -0
- package/test/places.test.js +134 -0
- package/test/preview-keys.test.js +60 -0
- package/test/preview-language.test.js +22 -0
- package/test/status-filename.test.js +20 -0
- package/test/transfer-replace-merge.test.js +187 -0
- package/test/trash-address.test.js +23 -0
- package/test/trash-view.test.js +37 -0
- package/test/trashbrowse.test.js +135 -0
- package/ui/AboutFacts.qml +78 -0
- package/ui/ArchiveCards.qml +95 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchiveHereConfirm.qml +127 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +775 -0
- package/ui/BulkOldNames.qml +47 -0
- package/ui/BulkRenameDialog.qml +380 -0
- package/ui/CardFrame.qml +67 -0
- package/ui/CardScroll.qml +79 -0
- package/ui/CheckBox.qml +73 -0
- package/ui/ChromeBar.qml +360 -0
- package/ui/ChromeButton.qml +131 -0
- package/ui/ChromeModes.qml +43 -0
- package/ui/CodeLines.qml +256 -0
- package/ui/CodeRefusal.qml +52 -0
- package/ui/CollideConfirm.qml +147 -0
- package/ui/CollideHost.qml +167 -0
- package/ui/ColumnPane.qml +525 -0
- package/ui/ColumnRow.qml +380 -0
- package/ui/ColumnsArea.qml +594 -0
- package/ui/ColumnsLanding.qml +147 -0
- package/ui/CompareView.qml +321 -0
- package/ui/ContextMenu.qml +743 -0
- package/ui/ConvertDialog.qml +456 -0
- package/ui/CountedWorker.qml +7 -0
- package/ui/Crumb.qml +64 -0
- package/ui/CrumbDrop.qml +25 -0
- package/ui/CsvTable.qml +394 -0
- package/ui/CursorMark.qml +41 -0
- package/ui/DefaultClaim.qml +130 -0
- package/ui/DeviceLock.qml +47 -0
- package/ui/DeviceMounts.qml +540 -0
- package/ui/DialogButton.qml +150 -0
- package/ui/DialogField.qml +147 -0
- package/ui/DialogHeader.qml +31 -0
- package/ui/DialogScrim.qml +20 -0
- package/ui/DialogTitle.qml +37 -0
- package/ui/Divider.qml +9 -0
- package/ui/DropInto.qml +126 -0
- package/ui/DropTarget.qml +35 -0
- package/ui/DropboxMark.qml +60 -0
- package/ui/EmptyState.qml +150 -0
- package/ui/EscapeHint.qml +11 -0
- package/ui/FactsTable.qml +54 -0
- package/ui/FastScrollHandler.qml +476 -0
- package/ui/FatNamesConfirm.qml +157 -0
- package/ui/Favourites.qml +143 -0
- package/ui/FigureService.qml +120 -0
- package/ui/FileDrag.qml +267 -0
- package/ui/FilterStrip.qml +133 -0
- package/ui/FitMetrics.qml +22 -0
- package/ui/FlashDriveRows.qml +137 -0
- package/ui/FlashHost.qml +72 -0
- package/ui/FlashImageRow.qml +104 -0
- package/ui/FlashRunner.qml +119 -0
- package/ui/FlashStepRow.qml +172 -0
- package/ui/FlashStrip.qml +38 -0
- package/ui/FlashView.qml +397 -0
- package/ui/FleaMark.qml +88 -0
- package/ui/FlyoutFade.qml +23 -0
- package/ui/FontPane.qml +170 -0
- package/ui/Glass.qml +114 -0
- package/ui/GlassTagger.qml +59 -0
- package/ui/Glyph.qml +64 -0
- package/ui/GlyphSolid.qml +22 -0
- package/ui/GridArea.qml +664 -0
- package/ui/GridTile.qml +325 -0
- package/ui/GvfsBridge.qml +164 -0
- package/ui/Header.qml +433 -0
- package/ui/HoverTimers.qml +39 -0
- package/ui/HtmlClip.qml +30 -0
- package/ui/HtmlPane.qml +63 -0
- package/ui/HyprlandMark.qml +45 -0
- package/ui/Ipc.qml +1005 -0
- package/ui/IpcControls.qml +7 -0
- package/ui/IpcMenuState.qml +48 -0
- package/ui/IpcPreviewState.qml +185 -0
- package/ui/JumpPath.qml +51 -0
- package/ui/KeymapSheet.qml +561 -0
- package/ui/KeymapSheetResult.qml +89 -0
- package/ui/KindStack.qml +40 -0
- package/ui/LangMark.qml +51 -0
- package/ui/LangMarkLoader.qml +26 -0
- package/ui/List.qml +480 -0
- package/ui/LoadingState.qml +54 -0
- package/ui/LocalSend.qml +56 -0
- package/ui/LocalSendMark.qml +73 -0
- package/ui/MarkdownBlockView.qml +311 -0
- package/ui/MarkdownBlocks.qml +35 -0
- package/ui/MarkdownFigure.qml +254 -0
- package/ui/MarkdownImages.qml +72 -0
- package/ui/MarkdownList.qml +81 -0
- package/ui/MarkdownMathsText.qml +97 -0
- package/ui/MarkdownPane.qml +83 -0
- package/ui/MarkdownPictures.qml +41 -0
- package/ui/MarkdownQuote.qml +52 -0
- package/ui/MarkdownRemote.qml +82 -0
- package/ui/MarkdownSource.qml +155 -0
- package/ui/MarkdownTable.qml +222 -0
- package/ui/MarkdownTableScroll.qml +64 -0
- package/ui/MarkdownTableWheel.qml +126 -0
- package/ui/MarkdownText.qml +87 -0
- package/ui/MarkdownWorker.js +132 -0
- package/ui/MatchText.qml +99 -0
- package/ui/MediaSession.qml +38 -0
- package/ui/MediaSound.qml +26 -0
- package/ui/MediaStrip.qml +191 -0
- package/ui/MediaTrack.qml +36 -0
- package/ui/MediaVolume.qml +54 -0
- package/ui/MenuActionDialog.qml +396 -0
- package/ui/MenuEdgeFade.qml +24 -0
- package/ui/MenuHost.qml +227 -0
- package/ui/MenuRow.qml +351 -0
- package/ui/MountListing.qml +100 -0
- package/ui/NetworkDialog.qml +435 -0
- package/ui/NetworkForm.qml +426 -0
- package/ui/NetworkMounts.qml +913 -0
- package/ui/NetworkPlaces.qml +127 -0
- package/ui/OpenWithDialog.qml +613 -0
- package/ui/Opener.qml +95 -0
- package/ui/Pane.qml +1320 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +268 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +601 -0
- package/ui/ParkedWait.qml +9 -0
- package/ui/PathEntry.qml +186 -0
- package/ui/PathJump.qml +400 -0
- package/ui/PdfViewer.qml +297 -0
- package/ui/PermissionsDialog.qml +658 -0
- package/ui/PermissionsHeadings.qml +31 -0
- package/ui/PhoneMounts.qml +67 -0
- package/ui/PickerAnswers.qml +75 -0
- package/ui/PickerBox.qml +26 -0
- package/ui/PickerChrome.qml +295 -0
- package/ui/PickerFilter.qml +97 -0
- package/ui/PickerGrid.qml +308 -0
- package/ui/PickerHeader.qml +28 -0
- package/ui/PickerLifecycle.qml +27 -0
- package/ui/PickerList.qml +218 -0
- package/ui/PickerListing.qml +149 -0
- package/ui/PickerPathBar.qml +127 -0
- package/ui/PickerPlaces.qml +189 -0
- package/ui/PickerRecent.qml +92 -0
- package/ui/PickerSave.qml +101 -0
- package/ui/PickerSelection.qml +155 -0
- package/ui/PickerWindow.qml +846 -0
- package/ui/PowerSectorsReader.qml +10 -0
- package/ui/PrebuildDriver.qml +146 -0
- package/ui/Preview.qml +1005 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +91 -0
- package/ui/PreviewColumn.qml +553 -0
- package/ui/PreviewEdge.qml +63 -0
- package/ui/PreviewFacts.qml +30 -0
- package/ui/PreviewFactsLine.qml +34 -0
- package/ui/PreviewHtml.qml +233 -0
- package/ui/PreviewImage.qml +253 -0
- package/ui/PreviewImagePan.qml +13 -0
- package/ui/PreviewImageSharp.qml +32 -0
- package/ui/PreviewLines.qml +106 -0
- package/ui/PreviewMarkdown.qml +706 -0
- package/ui/PreviewMedia.qml +250 -0
- package/ui/PreviewPdf.qml +482 -0
- package/ui/PreviewScroll.qml +201 -0
- package/ui/PreviewSwap.qml +335 -0
- package/ui/PreviewText.qml +149 -0
- package/ui/ProtocolChip.qml +18 -0
- package/ui/QuickLookArchive.qml +41 -0
- package/ui/QuickLookBar.qml +103 -0
- package/ui/QuickLookPrepare.qml +355 -0
- package/ui/QuickLookSwap.qml +10 -0
- package/ui/QuickLookWarm.qml +65 -0
- package/ui/RailDrop.qml +155 -0
- package/ui/RailHeading.qml +19 -0
- package/ui/RailPlaces.qml +38 -0
- package/ui/RailTrashRow.qml +67 -0
- package/ui/RenameField.qml +353 -0
- package/ui/RendererRetry.qml +11 -0
- package/ui/ResizeHandle.qml +52 -0
- package/ui/Reveal.qml +54 -0
- package/ui/Row.qml +476 -0
- package/ui/RowDrag.qml +213 -0
- package/ui/RowDropTarget.qml +27 -0
- package/ui/RunCard.qml +286 -0
- package/ui/Scripts.qml +65 -0
- package/ui/SearchStrip.qml +232 -0
- package/ui/SelectionBand.qml +140 -0
- package/ui/SelectionPreview.qml +370 -0
- package/ui/SettingsFavourite.qml +122 -0
- package/ui/SettingsGroup.qml +96 -0
- package/ui/SettingsHint.qml +12 -0
- package/ui/SettingsMetrics.qml +29 -0
- package/ui/SettingsPane.qml +178 -0
- package/ui/SettingsPanel.qml +547 -0
- package/ui/SettingsRail.qml +128 -0
- package/ui/SettingsRow.qml +409 -0
- package/ui/SettingsRuler.qml +85 -0
- package/ui/SettingsSegment.qml +85 -0
- package/ui/ShareBrowser.qml +113 -0
- package/ui/ShareLink.qml +67 -0
- package/ui/ShelfPins.qml +101 -0
- package/ui/Sidebar.qml +728 -0
- package/ui/SidebarRow.qml +358 -0
- package/ui/Spinner.qml +60 -0
- package/ui/StableModel.qml +89 -0
- package/ui/StateMessage.qml +84 -0
- package/ui/StatusBar.qml +512 -0
- package/ui/StatusFileName.qml +27 -0
- package/ui/TabBar.qml +673 -0
- package/ui/TabDragGeometry.qml +60 -0
- package/ui/TagMenuMark.qml +52 -0
- package/ui/TagRailSection.qml +53 -0
- package/ui/TagSlot.qml +40 -0
- package/ui/TagState.qml +150 -0
- package/ui/TagSwatch.qml +28 -0
- package/ui/Taildrop.qml +86 -0
- package/ui/TailscaleMark.qml +50 -0
- package/ui/TerminalService.qml +69 -0
- package/ui/TerminalTab.qml +48 -0
- package/ui/TerminalTabs.qml +27 -0
- package/ui/Theme.qml +460 -0
- package/ui/ThemeColors.qml +43 -0
- package/ui/TransferCard.qml +239 -0
- package/ui/TrashConfirm.qml +129 -0
- package/ui/TrashDropHandler.qml +11 -0
- package/ui/TrashHost.qml +202 -0
- package/ui/TrashMonitor.qml +30 -0
- package/ui/TrashToolbar.qml +19 -0
- package/ui/TrashView.qml +492 -0
- package/ui/UnlockDialog.qml +450 -0
- package/ui/UnlockHost.qml +206 -0
- package/ui/UpdateCheck.qml +97 -0
- package/ui/UserDirs.qml +25 -0
- package/ui/ViewState.qml +565 -0
- package/ui/ViewportScrollBar.qml +195 -0
- package/ui/ViewportScrollBars.qml +25 -0
- package/ui/WebPreview.qml +33 -0
- package/ui/WebPreviewView.qml +26 -0
- package/ui/WindowBody.qml +829 -0
- package/ui/WindowDrag.qml +35 -0
- package/ui/boot/Commons/AudioNodes.qml +50 -0
- package/ui/boot/Commons/AudioNodesModel.js +96 -0
- package/ui/boot/Commons/Border.qml +243 -0
- package/ui/boot/Commons/BorderGeometry.js +373 -0
- package/ui/boot/Commons/Color.qml +258 -0
- package/ui/boot/Commons/I18n.qml +118 -0
- package/ui/boot/Commons/InputDevices.qml +112 -0
- package/ui/boot/Commons/InputMethodState.qml +38 -0
- package/ui/boot/Commons/IpcRegistry.qml +77 -0
- package/ui/boot/Commons/Numbers.js +19 -0
- package/ui/boot/Commons/Plural.js +91 -0
- package/ui/boot/Commons/ShellIpc.qml +12 -0
- package/ui/boot/Commons/Style.qml +561 -0
- package/ui/boot/Commons/Translations.qml +100 -0
- package/ui/boot/Commons/UntypedInput.qml +152 -0
- package/ui/boot/Commons/Util.qml +188 -0
- package/ui/boot/Commons/qmldir +13 -0
- package/ui/boot/LICENSE-omarchy +20 -0
- package/ui/boot/Ui/BackgroundMedia.qml +49 -0
- package/ui/boot/Ui/BarIconButton.qml +106 -0
- package/ui/boot/Ui/BarIconContent.qml +38 -0
- package/ui/boot/Ui/BarIndicator.qml +53 -0
- package/ui/boot/Ui/BarWidget.qml +50 -0
- package/ui/boot/Ui/BorderOverlay.qml +54 -0
- package/ui/boot/Ui/BorderSurface.qml +40 -0
- package/ui/boot/Ui/Button.qml +224 -0
- package/ui/boot/Ui/ButtonGroup.qml +131 -0
- package/ui/boot/Ui/ConfirmDialog.qml +134 -0
- package/ui/boot/Ui/CursorSurface.qml +42 -0
- package/ui/boot/Ui/Dropdown.qml +245 -0
- package/ui/boot/Ui/FilterInput.qml +26 -0
- package/ui/boot/Ui/IconContentBounds.qml +141 -0
- package/ui/boot/Ui/KeyboardPanel.qml +453 -0
- package/ui/boot/Ui/MultiSelect.qml +624 -0
- package/ui/boot/Ui/NumberField.qml +86 -0
- package/ui/boot/Ui/OpticalGlyph.qml +68 -0
- package/ui/boot/Ui/OverlayWindow.qml +102 -0
- package/ui/boot/Ui/Panel.qml +60 -0
- package/ui/boot/Ui/PanelActionButton.qml +105 -0
- package/ui/boot/Ui/PanelController.qml +16 -0
- package/ui/boot/Ui/PanelHero.qml +112 -0
- package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
- package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
- package/ui/boot/Ui/PanelSeparator.qml +19 -0
- package/ui/boot/Ui/PanelSlider.qml +156 -0
- package/ui/boot/Ui/PanelToolTip.qml +50 -0
- package/ui/boot/Ui/PluginBarApi.qml +89 -0
- package/ui/boot/Ui/PointerMoveGate.qml +54 -0
- package/ui/boot/Ui/PopupCard.qml +181 -0
- package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
- package/ui/boot/Ui/SearchableDropdown.qml +354 -0
- package/ui/boot/Ui/SizedImage.qml +125 -0
- package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
- package/ui/boot/Ui/TextField.qml +58 -0
- package/ui/boot/Ui/Toggle.qml +118 -0
- package/ui/boot/Ui/ToggleSwitch.qml +115 -0
- package/ui/boot/Ui/WidgetButton.qml +172 -0
- package/ui/boot/Ui/qmldir +41 -0
- package/ui/boot/fleatab.qml +50 -0
- package/ui/boot/picker.qml +39 -0
- package/ui/boot/shell.qml +131 -0
- package/ui/boot/tabtearoff.qml +51 -0
- package/ui/js/Anchor.js +379 -0
- package/ui/js/AnchorHold.js +162 -0
- package/ui/js/Archive.js +157 -0
- package/ui/js/ArchiveCard.js +44 -0
- package/ui/js/ArchiveOps.js +44 -0
- package/ui/js/BackReturn.js +118 -0
- package/ui/js/BulkRename.js +100 -0
- package/ui/js/Buttons.js +54 -0
- package/ui/js/ChromeKeys.js +116 -0
- package/ui/js/ClipMarks.js +73 -0
- package/ui/js/ClipSelection.js +67 -0
- package/ui/js/Clipboard.js +179 -0
- package/ui/js/Cloud.js +97 -0
- package/ui/js/CodeRuns.js +72 -0
- package/ui/js/Collide.js +212 -0
- package/ui/js/ColumnFit.js +28 -0
- package/ui/js/ColumnMenu.js +111 -0
- package/ui/js/Columns.js +298 -0
- package/ui/js/ColumnsCarry.js +103 -0
- package/ui/js/Compare.js +74 -0
- package/ui/js/Contrast.js +157 -0
- package/ui/js/ControlReader.js +42 -0
- package/ui/js/Convert.js +52 -0
- package/ui/js/CopyAs.js +52 -0
- package/ui/js/Crumbs.js +178 -0
- package/ui/js/Csv.js +231 -0
- package/ui/js/Density.js +44 -0
- package/ui/js/Devices.js +440 -0
- package/ui/js/DirSizes.js +180 -0
- package/ui/js/Drag.js +360 -0
- package/ui/js/DragOut.js +166 -0
- package/ui/js/DropDev.js +52 -0
- package/ui/js/Dropbox.js +41 -0
- package/ui/js/Eject.js +217 -0
- package/ui/js/Errors.js +188 -0
- package/ui/js/ExtThumbs.js +115 -0
- package/ui/js/Facts.js +402 -0
- package/ui/js/FigureDate.js +14 -0
- package/ui/js/Filter.js +285 -0
- package/ui/js/Find.js +46 -0
- package/ui/js/Flash.js +184 -0
- package/ui/js/FlashCard.js +79 -0
- package/ui/js/FlashEndings.js +125 -0
- package/ui/js/FlashPane.js +116 -0
- package/ui/js/FleaBin.js +12 -0
- package/ui/js/Focus.js +504 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +314 -0
- package/ui/js/Fuzzy.js +141 -0
- package/ui/js/GlassTag.js +72 -0
- package/ui/js/Grid.js +33 -0
- package/ui/js/GridGeometry.js +90 -0
- package/ui/js/GridNames.js +153 -0
- package/ui/js/GvfsBridge.js +200 -0
- package/ui/js/HostClipboard.js +29 -0
- package/ui/js/Icons.js +218 -0
- package/ui/js/Input.js +50 -0
- package/ui/js/Jump.js +200 -0
- package/ui/js/KeyName.js +64 -0
- package/ui/js/Keymap.js +401 -0
- package/ui/js/Kinds.js +164 -0
- package/ui/js/LICENSES/ISC-lucide.txt +43 -0
- package/ui/js/LangMarkPaths.js +47 -0
- package/ui/js/LangMarks.js +120 -0
- package/ui/js/Lists.js +11 -0
- package/ui/js/LocalSend.js +39 -0
- package/ui/js/LockedMenu.js +63 -0
- package/ui/js/MakeDefault.js +186 -0
- package/ui/js/MarkBox.js +7 -0
- package/ui/js/Markdown.js +119 -0
- package/ui/js/MarkdownLists.js +86 -0
- package/ui/js/MarkdownMaths.js +58 -0
- package/ui/js/MarkdownPictures.js +32 -0
- package/ui/js/MarkdownPrepared.js +139 -0
- package/ui/js/MarkdownTableFit.js +34 -0
- package/ui/js/Marks.js +148 -0
- package/ui/js/Marquee.js +96 -0
- package/ui/js/Match.js +93 -0
- package/ui/js/Material.js +109 -0
- package/ui/js/MdBlocks.js +437 -0
- package/ui/js/MdBreak.js +71 -0
- package/ui/js/MdChunks.js +70 -0
- package/ui/js/MdContainer.js +137 -0
- package/ui/js/MdDocument.js +337 -0
- package/ui/js/MdEmph.js +97 -0
- package/ui/js/MdEntity.js +108 -0
- package/ui/js/MdEntityTable.js +223 -0
- package/ui/js/MdEscape.js +59 -0
- package/ui/js/MdFront.js +37 -0
- package/ui/js/MdHold.js +32 -0
- package/ui/js/MdHtml.js +307 -0
- package/ui/js/MdHtmlBlock.js +290 -0
- package/ui/js/MdHtmlHeading.js +53 -0
- package/ui/js/MdHtmlImage.js +179 -0
- package/ui/js/MdInline.js +154 -0
- package/ui/js/MdItems.js +212 -0
- package/ui/js/MdLeaf.js +309 -0
- package/ui/js/MdLink.js +196 -0
- package/ui/js/MdMath.js +67 -0
- package/ui/js/MdParagraphs.js +138 -0
- package/ui/js/MdRefs.js +232 -0
- package/ui/js/MdResolve.js +226 -0
- package/ui/js/MdRun.js +300 -0
- package/ui/js/MdUrl.js +226 -0
- package/ui/js/Menu.js +514 -0
- package/ui/js/MenuContext.js +85 -0
- package/ui/js/MenuFit.js +13 -0
- package/ui/js/MenuRefresh.js +74 -0
- package/ui/js/MenuWheel.js +35 -0
- package/ui/js/Messages.js +186 -0
- package/ui/js/Motion.js +16 -0
- package/ui/js/Mounts.js +320 -0
- package/ui/js/MouseNav.js +13 -0
- package/ui/js/Nav.js +329 -0
- package/ui/js/NetFs.js +26 -0
- package/ui/js/OpenWith.js +83 -0
- package/ui/js/Ops.js +585 -0
- package/ui/js/Palette.js +33 -0
- package/ui/js/PathBar.js +260 -0
- package/ui/js/Permissions.js +179 -0
- package/ui/js/Phones.js +112 -0
- package/ui/js/Picker.js +353 -0
- package/ui/js/PlaceMenu.js +96 -0
- package/ui/js/Places.js +265 -0
- package/ui/js/PreviewAsk.js +21 -0
- package/ui/js/PreviewKeys.js +155 -0
- package/ui/js/PreviewSettle.js +29 -0
- package/ui/js/PreviewSwap.js +101 -0
- package/ui/js/PropertyFacts.js +144 -0
- package/ui/js/Protocols.js +296 -0
- package/ui/js/QuickLookKinds.js +27 -0
- package/ui/js/QuickLookRect.js +24 -0
- package/ui/js/RailDrop.js +51 -0
- package/ui/js/RailKeys.js +87 -0
- package/ui/js/RailMenu.js +133 -0
- package/ui/js/Recent.js +135 -0
- package/ui/js/RecentMode.js +156 -0
- package/ui/js/Reload.js +60 -0
- package/ui/js/Renderer.js +9 -0
- package/ui/js/RunFile.js +143 -0
- package/ui/js/Scripts.js +28 -0
- package/ui/js/Scroll.js +304 -0
- package/ui/js/ScrollOff.js +69 -0
- package/ui/js/Search.js +478 -0
- package/ui/js/Selection.js +97 -0
- package/ui/js/Settings.js +476 -0
- package/ui/js/SettingsAbout.js +97 -0
- package/ui/js/SettingsShelf.js +52 -0
- package/ui/js/SheetKeys.js +42 -0
- package/ui/js/SheetQuery.js +281 -0
- package/ui/js/ShelfPile.js +27 -0
- package/ui/js/SlowClick.js +53 -0
- package/ui/js/SlowOp.js +6 -0
- package/ui/js/Sort.js +134 -0
- package/ui/js/Startup.js +63 -0
- package/ui/js/StateWords.js +17 -0
- package/ui/js/Status.js +238 -0
- package/ui/js/Swap.js +166 -0
- package/ui/js/TabMove.js +39 -0
- package/ui/js/Tabs.js +751 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +180 -0
- package/ui/js/TextSize.js +107 -0
- package/ui/js/Thumbs.js +158 -0
- package/ui/js/Transfer.js +172 -0
- package/ui/js/Trash.js +84 -0
- package/ui/js/TrashDates.js +47 -0
- package/ui/js/TrashDrop.js +64 -0
- package/ui/js/UiState.js +438 -0
- package/ui/js/Unlock.js +152 -0
- package/ui/js/Update.js +130 -0
- package/ui/js/UserDirs.js +56 -0
- package/ui/qmldir +230 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
pragma Singleton
|
|
2
|
+
import QtQuick
|
|
3
|
+
import Quickshell
|
|
4
|
+
import Quickshell.Io
|
|
5
|
+
import Quickshell.Services.Pipewire
|
|
6
|
+
import "AudioNodesModel.js" as Model
|
|
7
|
+
|
|
8
|
+
// Volume and mute of the default input when Quickshell gives it no
|
|
9
|
+
// PwNode.audio: Quickshell types only exact media classes, so a virtual source
|
|
10
|
+
// (an Audio/Source/Virtual, such as EasyEffects' or a platform's microphone
|
|
11
|
+
// mapping) has no volume or mute there. They go through wpctl instead, once for
|
|
12
|
+
// the whole shell. Reads and writes name the node by id, a reply for a node no
|
|
13
|
+
// longer tracked is dropped, and writes run one at a time with only the latest
|
|
14
|
+
// volume kept, so a slider drag cannot land on another input later.
|
|
15
|
+
Singleton {
|
|
16
|
+
id: root
|
|
17
|
+
|
|
18
|
+
readonly property var source: Pipewire.defaultAudioSource
|
|
19
|
+
// The default input is untyped, so this drives it.
|
|
20
|
+
readonly property bool active: !!source && !source.audio
|
|
21
|
+
// Every handler reads nodeId itself: a property bound to it could still hold
|
|
22
|
+
// its old value when onNodeIdChanged runs.
|
|
23
|
+
readonly property int nodeId: active ? source.id : -1
|
|
24
|
+
|
|
25
|
+
property bool known: false
|
|
26
|
+
property real volume: 0
|
|
27
|
+
property bool muted: false
|
|
28
|
+
|
|
29
|
+
property int generation: 0
|
|
30
|
+
property int readGeneration: -1
|
|
31
|
+
property bool readAgain: false
|
|
32
|
+
property var pendingVolume: null
|
|
33
|
+
property var pendingMute: null
|
|
34
|
+
|
|
35
|
+
// pactl subscribe is started again when it ends, unless it keeps ending at
|
|
36
|
+
// once (no pipewire-pulse), which would only respawn it forever.
|
|
37
|
+
property real subscribedAt: 0
|
|
38
|
+
property int quickExits: 0
|
|
39
|
+
|
|
40
|
+
onNodeIdChanged: reset()
|
|
41
|
+
Component.onCompleted: reset()
|
|
42
|
+
|
|
43
|
+
function reset() {
|
|
44
|
+
generation++
|
|
45
|
+
known = false
|
|
46
|
+
pendingVolume = null
|
|
47
|
+
pendingMute = null
|
|
48
|
+
quickExits = 0
|
|
49
|
+
events.running = nodeId >= 0
|
|
50
|
+
refresh()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function refresh() {
|
|
54
|
+
if (nodeId < 0) return
|
|
55
|
+
if (reader.running || writer.running) {
|
|
56
|
+
readAgain = true
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
readGeneration = generation
|
|
60
|
+
reader.command = ["wpctl", "get-volume", String(nodeId)]
|
|
61
|
+
reader.running = true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function setVolume(value) {
|
|
65
|
+
if (nodeId < 0) return
|
|
66
|
+
volume = Math.max(0, Math.min(1, value))
|
|
67
|
+
pendingVolume = [String(nodeId), volume.toFixed(2)]
|
|
68
|
+
flush()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function setMuted(value) {
|
|
72
|
+
if (nodeId < 0 || !known) return
|
|
73
|
+
muted = value
|
|
74
|
+
pendingMute = [String(nodeId), value ? "1" : "0"]
|
|
75
|
+
flush()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function flush() {
|
|
79
|
+
if (reader.running || writer.running) return true
|
|
80
|
+
var args = null
|
|
81
|
+
if (pendingMute !== null) {
|
|
82
|
+
args = ["wpctl", "set-mute"].concat(pendingMute)
|
|
83
|
+
pendingMute = null
|
|
84
|
+
} else if (pendingVolume !== null) {
|
|
85
|
+
args = ["wpctl", "set-volume"].concat(pendingVolume)
|
|
86
|
+
pendingVolume = null
|
|
87
|
+
}
|
|
88
|
+
if (!args) return false
|
|
89
|
+
writer.command = args
|
|
90
|
+
writer.running = true
|
|
91
|
+
return true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function settle() {
|
|
95
|
+
if (flush()) return
|
|
96
|
+
if (readAgain) {
|
|
97
|
+
readAgain = false
|
|
98
|
+
refresh()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
Process {
|
|
103
|
+
id: reader
|
|
104
|
+
stdout: StdioCollector {
|
|
105
|
+
waitForEnd: true
|
|
106
|
+
onStreamFinished: {
|
|
107
|
+
var level = Model.parseWpctlVolume(text)
|
|
108
|
+
if (!level || root.nodeId < 0 || root.readGeneration !== root.generation) return
|
|
109
|
+
if (root.pendingVolume !== null || root.pendingMute !== null || writer.running) return
|
|
110
|
+
root.volume = level.volume
|
|
111
|
+
root.muted = level.muted
|
|
112
|
+
root.known = true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
onExited: root.settle()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Process {
|
|
119
|
+
id: writer
|
|
120
|
+
onExited: {
|
|
121
|
+
root.readAgain = true
|
|
122
|
+
root.settle()
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The volume keys, the mute key and other apps change the node too. pactl
|
|
127
|
+
// translates its events, so they are read in the C locale.
|
|
128
|
+
Process {
|
|
129
|
+
id: events
|
|
130
|
+
command: ["pactl", "subscribe"]
|
|
131
|
+
environment: ({ LC_ALL: "C" })
|
|
132
|
+
onRunningChanged: if (running) root.subscribedAt = Date.now()
|
|
133
|
+
onExited: {
|
|
134
|
+
root.quickExits = Date.now() - root.subscribedAt < 1000 ? root.quickExits + 1 : 0
|
|
135
|
+
if (root.nodeId >= 0 && root.quickExits < 5) resubscribe.start()
|
|
136
|
+
}
|
|
137
|
+
stdout: SplitParser {
|
|
138
|
+
onRead: function(line) {
|
|
139
|
+
if (String(line).indexOf(" on source #") !== -1) root.refresh()
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
Timer {
|
|
145
|
+
id: resubscribe
|
|
146
|
+
interval: 2000
|
|
147
|
+
onTriggered: if (root.nodeId >= 0 && !events.running) {
|
|
148
|
+
events.running = true
|
|
149
|
+
root.refresh()
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
pragma Singleton
|
|
2
|
+
import Quickshell
|
|
3
|
+
import QtQuick
|
|
4
|
+
|
|
5
|
+
// Shared utility helpers used across plugins. Pure functions only — no
|
|
6
|
+
// state. Anything stateful belongs on Color, Style, or a service.
|
|
7
|
+
QtObject {
|
|
8
|
+
id: root
|
|
9
|
+
|
|
10
|
+
// Manual click forwarding must honor the same clipping as Qt's hit test.
|
|
11
|
+
// Collapsed drawers keep their children laid out beyond the visible edge.
|
|
12
|
+
function itemContainsPoint(target, source, x, y) {
|
|
13
|
+
if (!target || !target.contains(target.mapFromItem(source, x, y))) return false
|
|
14
|
+
for (var item = target; item; item = item.parent) {
|
|
15
|
+
if (!item.visible || item.opacity === 0 || !item.enabled) return false
|
|
16
|
+
if (item.clip && !item.contains(item.mapFromItem(source, x, y))) return false
|
|
17
|
+
}
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function clamp(value, min, max) {
|
|
22
|
+
var n = Number(value)
|
|
23
|
+
if (!isFinite(n)) return min
|
|
24
|
+
return Math.max(min, Math.min(max, n))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function clampAlpha(value) {
|
|
28
|
+
return clamp(value, 0, 1)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function wheelSteps(accumulator, delta) {
|
|
32
|
+
// Some mouse/compositor combinations scale a single notch well beyond
|
|
33
|
+
// Qt's conventional 120 units. Keep one event to one step while still
|
|
34
|
+
// accumulating the smaller deltas emitted by touchpads.
|
|
35
|
+
delta = Math.max(-120, Math.min(120, delta))
|
|
36
|
+
if (accumulator * delta < 0) accumulator = 0
|
|
37
|
+
var total = accumulator + delta
|
|
38
|
+
var steps = total < 0 ? Math.ceil(total / 120) : Math.floor(total / 120)
|
|
39
|
+
return { steps: steps, remainder: total - steps * 120 }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Compose a base color with an opacity. Accepts a color object or a hex
|
|
43
|
+
// string; null/undefined yields transparent black at the requested alpha.
|
|
44
|
+
function alpha(c, opacity) {
|
|
45
|
+
var a = clampAlpha(opacity)
|
|
46
|
+
if (!c) return Qt.rgba(0, 0, 0, a)
|
|
47
|
+
if (typeof c === "string") c = Qt.color(c)
|
|
48
|
+
return Qt.rgba(c.r, c.g, c.b, a)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// file:// URL with each path segment percent-encoded so spaces and
|
|
52
|
+
// special chars in user paths don't break Image.source.
|
|
53
|
+
function fileUrl(path) {
|
|
54
|
+
if (!path) return ""
|
|
55
|
+
return "file://" + String(path).split("/").map(encodeURIComponent).join("/")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isVideoPath(path) {
|
|
59
|
+
return /\.(mp4|m4v|mov|webm|mkv|avi)$/i.test(String(path || ""))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Single-quote a string for bash. The replace handles embedded single
|
|
63
|
+
// quotes by closing, escaping, and re-opening the literal.
|
|
64
|
+
function shellQuote(value) {
|
|
65
|
+
return "'" + String(value || "").replace(/'/g, "'\\''") + "'"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function execDetached(command) {
|
|
69
|
+
Quickshell.execDetached(["bash", "-lc", command])
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Run an argv vector without a shell interpreting it: the constant `exec "$@"`
|
|
73
|
+
// means the args only ever land in positional parameters, which bash expands
|
|
74
|
+
// without re-tokenizing — so untrusted data ($(id), a filename) stays literal.
|
|
75
|
+
// The login shell (-l) keeps the PATH/session env GUI targets (omasnap, mpv,
|
|
76
|
+
// xdg-open) need. Prefer this over execDetached for anything built from input.
|
|
77
|
+
function execArgv(argv) {
|
|
78
|
+
Quickshell.execDetached(["bash", "-lc", 'exec "$@"', "bash"].concat(argv))
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function isPlainObject(value) {
|
|
82
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function canonicalWidgetId(id) {
|
|
86
|
+
return String(id || "")
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Best-effort base64 decode. Returns "" on parse failure rather than
|
|
90
|
+
// surfacing garbage downstream.
|
|
91
|
+
function decodeBase64(value) {
|
|
92
|
+
var s = String(value || "")
|
|
93
|
+
if (!s) return ""
|
|
94
|
+
try { return Qt.atob(s) } catch (e) { return "" }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function cloneJson(value) {
|
|
98
|
+
return JSON.parse(JSON.stringify(value === undefined ? null : value))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Parse the last line of a custom-module / indicator process output as
|
|
102
|
+
// waybar-style JSON ({text, class, tooltip, ...}). Falls back to {text: raw}
|
|
103
|
+
// when the output isn't JSON, and {} for empty output.
|
|
104
|
+
function parseModuleJson(raw) {
|
|
105
|
+
var text = String(raw || "").trim()
|
|
106
|
+
if (!text) return {}
|
|
107
|
+
var lines = text.split("\n")
|
|
108
|
+
try {
|
|
109
|
+
return JSON.parse(lines[lines.length - 1])
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return { text: text }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Standard Qt text-editing keys shared by every searchable panel's filter:
|
|
116
|
+
// Backspace delete previous character
|
|
117
|
+
// Ctrl+Backspace delete previous word (Qt DeleteStartOfWord)
|
|
118
|
+
// Ctrl+U clear the whole field
|
|
119
|
+
// True only when the event would actually change the text, so an empty
|
|
120
|
+
// filter never swallows the key — panels keep their own empty-filter
|
|
121
|
+
// fallbacks (e.g. menu back-navigation) in later branches.
|
|
122
|
+
// The arrow a horizontal key press means along the reading direction: in a
|
|
123
|
+
// right-to-left layout, mirrored, Left moves forward and Right back. With
|
|
124
|
+
// vim set, h and l count as Left and Right too.
|
|
125
|
+
function readingKey(event, vim) {
|
|
126
|
+
var key = event.key
|
|
127
|
+
if (vim && (key === Qt.Key_H || event.text === "h")) key = Qt.Key_Left
|
|
128
|
+
else if (vim && (key === Qt.Key_L || event.text === "l")) key = Qt.Key_Right
|
|
129
|
+
if (I18n.rightToLeft) {
|
|
130
|
+
if (key === Qt.Key_Left) return Qt.Key_Right
|
|
131
|
+
if (key === Qt.Key_Right) return Qt.Key_Left
|
|
132
|
+
}
|
|
133
|
+
return key
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function editsFilter(event, text) {
|
|
137
|
+
if (!text) return false
|
|
138
|
+
// Alt/Meta-modified sequences belong to other shortcuts — never edit here.
|
|
139
|
+
if (event.modifiers & (Qt.AltModifier | Qt.MetaModifier)) return false
|
|
140
|
+
if (event.key === Qt.Key_U) // Ctrl+U only (not Ctrl+Shift+U → Unicode input)
|
|
141
|
+
return event.modifiers === Qt.ControlModifier
|
|
142
|
+
return event.key === Qt.Key_Backspace // plain, Shift, or Ctrl Backspace
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// New filter text after applying an edit key. Assumes editsFilter(event, text).
|
|
146
|
+
function editedFilter(event, text) {
|
|
147
|
+
if (event.key === Qt.Key_U) return "" // Ctrl+U: clear
|
|
148
|
+
if (event.modifiers & Qt.ControlModifier) // Ctrl+Backspace: word
|
|
149
|
+
return text.replace(/\s+$/, "").replace(/\S+$/, "")
|
|
150
|
+
return text.slice(0, -1) // Backspace: char
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Layout normalization shared by bar config consumers
|
|
154
|
+
// so the two never drift. Entries are deep-cloned to decouple from the
|
|
155
|
+
// input config; consumers can mutate without leaking back to shell.json.
|
|
156
|
+
function normalizeLayoutEntry(entry) {
|
|
157
|
+
if (typeof entry === "string") return { id: canonicalWidgetId(entry) }
|
|
158
|
+
if (isPlainObject(entry) && entry.id) {
|
|
159
|
+
var copy = cloneJson(entry)
|
|
160
|
+
copy.id = canonicalWidgetId(copy.id)
|
|
161
|
+
return copy
|
|
162
|
+
}
|
|
163
|
+
return null
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function normalizeLayoutSection(list) {
|
|
167
|
+
if (!Array.isArray(list)) return []
|
|
168
|
+
var out = []
|
|
169
|
+
for (var i = 0; i < list.length; i++) {
|
|
170
|
+
var e = normalizeLayoutEntry(list[i])
|
|
171
|
+
if (e) out.push(e)
|
|
172
|
+
}
|
|
173
|
+
return out
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// The bar's sections in the order they run along it, and tray, drawn
|
|
177
|
+
// inside the tray's drawer. The center box sits in the middle of the bar;
|
|
178
|
+
// centerBegin and centerEnd hang off its two edges.
|
|
179
|
+
readonly property var barSections: ["left", "centerBegin", "center", "centerEnd", "right", "tray"]
|
|
180
|
+
|
|
181
|
+
function normalizeLayout(layout) {
|
|
182
|
+
var src = isPlainObject(layout) ? layout : {}
|
|
183
|
+
var out = {}
|
|
184
|
+
for (var i = 0; i < barSections.length; i++)
|
|
185
|
+
out[barSections[i]] = normalizeLayoutSection(src[barSections[i]])
|
|
186
|
+
return out
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module qs.Commons
|
|
2
|
+
singleton AudioNodes 1.0 AudioNodes.qml
|
|
3
|
+
singleton Border 1.0 Border.qml
|
|
4
|
+
singleton Color 1.0 Color.qml
|
|
5
|
+
singleton I18n 1.0 I18n.qml
|
|
6
|
+
singleton InputDevices 1.0 InputDevices.qml
|
|
7
|
+
singleton IpcRegistry 1.0 IpcRegistry.qml
|
|
8
|
+
singleton InputMethodState 1.0 InputMethodState.qml
|
|
9
|
+
singleton Style 1.0 Style.qml
|
|
10
|
+
singleton UntypedInput 1.0 UntypedInput.qml
|
|
11
|
+
singleton Util 1.0 Util.qml
|
|
12
|
+
ShellIpc 1.0 ShellIpc.qml
|
|
13
|
+
Translations 1.0 Translations.qml
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) David Heinemeier Hansson
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
|
|
4
|
+
// The shell draws stills only. OWE owns video backgrounds on the desktop, and
|
|
5
|
+
// it feeds the lock screen through its own socket.
|
|
6
|
+
Item {
|
|
7
|
+
id: root
|
|
8
|
+
|
|
9
|
+
property string path: ""
|
|
10
|
+
property int version: 0
|
|
11
|
+
// Unversioned images cache by path. A caller whose version changes with every
|
|
12
|
+
// new file, as the lock's does, may cache too: the version is in the URL.
|
|
13
|
+
property bool cached: version === 0
|
|
14
|
+
// A caller that knows the size its screen needs, in physical pixels, sets
|
|
15
|
+
// constrainDecode and decodeSize. The image then waits for that size rather
|
|
16
|
+
// than decoding at the file's native size first.
|
|
17
|
+
property bool constrainDecode: false
|
|
18
|
+
property size decodeSize: Qt.size(0, 0)
|
|
19
|
+
readonly property var current: imageLoader.item
|
|
20
|
+
readonly property bool ready: current ? current.ready : false
|
|
21
|
+
// The file behind path could not be loaded, as when it was deleted.
|
|
22
|
+
readonly property bool failed: current ? current.failed : false
|
|
23
|
+
readonly property bool video: Util.isVideoPath(path)
|
|
24
|
+
// Cache-bust images selected in a running lock session, so a theme switch
|
|
25
|
+
// that replaces the file behind an unchanged path shows the new pixels.
|
|
26
|
+
readonly property url imageUrl: path && !video ? Util.fileUrl(path) + (version ? "?v=" + version : "") : ""
|
|
27
|
+
|
|
28
|
+
Loader {
|
|
29
|
+
id: imageLoader
|
|
30
|
+
anchors.fill: parent
|
|
31
|
+
active: root.path !== "" && !root.video
|
|
32
|
+
sourceComponent: imageComponent
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Component {
|
|
36
|
+
id: imageComponent
|
|
37
|
+
|
|
38
|
+
Image {
|
|
39
|
+
readonly property bool ready: status === Image.Ready
|
|
40
|
+
readonly property bool failed: status === Image.Error
|
|
41
|
+
source: !root.constrainDecode || root.decodeSize.width > 0 ? root.imageUrl : ""
|
|
42
|
+
fillMode: Image.PreserveAspectCrop
|
|
43
|
+
asynchronous: true
|
|
44
|
+
cache: root.cached
|
|
45
|
+
sourceSize.width: root.constrainDecode ? root.decodeSize.width : (root.version > 0 ? width : 0)
|
|
46
|
+
sourceSize.height: root.constrainDecode ? root.decodeSize.height : (root.version > 0 ? height : 0)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import Quickshell
|
|
3
|
+
import qs.Commons
|
|
4
|
+
|
|
5
|
+
WidgetButton {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
property Component iconComponent: null
|
|
9
|
+
property real slotSize: Style.bar.iconSlot
|
|
10
|
+
property real opticalSize: Style.bar.iconCanvas
|
|
11
|
+
property real iconSize: Math.min(Style.bar.iconSize, opticalSize)
|
|
12
|
+
readonly property real visualIconSize: Style.bar.iconSize
|
|
13
|
+
readonly property real canvasSize: Math.max(visualIconSize, opticalSize)
|
|
14
|
+
property string labelText: ""
|
|
15
|
+
property bool debugOpticalBounds: Quickshell.env("OMARCHY_DEBUG_BAR_ICONS") === "1"
|
|
16
|
+
// A label shifts the icon within the centered group.
|
|
17
|
+
readonly property real opticalCenterErrorX:
|
|
18
|
+
content.x + opticalCanvas.x + (glyph.visible ? glyph.paintedCenterX : customIcon.width / 2 + customIcon.centerErrorX) - root.width / 2
|
|
19
|
+
- (label.visible ? (label.implicitWidth + Style.space(4)) / 2 : 0)
|
|
20
|
+
readonly property real opticalCenterErrorY:
|
|
21
|
+
content.y + (glyph.visible ? glyph.paintedCenterY : customIcon.height / 2 + customIcon.centerErrorY) - root.height / 2
|
|
22
|
+
readonly property real glyphPaintedWidth: glyph.visible ? glyph.paintedWidth : 0
|
|
23
|
+
readonly property real glyphPaintedHeight: glyph.visible ? glyph.paintedHeight : 0
|
|
24
|
+
readonly property real glyphBaselineY: glyph.visible ? glyph.baselineY : 0
|
|
25
|
+
readonly property int glyphFontSize: glyph.visible ? glyph.renderedFontSize : 0
|
|
26
|
+
readonly property real componentPaintedWidth: customIcon.visible ? customIcon.paintedWidth : 0
|
|
27
|
+
readonly property real componentPaintedHeight: customIcon.visible ? customIcon.paintedHeight : 0
|
|
28
|
+
readonly property rect componentSourceBounds: customIcon.sourceBounds
|
|
29
|
+
|
|
30
|
+
labelVisible: false
|
|
31
|
+
hasVisualContent: text !== "" || iconComponent !== null || labelText !== ""
|
|
32
|
+
fontSize: Style.bar.iconFont
|
|
33
|
+
fixedWidth: vertical ? -1 : slotSize
|
|
34
|
+
fixedHeight: vertical ? slotSize : -1
|
|
35
|
+
|
|
36
|
+
Item {
|
|
37
|
+
id: content
|
|
38
|
+
// Exact coordinates preserve the center of odd-width slots.
|
|
39
|
+
x: (root.width - width) / 2
|
|
40
|
+
y: (root.height - height) / 2
|
|
41
|
+
width: root.canvasSize + (label.visible ? label.implicitWidth + Style.space(4) : 0)
|
|
42
|
+
height: root.canvasSize
|
|
43
|
+
|
|
44
|
+
Text {
|
|
45
|
+
id: label
|
|
46
|
+
visible: root.labelText !== ""
|
|
47
|
+
textFormat: Text.PlainText
|
|
48
|
+
text: root.labelText
|
|
49
|
+
font.family: root.fontFamily
|
|
50
|
+
font.pixelSize: root.fontSize
|
|
51
|
+
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
|
|
52
|
+
y: (parent.height - height) / 2
|
|
53
|
+
+ (labelMetrics.descent - labelMetrics.ascent + labelMetrics.tightBoundingRect("0").height) / 2
|
|
54
|
+
renderType: Text.NativeRendering
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
FontMetrics {
|
|
58
|
+
id: labelMetrics
|
|
59
|
+
font: label.font
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Item {
|
|
63
|
+
id: opticalCanvas
|
|
64
|
+
x: label.visible ? label.implicitWidth + Style.space(4) : 0
|
|
65
|
+
width: root.canvasSize
|
|
66
|
+
height: root.canvasSize
|
|
67
|
+
|
|
68
|
+
OpticalGlyph {
|
|
69
|
+
id: glyph
|
|
70
|
+
anchors.fill: parent
|
|
71
|
+
visible: root.iconComponent === null
|
|
72
|
+
text: root.text
|
|
73
|
+
fontFamily: root.fontFamily
|
|
74
|
+
fontSize: root.fontSize
|
|
75
|
+
paintedSize: root.visualIconSize
|
|
76
|
+
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
|
|
77
|
+
rotation: root.textRotation
|
|
78
|
+
debugBounds: root.debugOpticalBounds
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
BarIconContent {
|
|
82
|
+
id: customIcon
|
|
83
|
+
anchors.fill: parent
|
|
84
|
+
visible: root.iconComponent !== null
|
|
85
|
+
sourceComponent: root.iconComponent
|
|
86
|
+
sourceSize: root.opticalSize
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Rectangle {
|
|
90
|
+
visible: root.debugOpticalBounds && root.iconComponent !== null
|
|
91
|
+
anchors.fill: parent
|
|
92
|
+
color: "transparent"
|
|
93
|
+
border.width: 1
|
|
94
|
+
border.color: "#4488ff"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Rectangle {
|
|
100
|
+
visible: root.debugOpticalBounds
|
|
101
|
+
anchors.fill: parent
|
|
102
|
+
color: "transparent"
|
|
103
|
+
border.width: 1
|
|
104
|
+
border.color: "#ff4455"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
|
|
4
|
+
Item {
|
|
5
|
+
id: root
|
|
6
|
+
|
|
7
|
+
property Component sourceComponent: null
|
|
8
|
+
property real sourceSize: Style.bar.iconCanvas
|
|
9
|
+
readonly property rect sourceBounds: bounds.mappedBounds
|
|
10
|
+
readonly property real contentScale: sourceBounds.width > 0 && sourceBounds.height > 0
|
|
11
|
+
? Style.bar.iconSize / Math.max(sourceBounds.width, sourceBounds.height) : 1
|
|
12
|
+
readonly property real paintedWidth: sourceBounds.width * contentScale
|
|
13
|
+
readonly property real paintedHeight: sourceBounds.height * contentScale
|
|
14
|
+
readonly property real centerErrorX: content.x + (sourceBounds.x + sourceBounds.width / 2) * contentScale - width / 2
|
|
15
|
+
readonly property real centerErrorY: content.y + (sourceBounds.y + sourceBounds.height / 2) * contentScale - height / 2
|
|
16
|
+
|
|
17
|
+
Loader {
|
|
18
|
+
id: content
|
|
19
|
+
sourceComponent: root.sourceComponent
|
|
20
|
+
onLoaded: {
|
|
21
|
+
// Keep declared dimensions. Empty wrapper items receive a source canvas.
|
|
22
|
+
if (!(item instanceof Image)) {
|
|
23
|
+
if (item.width <= 0) item.width = Qt.binding(function() { return root.sourceSize })
|
|
24
|
+
if (item.height <= 0) item.height = Qt.binding(function() { return root.sourceSize })
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
transformOrigin: Item.TopLeft
|
|
28
|
+
scale: root.contentScale
|
|
29
|
+
x: root.width / 2 - (root.sourceBounds.x + root.sourceBounds.width / 2) * scale
|
|
30
|
+
y: root.height / 2 - (root.sourceBounds.y + root.sourceBounds.height / 2) * scale
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
IconContentBounds {
|
|
34
|
+
id: bounds
|
|
35
|
+
sourceItem: content.item
|
|
36
|
+
boundsParent: content
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
|
|
4
|
+
BarIconButton {
|
|
5
|
+
id: root
|
|
6
|
+
|
|
7
|
+
property string moduleName: ""
|
|
8
|
+
property var settings: ({})
|
|
9
|
+
property string activeText: ""
|
|
10
|
+
property string inactiveText: activeText
|
|
11
|
+
property string activeTooltipText: ""
|
|
12
|
+
property string inactiveTooltipText: activeTooltipText
|
|
13
|
+
property string indicatorBlock: "single"
|
|
14
|
+
property var indicatorHost: null
|
|
15
|
+
property var activeOverride: null
|
|
16
|
+
// An indicator with nothing to turn on, such as a remote session, shows only
|
|
17
|
+
// while it is active, never among the inactive ones a hover reveals.
|
|
18
|
+
property bool revealWhenInactive: true
|
|
19
|
+
readonly property bool effectiveActive: activeOverride === null || activeOverride === undefined ? active : activeOverride === true
|
|
20
|
+
readonly property bool belongsInBlock: indicatorBlock === "active" ? effectiveActive : (indicatorBlock === "inactive" ? !effectiveActive && revealWhenInactive : true)
|
|
21
|
+
readonly property bool inactiveRevealed: !effectiveActive && revealWhenInactive && !!indicatorHost && indicatorHost.revealInactiveIndicators
|
|
22
|
+
|
|
23
|
+
function extractData(raw) {
|
|
24
|
+
return Util.parseModuleJson(raw)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function syncIndicatorOpacity() {
|
|
28
|
+
root.opacity = !belongsInBlock ? 0 : (effectiveActive ? 1 : (inactiveRevealed ? 0.45 : 0))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Component.onCompleted: syncIndicatorOpacity()
|
|
32
|
+
onActiveChanged: syncIndicatorOpacity()
|
|
33
|
+
onEffectiveActiveChanged: syncIndicatorOpacity()
|
|
34
|
+
onBarChanged: syncIndicatorOpacity()
|
|
35
|
+
onBelongsInBlockChanged: syncIndicatorOpacity()
|
|
36
|
+
onInactiveRevealedChanged: syncIndicatorOpacity()
|
|
37
|
+
onIndicatorBlockChanged: syncIndicatorOpacity()
|
|
38
|
+
|
|
39
|
+
visible: belongsInBlock && (text !== "" || keepSpace)
|
|
40
|
+
text: effectiveActive ? activeText : inactiveText
|
|
41
|
+
tooltipText: effectiveActive ? activeTooltipText : inactiveTooltipText
|
|
42
|
+
keepSpace: true
|
|
43
|
+
dimmed: !effectiveActive
|
|
44
|
+
concealed: !effectiveActive && !inactiveRevealed
|
|
45
|
+
interactive: belongsInBlock && (effectiveActive || indicatorBlock === "inactive" || inactiveRevealed)
|
|
46
|
+
useActiveColor: false
|
|
47
|
+
maintainIndicatorReveal: indicatorBlock === "inactive"
|
|
48
|
+
revealHost: indicatorHost
|
|
49
|
+
horizontalMargin: 5
|
|
50
|
+
verticalPadding: 5
|
|
51
|
+
fixedWidth: vertical ? -1 : Style.bar.statusSlot
|
|
52
|
+
fixedHeight: vertical ? Style.bar.statusSlot : -1
|
|
53
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
|
|
4
|
+
// Base item every bar widget extends. Codifies the properties the bar host
|
|
5
|
+
// injects into each widget slot:
|
|
6
|
+
// bar - the host Bar instance (foreground/background/run/etc).
|
|
7
|
+
// moduleName - widget's canonical id, used by the host registry to look
|
|
8
|
+
// up settings and to disambiguate inline IPC routes.
|
|
9
|
+
// settings - per-widget overrides read from shell.json's layout entry.
|
|
10
|
+
// fixedEdge - the edge of the widget that stays put when it grows:
|
|
11
|
+
// "start" (left, or top on a vertical bar), "end", or
|
|
12
|
+
// "center" when it grows both ways. Content laid out
|
|
13
|
+
// against it stays put while the widget grows.
|
|
14
|
+
//
|
|
15
|
+
// Widgets are free to add their own properties, signals, and child items.
|
|
16
|
+
Item {
|
|
17
|
+
id: root
|
|
18
|
+
|
|
19
|
+
property QtObject bar: null
|
|
20
|
+
property string moduleName: ""
|
|
21
|
+
property var settings: ({})
|
|
22
|
+
property string fixedEdge: "center"
|
|
23
|
+
|
|
24
|
+
// Bar geometry, lifted off the host. Widgets read these constantly to pick
|
|
25
|
+
// between horizontal/vertical layouts; defining them on the base keeps the
|
|
26
|
+
// `bar ? bar.x : fallback` ternary out of every widget body.
|
|
27
|
+
readonly property bool vertical: bar ? bar.vertical : false
|
|
28
|
+
readonly property int barSize: bar ? bar.barSize : Style.bar.sizeHorizontal
|
|
29
|
+
|
|
30
|
+
// Run `method` on every live instance of this widget. An IPC target only
|
|
31
|
+
// ever routes to one handler, but a bar surface exists per monitor, so the
|
|
32
|
+
// instance that owns the target relays the call to its peers — otherwise a
|
|
33
|
+
// refresh would land on a single screen and leave the others stale.
|
|
34
|
+
function broadcast(method) {
|
|
35
|
+
var items = bar && typeof bar.moduleWidgets === "function"
|
|
36
|
+
? bar.moduleWidgets(moduleName) : [root]
|
|
37
|
+
for (var i = 0; i < items.length; i++) {
|
|
38
|
+
if (items[i] && typeof items[i][method] === "function") items[i][method]()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Read a single value from this widget's inline shell.json entry, with a
|
|
43
|
+
// fallback for missing/null values. Every widget that takes user-tunable
|
|
44
|
+
// settings needs this; defining it once on the base keeps the wiring
|
|
45
|
+
// consistent.
|
|
46
|
+
function setting(name, fallback) {
|
|
47
|
+
var value = settings ? settings[name] : undefined
|
|
48
|
+
return value === undefined || value === null ? fallback : value
|
|
49
|
+
}
|
|
50
|
+
}
|