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.
Files changed (637) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +511 -2
  3. package/THIRD-PARTY-NOTICES.md +29 -0
  4. package/demos/App.java +5 -0
  5. package/demos/Dockerfile +4 -0
  6. package/demos/Main.kt +3 -0
  7. package/demos/Program.cs +1 -0
  8. package/demos/README.md +12 -0
  9. package/demos/app.dart +3 -0
  10. package/demos/app.deb +0 -0
  11. package/demos/app.js +1 -0
  12. package/demos/backup.tar +0 -0
  13. package/demos/budget.xlsx +0 -0
  14. package/demos/build.sh +2 -0
  15. package/demos/bundle.zip +0 -0
  16. package/demos/clip.mp4 +0 -0
  17. package/demos/data.sqlite +0 -0
  18. package/demos/disk.iso +0 -0
  19. package/demos/engine.cpp +5 -0
  20. package/demos/firmware.bin +0 -0
  21. package/demos/flake.nix +4 -0
  22. package/demos/folder/inside.txt +1 -0
  23. package/demos/font.ttf +0 -0
  24. package/demos/index.html +5 -0
  25. package/demos/index.php +2 -0
  26. package/demos/init.lua +1 -0
  27. package/demos/letter.docx +0 -0
  28. package/demos/lib.rs +3 -0
  29. package/demos/main.c +6 -0
  30. package/demos/main.h +3 -0
  31. package/demos/math-and-diagrams.md +200 -0
  32. package/demos/notes.tar.gz +0 -0
  33. package/demos/notes.txt +3 -0
  34. package/demos/photo.png +0 -0
  35. package/demos/program +2 -0
  36. package/demos/report.pdf +32 -0
  37. package/demos/script.py +1 -0
  38. package/demos/server.go +7 -0
  39. package/demos/settings.json +4 -0
  40. package/demos/slides.pptx +0 -0
  41. package/demos/song.mp3 +0 -0
  42. package/demos/style.css +4 -0
  43. package/demos/tool.rb +1 -0
  44. package/demos/types.ts +2 -0
  45. package/docs/pele.md +23 -0
  46. package/docs/protocol.md +3420 -0
  47. package/docs/temml.md +63 -0
  48. package/index.js +107 -0
  49. package/package.json +34 -4
  50. package/src/archive.js +407 -0
  51. package/src/archiveops.js +728 -0
  52. package/src/backend.js +369 -0
  53. package/src/bulkrename.js +95 -0
  54. package/src/clip-host.js +76 -0
  55. package/src/clip.js +462 -0
  56. package/src/code.js +168 -0
  57. package/src/compare.js +74 -0
  58. package/src/create.js +128 -0
  59. package/src/dirsize.js +147 -0
  60. package/src/figure-svg.js +530 -0
  61. package/src/figure-thread.js +23 -0
  62. package/src/figure.js +132 -0
  63. package/src/find.js +55 -0
  64. package/src/flea.js +39 -0
  65. package/src/fsinfo.js +39 -0
  66. package/src/highlight.js +141 -0
  67. package/src/html.js +52 -0
  68. package/src/kinds.js +89 -0
  69. package/src/listing.js +130 -0
  70. package/src/markdown-html.js +317 -0
  71. package/src/mathml.js +186 -0
  72. package/src/menu.js +180 -0
  73. package/src/meta.js +135 -0
  74. package/src/office.js +810 -0
  75. package/src/order.js +100 -0
  76. package/src/peek.js +49 -0
  77. package/src/pele-wrapper.js +695 -0
  78. package/src/permissions.js +180 -0
  79. package/src/places.js +313 -0
  80. package/src/preview-language.js +10 -0
  81. package/src/terminal-server.js +95 -0
  82. package/src/terminal-shell.js +26 -0
  83. package/src/transfer.js +669 -0
  84. package/src/trash-record.js +41 -0
  85. package/src/trash.js +210 -0
  86. package/src/trashbrowse.js +327 -0
  87. package/src/uistate.js +393 -0
  88. package/src/uistore.js +168 -0
  89. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  90. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  91. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  92. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  93. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  94. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  95. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  96. package/src/vendor/pele.js +145 -0
  97. package/src/vendor/temml.mjs +14708 -0
  98. package/src/watch.js +98 -0
  99. package/src/wayland/client.js +109 -0
  100. package/src/wayland/protocol.js +55 -0
  101. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  102. package/src/wayland/protocols/wayland.xml +3248 -0
  103. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  104. package/src/wayland/resource-io.js +6 -0
  105. package/src/wayland/socket-discovery.js +26 -0
  106. package/src/wayland/transport-posix.js +120 -0
  107. package/src/wayland/transport-win32.js +11 -0
  108. package/src/wayland/transport.js +3 -0
  109. package/src/wayland/win32-resources.js +80 -0
  110. package/src/wayland/win32-wire.js +62 -0
  111. package/test/archive.test.js +80 -0
  112. package/test/bench-markdown-scroll.mjs +190 -0
  113. package/test/clip-host.test.js +113 -0
  114. package/test/code-preview.test.js +35 -0
  115. package/test/compare-ui-paths.test.js +24 -0
  116. package/test/compare.test.js +54 -0
  117. package/test/delete-trash.test.js +67 -0
  118. package/test/dirsize.test.js +138 -0
  119. package/test/file-ops.test.js +307 -0
  120. package/test/file-url.test.js +24 -0
  121. package/test/find-contents.test.js +161 -0
  122. package/test/find-input.test.js +66 -0
  123. package/test/fixtures/pele-parity.json +1006 -0
  124. package/test/highlight-launcher.test.js +35 -0
  125. package/test/html-preview.test.js +22 -0
  126. package/test/input.test.js +15 -0
  127. package/test/keymap.test.js +26 -0
  128. package/test/language-icons.test.js +36 -0
  129. package/test/launcher.test.js +51 -0
  130. package/test/manual-archive-here-ui.mjs +47 -0
  131. package/test/manual-code-scroll.mjs +28 -0
  132. package/test/manual-column-scroll.mjs +24 -0
  133. package/test/manual-compare-ui.mjs +20 -0
  134. package/test/manual-find-status.mjs +37 -0
  135. package/test/manual-folder-focus.mjs +63 -0
  136. package/test/manual-html-security.mjs +23 -0
  137. package/test/manual-html-ui.mjs +30 -0
  138. package/test/manual-syntax-preview.mjs +26 -0
  139. package/test/manual-terminal-lifecycle.mjs +42 -0
  140. package/test/manual-terminal-navigation.mjs +48 -0
  141. package/test/manual-terminal-ui.mjs +47 -0
  142. package/test/manual-trash-ui.mjs +86 -0
  143. package/test/markdown-diagrams.test.js +93 -0
  144. package/test/markdown-html.test.js +105 -0
  145. package/test/mathml.test.js +92 -0
  146. package/test/menu-transfer.test.js +57 -0
  147. package/test/office-preview.test.js +154 -0
  148. package/test/pele-parity.test.js +28 -0
  149. package/test/places.test.js +134 -0
  150. package/test/preview-keys.test.js +60 -0
  151. package/test/preview-language.test.js +22 -0
  152. package/test/status-filename.test.js +20 -0
  153. package/test/transfer-replace-merge.test.js +187 -0
  154. package/test/trash-address.test.js +23 -0
  155. package/test/trash-view.test.js +37 -0
  156. package/test/trashbrowse.test.js +135 -0
  157. package/ui/AboutFacts.qml +78 -0
  158. package/ui/ArchiveCards.qml +95 -0
  159. package/ui/ArchiveCompressDialog.qml +378 -0
  160. package/ui/ArchiveHereConfirm.qml +127 -0
  161. package/ui/ArchivePasswordDialog.qml +257 -0
  162. package/ui/Backend.qml +775 -0
  163. package/ui/BulkOldNames.qml +47 -0
  164. package/ui/BulkRenameDialog.qml +380 -0
  165. package/ui/CardFrame.qml +67 -0
  166. package/ui/CardScroll.qml +79 -0
  167. package/ui/CheckBox.qml +73 -0
  168. package/ui/ChromeBar.qml +360 -0
  169. package/ui/ChromeButton.qml +131 -0
  170. package/ui/ChromeModes.qml +43 -0
  171. package/ui/CodeLines.qml +256 -0
  172. package/ui/CodeRefusal.qml +52 -0
  173. package/ui/CollideConfirm.qml +147 -0
  174. package/ui/CollideHost.qml +167 -0
  175. package/ui/ColumnPane.qml +525 -0
  176. package/ui/ColumnRow.qml +380 -0
  177. package/ui/ColumnsArea.qml +594 -0
  178. package/ui/ColumnsLanding.qml +147 -0
  179. package/ui/CompareView.qml +321 -0
  180. package/ui/ContextMenu.qml +743 -0
  181. package/ui/ConvertDialog.qml +456 -0
  182. package/ui/CountedWorker.qml +7 -0
  183. package/ui/Crumb.qml +64 -0
  184. package/ui/CrumbDrop.qml +25 -0
  185. package/ui/CsvTable.qml +394 -0
  186. package/ui/CursorMark.qml +41 -0
  187. package/ui/DefaultClaim.qml +130 -0
  188. package/ui/DeviceLock.qml +47 -0
  189. package/ui/DeviceMounts.qml +540 -0
  190. package/ui/DialogButton.qml +150 -0
  191. package/ui/DialogField.qml +147 -0
  192. package/ui/DialogHeader.qml +31 -0
  193. package/ui/DialogScrim.qml +20 -0
  194. package/ui/DialogTitle.qml +37 -0
  195. package/ui/Divider.qml +9 -0
  196. package/ui/DropInto.qml +126 -0
  197. package/ui/DropTarget.qml +35 -0
  198. package/ui/DropboxMark.qml +60 -0
  199. package/ui/EmptyState.qml +150 -0
  200. package/ui/EscapeHint.qml +11 -0
  201. package/ui/FactsTable.qml +54 -0
  202. package/ui/FastScrollHandler.qml +476 -0
  203. package/ui/FatNamesConfirm.qml +157 -0
  204. package/ui/Favourites.qml +143 -0
  205. package/ui/FigureService.qml +120 -0
  206. package/ui/FileDrag.qml +267 -0
  207. package/ui/FilterStrip.qml +133 -0
  208. package/ui/FitMetrics.qml +22 -0
  209. package/ui/FlashDriveRows.qml +137 -0
  210. package/ui/FlashHost.qml +72 -0
  211. package/ui/FlashImageRow.qml +104 -0
  212. package/ui/FlashRunner.qml +119 -0
  213. package/ui/FlashStepRow.qml +172 -0
  214. package/ui/FlashStrip.qml +38 -0
  215. package/ui/FlashView.qml +397 -0
  216. package/ui/FleaMark.qml +88 -0
  217. package/ui/FlyoutFade.qml +23 -0
  218. package/ui/FontPane.qml +170 -0
  219. package/ui/Glass.qml +114 -0
  220. package/ui/GlassTagger.qml +59 -0
  221. package/ui/Glyph.qml +64 -0
  222. package/ui/GlyphSolid.qml +22 -0
  223. package/ui/GridArea.qml +664 -0
  224. package/ui/GridTile.qml +325 -0
  225. package/ui/GvfsBridge.qml +164 -0
  226. package/ui/Header.qml +433 -0
  227. package/ui/HoverTimers.qml +39 -0
  228. package/ui/HtmlClip.qml +30 -0
  229. package/ui/HtmlPane.qml +63 -0
  230. package/ui/HyprlandMark.qml +45 -0
  231. package/ui/Ipc.qml +1005 -0
  232. package/ui/IpcControls.qml +7 -0
  233. package/ui/IpcMenuState.qml +48 -0
  234. package/ui/IpcPreviewState.qml +185 -0
  235. package/ui/JumpPath.qml +51 -0
  236. package/ui/KeymapSheet.qml +561 -0
  237. package/ui/KeymapSheetResult.qml +89 -0
  238. package/ui/KindStack.qml +40 -0
  239. package/ui/LangMark.qml +51 -0
  240. package/ui/LangMarkLoader.qml +26 -0
  241. package/ui/List.qml +480 -0
  242. package/ui/LoadingState.qml +54 -0
  243. package/ui/LocalSend.qml +56 -0
  244. package/ui/LocalSendMark.qml +73 -0
  245. package/ui/MarkdownBlockView.qml +311 -0
  246. package/ui/MarkdownBlocks.qml +35 -0
  247. package/ui/MarkdownFigure.qml +254 -0
  248. package/ui/MarkdownImages.qml +72 -0
  249. package/ui/MarkdownList.qml +81 -0
  250. package/ui/MarkdownMathsText.qml +97 -0
  251. package/ui/MarkdownPane.qml +83 -0
  252. package/ui/MarkdownPictures.qml +41 -0
  253. package/ui/MarkdownQuote.qml +52 -0
  254. package/ui/MarkdownRemote.qml +82 -0
  255. package/ui/MarkdownSource.qml +155 -0
  256. package/ui/MarkdownTable.qml +222 -0
  257. package/ui/MarkdownTableScroll.qml +64 -0
  258. package/ui/MarkdownTableWheel.qml +126 -0
  259. package/ui/MarkdownText.qml +87 -0
  260. package/ui/MarkdownWorker.js +132 -0
  261. package/ui/MatchText.qml +99 -0
  262. package/ui/MediaSession.qml +38 -0
  263. package/ui/MediaSound.qml +26 -0
  264. package/ui/MediaStrip.qml +191 -0
  265. package/ui/MediaTrack.qml +36 -0
  266. package/ui/MediaVolume.qml +54 -0
  267. package/ui/MenuActionDialog.qml +396 -0
  268. package/ui/MenuEdgeFade.qml +24 -0
  269. package/ui/MenuHost.qml +227 -0
  270. package/ui/MenuRow.qml +351 -0
  271. package/ui/MountListing.qml +100 -0
  272. package/ui/NetworkDialog.qml +435 -0
  273. package/ui/NetworkForm.qml +426 -0
  274. package/ui/NetworkMounts.qml +913 -0
  275. package/ui/NetworkPlaces.qml +127 -0
  276. package/ui/OpenWithDialog.qml +613 -0
  277. package/ui/Opener.qml +95 -0
  278. package/ui/Pane.qml +1320 -0
  279. package/ui/PaneMenuActions.qml +527 -0
  280. package/ui/PanePath.qml +90 -0
  281. package/ui/PaneRail.qml +268 -0
  282. package/ui/PaneStates.qml +88 -0
  283. package/ui/PaneSwap.qml +339 -0
  284. package/ui/PaneWire.qml +601 -0
  285. package/ui/ParkedWait.qml +9 -0
  286. package/ui/PathEntry.qml +186 -0
  287. package/ui/PathJump.qml +400 -0
  288. package/ui/PdfViewer.qml +297 -0
  289. package/ui/PermissionsDialog.qml +658 -0
  290. package/ui/PermissionsHeadings.qml +31 -0
  291. package/ui/PhoneMounts.qml +67 -0
  292. package/ui/PickerAnswers.qml +75 -0
  293. package/ui/PickerBox.qml +26 -0
  294. package/ui/PickerChrome.qml +295 -0
  295. package/ui/PickerFilter.qml +97 -0
  296. package/ui/PickerGrid.qml +308 -0
  297. package/ui/PickerHeader.qml +28 -0
  298. package/ui/PickerLifecycle.qml +27 -0
  299. package/ui/PickerList.qml +218 -0
  300. package/ui/PickerListing.qml +149 -0
  301. package/ui/PickerPathBar.qml +127 -0
  302. package/ui/PickerPlaces.qml +189 -0
  303. package/ui/PickerRecent.qml +92 -0
  304. package/ui/PickerSave.qml +101 -0
  305. package/ui/PickerSelection.qml +155 -0
  306. package/ui/PickerWindow.qml +846 -0
  307. package/ui/PowerSectorsReader.qml +10 -0
  308. package/ui/PrebuildDriver.qml +146 -0
  309. package/ui/Preview.qml +1005 -0
  310. package/ui/PreviewAnimation.qml +24 -0
  311. package/ui/PreviewArchive.qml +91 -0
  312. package/ui/PreviewColumn.qml +553 -0
  313. package/ui/PreviewEdge.qml +63 -0
  314. package/ui/PreviewFacts.qml +30 -0
  315. package/ui/PreviewFactsLine.qml +34 -0
  316. package/ui/PreviewHtml.qml +233 -0
  317. package/ui/PreviewImage.qml +253 -0
  318. package/ui/PreviewImagePan.qml +13 -0
  319. package/ui/PreviewImageSharp.qml +32 -0
  320. package/ui/PreviewLines.qml +106 -0
  321. package/ui/PreviewMarkdown.qml +706 -0
  322. package/ui/PreviewMedia.qml +250 -0
  323. package/ui/PreviewPdf.qml +482 -0
  324. package/ui/PreviewScroll.qml +201 -0
  325. package/ui/PreviewSwap.qml +335 -0
  326. package/ui/PreviewText.qml +149 -0
  327. package/ui/ProtocolChip.qml +18 -0
  328. package/ui/QuickLookArchive.qml +41 -0
  329. package/ui/QuickLookBar.qml +103 -0
  330. package/ui/QuickLookPrepare.qml +355 -0
  331. package/ui/QuickLookSwap.qml +10 -0
  332. package/ui/QuickLookWarm.qml +65 -0
  333. package/ui/RailDrop.qml +155 -0
  334. package/ui/RailHeading.qml +19 -0
  335. package/ui/RailPlaces.qml +38 -0
  336. package/ui/RailTrashRow.qml +67 -0
  337. package/ui/RenameField.qml +353 -0
  338. package/ui/RendererRetry.qml +11 -0
  339. package/ui/ResizeHandle.qml +52 -0
  340. package/ui/Reveal.qml +54 -0
  341. package/ui/Row.qml +476 -0
  342. package/ui/RowDrag.qml +213 -0
  343. package/ui/RowDropTarget.qml +27 -0
  344. package/ui/RunCard.qml +286 -0
  345. package/ui/Scripts.qml +65 -0
  346. package/ui/SearchStrip.qml +232 -0
  347. package/ui/SelectionBand.qml +140 -0
  348. package/ui/SelectionPreview.qml +370 -0
  349. package/ui/SettingsFavourite.qml +122 -0
  350. package/ui/SettingsGroup.qml +96 -0
  351. package/ui/SettingsHint.qml +12 -0
  352. package/ui/SettingsMetrics.qml +29 -0
  353. package/ui/SettingsPane.qml +178 -0
  354. package/ui/SettingsPanel.qml +547 -0
  355. package/ui/SettingsRail.qml +128 -0
  356. package/ui/SettingsRow.qml +409 -0
  357. package/ui/SettingsRuler.qml +85 -0
  358. package/ui/SettingsSegment.qml +85 -0
  359. package/ui/ShareBrowser.qml +113 -0
  360. package/ui/ShareLink.qml +67 -0
  361. package/ui/ShelfPins.qml +101 -0
  362. package/ui/Sidebar.qml +728 -0
  363. package/ui/SidebarRow.qml +358 -0
  364. package/ui/Spinner.qml +60 -0
  365. package/ui/StableModel.qml +89 -0
  366. package/ui/StateMessage.qml +84 -0
  367. package/ui/StatusBar.qml +512 -0
  368. package/ui/StatusFileName.qml +27 -0
  369. package/ui/TabBar.qml +673 -0
  370. package/ui/TabDragGeometry.qml +60 -0
  371. package/ui/TagMenuMark.qml +52 -0
  372. package/ui/TagRailSection.qml +53 -0
  373. package/ui/TagSlot.qml +40 -0
  374. package/ui/TagState.qml +150 -0
  375. package/ui/TagSwatch.qml +28 -0
  376. package/ui/Taildrop.qml +86 -0
  377. package/ui/TailscaleMark.qml +50 -0
  378. package/ui/TerminalService.qml +69 -0
  379. package/ui/TerminalTab.qml +48 -0
  380. package/ui/TerminalTabs.qml +27 -0
  381. package/ui/Theme.qml +460 -0
  382. package/ui/ThemeColors.qml +43 -0
  383. package/ui/TransferCard.qml +239 -0
  384. package/ui/TrashConfirm.qml +129 -0
  385. package/ui/TrashDropHandler.qml +11 -0
  386. package/ui/TrashHost.qml +202 -0
  387. package/ui/TrashMonitor.qml +30 -0
  388. package/ui/TrashToolbar.qml +19 -0
  389. package/ui/TrashView.qml +492 -0
  390. package/ui/UnlockDialog.qml +450 -0
  391. package/ui/UnlockHost.qml +206 -0
  392. package/ui/UpdateCheck.qml +97 -0
  393. package/ui/UserDirs.qml +25 -0
  394. package/ui/ViewState.qml +565 -0
  395. package/ui/ViewportScrollBar.qml +195 -0
  396. package/ui/ViewportScrollBars.qml +25 -0
  397. package/ui/WebPreview.qml +33 -0
  398. package/ui/WebPreviewView.qml +26 -0
  399. package/ui/WindowBody.qml +829 -0
  400. package/ui/WindowDrag.qml +35 -0
  401. package/ui/boot/Commons/AudioNodes.qml +50 -0
  402. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  403. package/ui/boot/Commons/Border.qml +243 -0
  404. package/ui/boot/Commons/BorderGeometry.js +373 -0
  405. package/ui/boot/Commons/Color.qml +258 -0
  406. package/ui/boot/Commons/I18n.qml +118 -0
  407. package/ui/boot/Commons/InputDevices.qml +112 -0
  408. package/ui/boot/Commons/InputMethodState.qml +38 -0
  409. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  410. package/ui/boot/Commons/Numbers.js +19 -0
  411. package/ui/boot/Commons/Plural.js +91 -0
  412. package/ui/boot/Commons/ShellIpc.qml +12 -0
  413. package/ui/boot/Commons/Style.qml +561 -0
  414. package/ui/boot/Commons/Translations.qml +100 -0
  415. package/ui/boot/Commons/UntypedInput.qml +152 -0
  416. package/ui/boot/Commons/Util.qml +188 -0
  417. package/ui/boot/Commons/qmldir +13 -0
  418. package/ui/boot/LICENSE-omarchy +20 -0
  419. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  420. package/ui/boot/Ui/BarIconButton.qml +106 -0
  421. package/ui/boot/Ui/BarIconContent.qml +38 -0
  422. package/ui/boot/Ui/BarIndicator.qml +53 -0
  423. package/ui/boot/Ui/BarWidget.qml +50 -0
  424. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  425. package/ui/boot/Ui/BorderSurface.qml +40 -0
  426. package/ui/boot/Ui/Button.qml +224 -0
  427. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  428. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  429. package/ui/boot/Ui/CursorSurface.qml +42 -0
  430. package/ui/boot/Ui/Dropdown.qml +245 -0
  431. package/ui/boot/Ui/FilterInput.qml +26 -0
  432. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  433. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  434. package/ui/boot/Ui/MultiSelect.qml +624 -0
  435. package/ui/boot/Ui/NumberField.qml +86 -0
  436. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  437. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  438. package/ui/boot/Ui/Panel.qml +60 -0
  439. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  440. package/ui/boot/Ui/PanelController.qml +16 -0
  441. package/ui/boot/Ui/PanelHero.qml +112 -0
  442. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  443. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  444. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  445. package/ui/boot/Ui/PanelSlider.qml +156 -0
  446. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  447. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  448. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  449. package/ui/boot/Ui/PopupCard.qml +181 -0
  450. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  451. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  452. package/ui/boot/Ui/SizedImage.qml +125 -0
  453. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  454. package/ui/boot/Ui/TextField.qml +58 -0
  455. package/ui/boot/Ui/Toggle.qml +118 -0
  456. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  457. package/ui/boot/Ui/WidgetButton.qml +172 -0
  458. package/ui/boot/Ui/qmldir +41 -0
  459. package/ui/boot/fleatab.qml +50 -0
  460. package/ui/boot/picker.qml +39 -0
  461. package/ui/boot/shell.qml +131 -0
  462. package/ui/boot/tabtearoff.qml +51 -0
  463. package/ui/js/Anchor.js +379 -0
  464. package/ui/js/AnchorHold.js +162 -0
  465. package/ui/js/Archive.js +157 -0
  466. package/ui/js/ArchiveCard.js +44 -0
  467. package/ui/js/ArchiveOps.js +44 -0
  468. package/ui/js/BackReturn.js +118 -0
  469. package/ui/js/BulkRename.js +100 -0
  470. package/ui/js/Buttons.js +54 -0
  471. package/ui/js/ChromeKeys.js +116 -0
  472. package/ui/js/ClipMarks.js +73 -0
  473. package/ui/js/ClipSelection.js +67 -0
  474. package/ui/js/Clipboard.js +179 -0
  475. package/ui/js/Cloud.js +97 -0
  476. package/ui/js/CodeRuns.js +72 -0
  477. package/ui/js/Collide.js +212 -0
  478. package/ui/js/ColumnFit.js +28 -0
  479. package/ui/js/ColumnMenu.js +111 -0
  480. package/ui/js/Columns.js +298 -0
  481. package/ui/js/ColumnsCarry.js +103 -0
  482. package/ui/js/Compare.js +74 -0
  483. package/ui/js/Contrast.js +157 -0
  484. package/ui/js/ControlReader.js +42 -0
  485. package/ui/js/Convert.js +52 -0
  486. package/ui/js/CopyAs.js +52 -0
  487. package/ui/js/Crumbs.js +178 -0
  488. package/ui/js/Csv.js +231 -0
  489. package/ui/js/Density.js +44 -0
  490. package/ui/js/Devices.js +440 -0
  491. package/ui/js/DirSizes.js +180 -0
  492. package/ui/js/Drag.js +360 -0
  493. package/ui/js/DragOut.js +166 -0
  494. package/ui/js/DropDev.js +52 -0
  495. package/ui/js/Dropbox.js +41 -0
  496. package/ui/js/Eject.js +217 -0
  497. package/ui/js/Errors.js +188 -0
  498. package/ui/js/ExtThumbs.js +115 -0
  499. package/ui/js/Facts.js +402 -0
  500. package/ui/js/FigureDate.js +14 -0
  501. package/ui/js/Filter.js +285 -0
  502. package/ui/js/Find.js +46 -0
  503. package/ui/js/Flash.js +184 -0
  504. package/ui/js/FlashCard.js +79 -0
  505. package/ui/js/FlashEndings.js +125 -0
  506. package/ui/js/FlashPane.js +116 -0
  507. package/ui/js/FleaBin.js +12 -0
  508. package/ui/js/Focus.js +504 -0
  509. package/ui/js/FolderSorts.js +108 -0
  510. package/ui/js/FolderViews.js +44 -0
  511. package/ui/js/Format.js +314 -0
  512. package/ui/js/Fuzzy.js +141 -0
  513. package/ui/js/GlassTag.js +72 -0
  514. package/ui/js/Grid.js +33 -0
  515. package/ui/js/GridGeometry.js +90 -0
  516. package/ui/js/GridNames.js +153 -0
  517. package/ui/js/GvfsBridge.js +200 -0
  518. package/ui/js/HostClipboard.js +29 -0
  519. package/ui/js/Icons.js +218 -0
  520. package/ui/js/Input.js +50 -0
  521. package/ui/js/Jump.js +200 -0
  522. package/ui/js/KeyName.js +64 -0
  523. package/ui/js/Keymap.js +401 -0
  524. package/ui/js/Kinds.js +164 -0
  525. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  526. package/ui/js/LangMarkPaths.js +47 -0
  527. package/ui/js/LangMarks.js +120 -0
  528. package/ui/js/Lists.js +11 -0
  529. package/ui/js/LocalSend.js +39 -0
  530. package/ui/js/LockedMenu.js +63 -0
  531. package/ui/js/MakeDefault.js +186 -0
  532. package/ui/js/MarkBox.js +7 -0
  533. package/ui/js/Markdown.js +119 -0
  534. package/ui/js/MarkdownLists.js +86 -0
  535. package/ui/js/MarkdownMaths.js +58 -0
  536. package/ui/js/MarkdownPictures.js +32 -0
  537. package/ui/js/MarkdownPrepared.js +139 -0
  538. package/ui/js/MarkdownTableFit.js +34 -0
  539. package/ui/js/Marks.js +148 -0
  540. package/ui/js/Marquee.js +96 -0
  541. package/ui/js/Match.js +93 -0
  542. package/ui/js/Material.js +109 -0
  543. package/ui/js/MdBlocks.js +437 -0
  544. package/ui/js/MdBreak.js +71 -0
  545. package/ui/js/MdChunks.js +70 -0
  546. package/ui/js/MdContainer.js +137 -0
  547. package/ui/js/MdDocument.js +337 -0
  548. package/ui/js/MdEmph.js +97 -0
  549. package/ui/js/MdEntity.js +108 -0
  550. package/ui/js/MdEntityTable.js +223 -0
  551. package/ui/js/MdEscape.js +59 -0
  552. package/ui/js/MdFront.js +37 -0
  553. package/ui/js/MdHold.js +32 -0
  554. package/ui/js/MdHtml.js +307 -0
  555. package/ui/js/MdHtmlBlock.js +290 -0
  556. package/ui/js/MdHtmlHeading.js +53 -0
  557. package/ui/js/MdHtmlImage.js +179 -0
  558. package/ui/js/MdInline.js +154 -0
  559. package/ui/js/MdItems.js +212 -0
  560. package/ui/js/MdLeaf.js +309 -0
  561. package/ui/js/MdLink.js +196 -0
  562. package/ui/js/MdMath.js +67 -0
  563. package/ui/js/MdParagraphs.js +138 -0
  564. package/ui/js/MdRefs.js +232 -0
  565. package/ui/js/MdResolve.js +226 -0
  566. package/ui/js/MdRun.js +300 -0
  567. package/ui/js/MdUrl.js +226 -0
  568. package/ui/js/Menu.js +514 -0
  569. package/ui/js/MenuContext.js +85 -0
  570. package/ui/js/MenuFit.js +13 -0
  571. package/ui/js/MenuRefresh.js +74 -0
  572. package/ui/js/MenuWheel.js +35 -0
  573. package/ui/js/Messages.js +186 -0
  574. package/ui/js/Motion.js +16 -0
  575. package/ui/js/Mounts.js +320 -0
  576. package/ui/js/MouseNav.js +13 -0
  577. package/ui/js/Nav.js +329 -0
  578. package/ui/js/NetFs.js +26 -0
  579. package/ui/js/OpenWith.js +83 -0
  580. package/ui/js/Ops.js +585 -0
  581. package/ui/js/Palette.js +33 -0
  582. package/ui/js/PathBar.js +260 -0
  583. package/ui/js/Permissions.js +179 -0
  584. package/ui/js/Phones.js +112 -0
  585. package/ui/js/Picker.js +353 -0
  586. package/ui/js/PlaceMenu.js +96 -0
  587. package/ui/js/Places.js +265 -0
  588. package/ui/js/PreviewAsk.js +21 -0
  589. package/ui/js/PreviewKeys.js +155 -0
  590. package/ui/js/PreviewSettle.js +29 -0
  591. package/ui/js/PreviewSwap.js +101 -0
  592. package/ui/js/PropertyFacts.js +144 -0
  593. package/ui/js/Protocols.js +296 -0
  594. package/ui/js/QuickLookKinds.js +27 -0
  595. package/ui/js/QuickLookRect.js +24 -0
  596. package/ui/js/RailDrop.js +51 -0
  597. package/ui/js/RailKeys.js +87 -0
  598. package/ui/js/RailMenu.js +133 -0
  599. package/ui/js/Recent.js +135 -0
  600. package/ui/js/RecentMode.js +156 -0
  601. package/ui/js/Reload.js +60 -0
  602. package/ui/js/Renderer.js +9 -0
  603. package/ui/js/RunFile.js +143 -0
  604. package/ui/js/Scripts.js +28 -0
  605. package/ui/js/Scroll.js +304 -0
  606. package/ui/js/ScrollOff.js +69 -0
  607. package/ui/js/Search.js +478 -0
  608. package/ui/js/Selection.js +97 -0
  609. package/ui/js/Settings.js +476 -0
  610. package/ui/js/SettingsAbout.js +97 -0
  611. package/ui/js/SettingsShelf.js +52 -0
  612. package/ui/js/SheetKeys.js +42 -0
  613. package/ui/js/SheetQuery.js +281 -0
  614. package/ui/js/ShelfPile.js +27 -0
  615. package/ui/js/SlowClick.js +53 -0
  616. package/ui/js/SlowOp.js +6 -0
  617. package/ui/js/Sort.js +134 -0
  618. package/ui/js/Startup.js +63 -0
  619. package/ui/js/StateWords.js +17 -0
  620. package/ui/js/Status.js +238 -0
  621. package/ui/js/Swap.js +166 -0
  622. package/ui/js/TabMove.js +39 -0
  623. package/ui/js/Tabs.js +751 -0
  624. package/ui/js/Tags.js +134 -0
  625. package/ui/js/Taildrop.js +128 -0
  626. package/ui/js/Tap.js +180 -0
  627. package/ui/js/TextSize.js +107 -0
  628. package/ui/js/Thumbs.js +158 -0
  629. package/ui/js/Transfer.js +172 -0
  630. package/ui/js/Trash.js +84 -0
  631. package/ui/js/TrashDates.js +47 -0
  632. package/ui/js/TrashDrop.js +64 -0
  633. package/ui/js/UiState.js +438 -0
  634. package/ui/js/Unlock.js +152 -0
  635. package/ui/js/Update.js +130 -0
  636. package/ui/js/UserDirs.js +56 -0
  637. package/ui/qmldir +230 -0
@@ -0,0 +1,150 @@
1
+ import QtQuick
2
+ import "js/Motion.js" as Motion
3
+
4
+ // The empty-directory touch: the operator's mark above a rotating caption, matched exact off /usr/share/omarchy/shell/Ui/PanelHero.qml and the tailscale/airpods phraseTimer pair (see AGENTS.md for the quoted values); visibility and geometry come from the caller (ui/shell.qml) via Pane's listingState and listArea.
5
+ Item {
6
+ id: root
7
+
8
+ property int messageIndex: 0
9
+ // A fixed caption with its own mark, for a state that is not "this directory is empty": the
10
+ // search's no-match answer names the query, so the rotation would be wrong there.
11
+ property string caption: ""
12
+ property string mark: ""
13
+ // Sentence case, not uppercased: the rotating caption is OEM all-caps; this is the next action.
14
+ property string hint: ""
15
+ // The hero mark alone, for ui/Ipc.qml's painted-pixel count: the hint would light the wider rectangle.
16
+ readonly property alias markItem: heroMark
17
+ readonly property alias captionItem: caption
18
+ // Sentence case, matching the OEM's activePhrases; caption.text below uppercases at render, like PanelHero, not in the source.
19
+ readonly property var messages: [
20
+ "Nothing here yet",
21
+ "A very tidy folder",
22
+ "Not a file in sight",
23
+ "Quiet in here",
24
+ "No clutter to report",
25
+ "Waiting for something to land",
26
+ "Empty, and that is fine"
27
+ ]
28
+ // The OEM phraseTimer's own interval, tailscale's and airpods' Panel.qml.
29
+ readonly property int rotateMs: 2800
30
+ // PanelHero's own secondary ink, the metadata role, not the row's muted one.
31
+ readonly property color dim: Theme.color.metadata
32
+ // A data-held folder skips this for one landing, so it draws whole like the picture hold did.
33
+ property bool animateEntrance: true
34
+
35
+ // The widest the hero draws, the longest rotating phrase included, so ui/PaneStates.qml places it once per state.
36
+ readonly property real naturalWidth: Math.max(root.hint.length > 0 ? hintText.implicitWidth : 0,
37
+ root.caption.length > 0 ? caption.implicitWidth : root.widestPhrase(phraseFace.font))
38
+
39
+ FontMetrics { id: phraseFace; font: caption.font }
40
+ // face is read only so a font change re-measures, as GridTile's caption marks do.
41
+ function widestPhrase(face) {
42
+ return root.messages.reduce(function (widest, phrase) {
43
+ return Math.max(widest, phraseFace.advanceWidth(phrase.toUpperCase()))
44
+ }, 0)
45
+ }
46
+
47
+ // Entrance only: the caller (shell.qml) cuts visible straight to false on the way out, so
48
+ // this only ever animates the appear direction, never a disappearance.
49
+ opacity: root.visible ? 1 : 0
50
+
51
+ Behavior on opacity {
52
+ id: entranceOpacity
53
+ enabled: root.animateEntrance && root.visible && !Theme.reducedMotion
54
+ NumberAnimation { duration: Motion.durMs.open; easing.type: Easing.OutCubic }
55
+ }
56
+
57
+ Column {
58
+ id: content
59
+ anchors.centerIn: parent
60
+ anchors.verticalCenterOffset: root.visible ? 0 : Motion.translateUpPx
61
+ spacing: Theme.spacing.gap
62
+
63
+ Behavior on anchors.verticalCenterOffset {
64
+ id: entranceOffset
65
+ enabled: root.animateEntrance && root.visible && !Theme.reducedMotion
66
+ NumberAnimation { duration: Motion.durMs.open; easing.type: Easing.OutCubic }
67
+ }
68
+
69
+ FleaMark {
70
+ id: heroMark
71
+ visible: root.caption.length === 0
72
+ anchors.horizontalCenter: parent.horizontalCenter
73
+ // The brand moment, which States.dc.html draws at 48; four row heights was 148.
74
+ width: Theme.heroMarkSize
75
+ height: Theme.heroMarkSize
76
+ }
77
+
78
+ Glyph {
79
+ visible: root.caption.length > 0
80
+ anchors.horizontalCenter: parent.horizontalCenter
81
+ // A search that found nothing is a failure to find, not an arrival: Search.dc.html draws 40.
82
+ maxSize: Theme.stateMarkSize
83
+ width: Theme.stateMarkSize
84
+ height: Theme.stateMarkSize
85
+ name: root.mark
86
+ color: Theme.color.metadataFrame
87
+ }
88
+
89
+ Text {
90
+ id: caption
91
+ anchors.horizontalCenter: parent.horizontalCenter
92
+ text: (root.caption.length > 0 ? root.caption : root.messages[root.messageIndex]).toUpperCase()
93
+ color: root.caption.length > 0 ? root.dim : Theme.color.foreground
94
+ font.family: Theme.font.family
95
+ font.pixelSize: Theme.font.caption
96
+ font.bold: true
97
+ font.letterSpacing: 1.2
98
+ textFormat: Text.PlainText
99
+ }
100
+
101
+ Text {
102
+ id: hintText
103
+ visible: root.hint.length > 0
104
+ anchors.horizontalCenter: parent.horizontalCenter
105
+ text: root.hint
106
+ color: root.dim
107
+ font.family: Theme.font.family
108
+ font.pixelSize: Theme.font.caption
109
+ textFormat: Text.PlainText
110
+ }
111
+ }
112
+
113
+ // Three beats per appearance, then rest on the third phrase with the mark drawn: an endless rotation kept a core 12% busy.
114
+ readonly property int beatLimit: 3
115
+ property int beats: 0
116
+ // Rest is no beat left with the fade stopped and the mark drawn whole; reduced motion and a fixed caption keep no beat, so the fade and the opacity gate those.
117
+ readonly property bool atRest: Theme.reducedMotion || (!fade.running && root.opacity === 1 && (root.caption.length > 0 || (root.beats >= root.beatLimit && heroMark.settled)))
118
+ onVisibleChanged: root.beats = 0
119
+
120
+ // root.visible mirrors the caller's listingState === "empty" gate, so the rotation timer stops once a real listing arrives.
121
+ Timer {
122
+ interval: root.rotateMs
123
+ running: root.visible && root.caption.length === 0 && !Theme.reducedMotion && root.beats < root.beatLimit
124
+ repeat: true
125
+ // One beat for both, per the operator: the mark repaints as the sentence changes.
126
+ onTriggered: { root.beats += 1; fade.restart(); heroMark.replay() }
127
+ }
128
+
129
+ // The OEM's phraseSwap order (tailscale's and airpods' Panel.qml): fade out, swap the index, fade in, on Flea's OutCubic and Motion durations.
130
+ SequentialAnimation {
131
+ id: fade
132
+ PropertyAnimation { target: caption; property: "opacity"; to: 0.0; duration: Motion.durMs.close; easing.type: Easing.OutCubic }
133
+ ScriptAction { script: root.messageIndex = (root.messageIndex + 1) % root.messages.length }
134
+ PropertyAnimation { target: caption; property: "opacity"; to: 1.0; duration: Motion.durMs.open; easing.type: Easing.OutCubic }
135
+ }
136
+ Connections {
137
+ target: Theme
138
+ function onReducedMotionChanged() {
139
+ if (Theme.reducedMotion) {
140
+ // Disabling a Behavior leaves its current animation running until the next property write.
141
+ entranceOpacity.enabled = Qt.binding(function() { return root.animateEntrance && root.visible && !Theme.reducedMotion })
142
+ entranceOffset.enabled = Qt.binding(function() { return root.animateEntrance && root.visible && !Theme.reducedMotion })
143
+ root.opacity = Qt.binding(function() { return root.visible ? 1 : 0 })
144
+ content.anchors.verticalCenterOffset = Qt.binding(function() { return root.visible ? 0 : Motion.translateUpPx })
145
+ fade.stop()
146
+ caption.opacity = 1
147
+ }
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,11 @@
1
+ import QtQuick
2
+
3
+ // The word that closes a surface, in the corner every surface puts it in: Dialogs rule 7, and the
4
+ // spelling ui/SettingsPanel.qml already uses, so no two dialogs can name the way out differently.
5
+ Text {
6
+ text: "esc"
7
+ color: Theme.color.muted
8
+ font.family: Theme.font.family
9
+ font.pixelSize: Theme.font.caption
10
+ textFormat: Text.PlainText
11
+ }
@@ -0,0 +1,54 @@
1
+ import QtQuick
2
+
3
+ // The caption-type table under every preview state's frame, one label and value pair a row. Every
4
+ // value starts at the same x in all twelve states, which is what makes them read as one anatomy.
5
+ Column {
6
+ id: root
7
+
8
+ // { label, value } pairs, as ui/js/Facts.js facts and multiFacts build them.
9
+ property var rows: []
10
+
11
+ spacing: Theme.spacing.hairline * 3
12
+
13
+ // The widest label the twelve states use, by advanceWidth because width drops the trailing gutter space.
14
+ readonly property int labelWidth: labelMetrics.advanceWidth
15
+
16
+ TextMetrics {
17
+ id: labelMetrics
18
+ font.family: Theme.font.family
19
+ font.pixelSize: Theme.font.caption
20
+ text: "Points at "
21
+ }
22
+
23
+ Repeater {
24
+ model: root.rows
25
+
26
+ delegate: Item {
27
+ required property var modelData
28
+ width: root.width
29
+ height: Math.round(Theme.font.caption * 1.5)
30
+
31
+ Text {
32
+ id: factLabel
33
+ anchors.left: parent.left
34
+ width: root.labelWidth
35
+ text: modelData.label
36
+ color: Theme.color.muted
37
+ font.family: Theme.font.family
38
+ font.pixelSize: Theme.font.caption
39
+ textFormat: Text.PlainText
40
+ }
41
+
42
+ Text {
43
+ anchors.left: factLabel.right
44
+ anchors.right: parent.right
45
+ text: modelData.value
46
+ color: Theme.color.foreground
47
+ font.family: Theme.font.family
48
+ font.pixelSize: Theme.font.caption
49
+ textFormat: Text.PlainText
50
+ elide: Text.ElideRight
51
+ }
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,476 @@
1
+ import QtQuick
2
+ import "js/Scroll.js" as Scroll
3
+ import "js/Motion.js" as Motion
4
+ import "js/MenuWheel.js" as MenuWheel
5
+
6
+ // A MouseArea because Flickable eats wheel before a child WheelHandler; presses pass through, arithmetic in Scroll.js.
7
+ MouseArea {
8
+ id: root
9
+ objectName: "fleaScroll"
10
+
11
+ required property var flickable
12
+ property var ctrlWheelAction: null
13
+ property bool tailRunning: false
14
+ property bool returnRunning: false
15
+ // A menu highlight steps here; null everywhere else, so pixel scrolling is untouched.
16
+ property bool stepMode: false
17
+ property real stepRowHeight: 0
18
+ property var stepBy: null
19
+ property real stepAccum: 0
20
+ // The notch remainder in raw angleDelta units and the phaseless-pixel remainder in raw
21
+ // pixels; both reset when the menu opens, so one menu never spends another's travel.
22
+ property real notchAccum: 0
23
+ property real pixelAccum: 0
24
+
25
+ function resetSteps() {
26
+ root.stepAccum = 0
27
+ root.notchAccum = 0
28
+ root.pixelAccum = 0
29
+ }
30
+
31
+ // Field names per axis, built once so each routine serves both in the order of the pair it replaces.
32
+ readonly property var axisY: ({ pos: "contentY", last: "lastY", over: "overY", vel: "vy", size: "height", limits: Scroll.limitsY })
33
+ readonly property var axisX: ({ pos: "contentX", last: "lastX", over: "overX", vel: "vx", size: "width", limits: Scroll.limitsX })
34
+
35
+ anchors.fill: parent
36
+ acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
37
+ propagateComposedEvents: true
38
+ z: 1000
39
+
40
+ function scrollDistance(pixelDelta, angleDelta) {
41
+ return Scroll.distance(pixelDelta, angleDelta, Application.styleHints.wheelScrollLines,
42
+ Theme.scroll.notchPx, Theme.scroll.multiplier)
43
+ }
44
+
45
+ function tailActive() {
46
+ var found = Scroll.tailState(root.flickable, false)
47
+ return found !== null && found.active
48
+ }
49
+
50
+ function stopTail() {
51
+ Scroll.stopTail(root.flickable)
52
+ root.tailRunning = false
53
+ if (root.flickable)
54
+ root.flickable.cancelFlick()
55
+ }
56
+
57
+ function returnActive() {
58
+ var found = Scroll.tailState(root.flickable, false)
59
+ return found !== null && found.retActive
60
+ }
61
+
62
+ // An axis the view cannot scroll takes no delta at all.
63
+ function scrollsX() {
64
+ var f = root.flickable
65
+ if (!f || f.flickableDirection === Flickable.VerticalFlick)
66
+ return false
67
+ return Scroll.rangesX(f)
68
+ }
69
+ function scrollsY() {
70
+ var f = root.flickable
71
+ if (!f || f.flickableDirection === Flickable.HorizontalFlick)
72
+ return false
73
+ return Scroll.rangesY(f)
74
+ }
75
+
76
+ // Any foreign write ends the return; a press holds it instead of snapping to the bound.
77
+ function stopReturn(snap) {
78
+ var f = root.flickable
79
+ if (!f) {
80
+ root.returnRunning = false
81
+ return
82
+ }
83
+ var found = Scroll.tailState(f, false)
84
+ if (found !== null) {
85
+ found.retActive = false
86
+ found.retElapsed = 0
87
+ found.overY = 0
88
+ found.overX = 0
89
+ }
90
+ root.returnRunning = false
91
+ if (snap) {
92
+ var ly = Scroll.limitsY(f)
93
+ var lx = Scroll.limitsX(f)
94
+ var ty = Math.max(ly.min, Math.min(ly.max, f.contentY))
95
+ var tx = Math.max(lx.min, Math.min(lx.max, f.contentX))
96
+ if (ty !== f.contentY || tx !== f.contentX) {
97
+ var live = Scroll.tailState(f, true)
98
+ live.lastY = ty
99
+ live.lastX = tx
100
+ f.contentY = ty
101
+ f.contentX = tx
102
+ f.cancelFlick()
103
+ }
104
+ }
105
+ }
106
+
107
+ function overscrolled() {
108
+ var found = Scroll.tailState(root.flickable, false)
109
+ if (found !== null && (found.overY !== 0 || found.overX !== 0))
110
+ return true
111
+ var f = root.flickable
112
+ var ly = Scroll.limitsY(f)
113
+ var lx = Scroll.limitsX(f)
114
+ return f.contentY < ly.min - 0.01 || f.contentY > ly.max + 0.01
115
+ || f.contentX < lx.min - 0.01 || f.contentX > lx.max + 0.01
116
+ }
117
+
118
+ function writeAxis(value, ax) {
119
+ var f = root.flickable
120
+ var lim = ax.limits(f)
121
+ var at = Math.max(lim.min, Math.min(lim.max, value))
122
+ Scroll.tailState(f, true)[ax.last] = at
123
+ f[ax.pos] = at
124
+ }
125
+
126
+ function writeRawAxis(at, ax) {
127
+ Scroll.tailState(root.flickable, true)[ax.last] = at
128
+ root.flickable[ax.pos] = at
129
+ }
130
+
131
+ // Banks raw travel past the bound and returns the rubber-band spot; the first overshoot banks its raw travel.
132
+ function bankOver(st, lim, want, dim, ax) {
133
+ var below = want < lim.min
134
+ var beyond = below ? lim.min - want : want - lim.max
135
+ var prev = Math.abs(st[ax.over])
136
+ var acc = prev === 0 ? beyond : prev + Math.max(0, beyond - Scroll.overResist(prev, dim))
137
+ st[ax.over] = below ? -acc : acc
138
+ var shown = Scroll.overResist(acc, dim)
139
+ return below ? lim.min - shown : lim.max + shown
140
+ }
141
+
142
+ // Past the bound travel resists; banked travel from a swapped listing is dropped.
143
+ function touchAxis(delta, ax) {
144
+ var f = root.flickable
145
+ var lim = ax.limits(f)
146
+ var st = Scroll.tailState(f, true)
147
+ if (st[ax.over] !== 0 && f[ax.pos] >= lim.min - 0.01 && f[ax.pos] <= lim.max + 0.01)
148
+ st[ax.over] = 0
149
+ var d = Math.max(1, f[ax.size])
150
+ if (st[ax.over] === 0) {
151
+ var want = f[ax.pos] - delta
152
+ if (want >= lim.min && want <= lim.max)
153
+ writeAxis(want, ax)
154
+ else
155
+ writeRawAxis(bankOver(st, lim, want, d, ax), ax)
156
+ return
157
+ }
158
+ var m = Math.abs(st[ax.over])
159
+ var below = st[ax.over] < 0
160
+ var nm = below ? m + delta : m - delta
161
+ if (nm <= 0) {
162
+ var inside = below ? lim.min + (-nm) : lim.max + nm
163
+ st[ax.over] = 0
164
+ writeAxis(inside, ax)
165
+ return
166
+ }
167
+ var shown = Scroll.overResist(nm, d)
168
+ st[ax.over] = below ? -nm : nm
169
+ writeRawAxis(st[ax.over] < 0 ? lim.min - shown : lim.max + shown, ax)
170
+ }
171
+
172
+ // A past-bound lift returns on Omarchy's duration, at once under reduced motion.
173
+ function startReturn() {
174
+ var f = root.flickable
175
+ if (!f)
176
+ return
177
+ var st = Scroll.tailState(f, true)
178
+ var ly = Scroll.limitsY(f)
179
+ var lx = Scroll.limitsX(f)
180
+ var needY = f.contentY < ly.min - 0.01 || f.contentY > ly.max + 0.01
181
+ var needX = f.contentX < lx.min - 0.01 || f.contentX > lx.max + 0.01
182
+ if (!needY && !needX) {
183
+ st.overY = 0
184
+ st.overX = 0
185
+ root.returnRunning = false
186
+ return
187
+ }
188
+ var toY = f.contentY < ly.min ? ly.min : (f.contentY > ly.max ? ly.max : f.contentY)
189
+ var toX = f.contentX < lx.min ? lx.min : (f.contentX > lx.max ? lx.max : f.contentX)
190
+ if (Theme.reducedMotion) {
191
+ st.overY = 0
192
+ st.overX = 0
193
+ st.retActive = false
194
+ root.returnRunning = false
195
+ st.lastY = toY
196
+ st.lastX = toX
197
+ f.contentY = toY
198
+ f.contentX = toX
199
+ f.cancelFlick()
200
+ return
201
+ }
202
+ st.retFromY = f.contentY
203
+ st.retToY = toY
204
+ st.retFromX = f.contentX
205
+ st.retToX = toX
206
+ st.retElapsed = 0
207
+ st.retDur = Motion.durMs.open
208
+ st.retActive = true
209
+ st.overY = 0
210
+ st.overX = 0
211
+ root.returnRunning = true
212
+ }
213
+
214
+ // One frame of the return; the FrameAnimation below and the headless probe both enter here.
215
+ function advanceReturn(dtMs) {
216
+ var found = Scroll.tailState(root.flickable, false)
217
+ if (found === null || !found.retActive) {
218
+ root.returnRunning = false
219
+ return 0
220
+ }
221
+ var dt = Math.max(0, Number(dtMs) || 0)
222
+ if (dt <= 0)
223
+ return 0
224
+ found.retElapsed += dt
225
+ var ny = Scroll.returnAt(found.retFromY, found.retToY, found.retElapsed, found.retDur)
226
+ var nx = Scroll.returnAt(found.retFromX, found.retToX, found.retElapsed, found.retDur)
227
+ var moved = Math.abs(ny - root.flickable.contentY) + Math.abs(nx - root.flickable.contentX)
228
+ found.lastY = ny
229
+ found.lastX = nx
230
+ root.flickable.contentY = ny
231
+ root.flickable.contentX = nx
232
+ if (found.retElapsed >= found.retDur) {
233
+ found.retActive = false
234
+ found.overY = 0
235
+ found.overX = 0
236
+ root.returnRunning = false
237
+ }
238
+ return moved
239
+ }
240
+
241
+ // One axis of a tail frame; the caller runs Y before X. Returns the distance moved.
242
+ function advanceOne(found, step, dt, ax) {
243
+ if (step.dx === 0)
244
+ return 0
245
+ var f = root.flickable
246
+ var before = f[ax.pos]
247
+ var want = before - step.dx
248
+ var lim = ax.limits(f)
249
+ if (want >= lim.min && want <= lim.max) {
250
+ writeAxis(want, ax)
251
+ if (f[ax.pos] === before) {
252
+ found[ax.vel] = 0
253
+ return 0
254
+ }
255
+ return Math.abs(f[ax.pos] - before)
256
+ }
257
+ // The frame's raw travel joins the banked total shown through resistance.
258
+ var at = bankOver(found, lim, want, Math.max(1, f[ax.size]), ax)
259
+ found[ax.vel] = Scroll.overDecel(found[ax.vel], dt)
260
+ writeRawAxis(at, ax)
261
+ return Math.abs(f[ax.pos] - before)
262
+ }
263
+
264
+ // Past the bound the tail integrates through stroke resistance and brakes to a peak.
265
+ function advanceTail(dtMs) {
266
+ var found = Scroll.tailState(root.flickable, false)
267
+ if (found === null || !found.active) {
268
+ root.tailRunning = false
269
+ return 0
270
+ }
271
+ var dt = Math.max(0, Number(dtMs) || 0)
272
+ if (dt <= 0)
273
+ return 0
274
+ var stepY = Scroll.tailStep(found.vy, dt)
275
+ var stepX = Scroll.tailStep(found.vx, dt)
276
+ found.vy = stepY.v
277
+ found.vx = stepX.v
278
+ var moved = advanceOne(found, stepY, dt, root.axisY) + advanceOne(found, stepX, dt, root.axisX)
279
+ if (!Scroll.tailLive(found.vx, found.vy)) {
280
+ found.active = false
281
+ found.vx = 0
282
+ found.vy = 0
283
+ root.tailRunning = false
284
+ if (root.overscrolled())
285
+ root.startReturn()
286
+ }
287
+ return moved
288
+ }
289
+
290
+ function startTail() {
291
+ var found = Scroll.tailState(root.flickable, true)
292
+ if (found.overY !== 0 || found.overX !== 0)
293
+ return
294
+ // A repeated End carries no new samples, so it never stops a live tail.
295
+ if (found.samples.length === 0 && found.active)
296
+ return
297
+ var v = Scroll.liftVelocity(found.samples, Scroll.now())
298
+ found.samples = []
299
+ if (v.vx === 0 && v.vy === 0) {
300
+ found.active = false
301
+ root.tailRunning = false
302
+ return
303
+ }
304
+ found.vx = v.vx
305
+ found.vy = v.vy
306
+ found.active = true
307
+ root.tailRunning = true
308
+ }
309
+
310
+ function stepRows(steps) {
311
+ for (var i = 0; i < Math.abs(steps); i++)
312
+ root.stepBy(steps > 0 ? 1 : -1)
313
+ }
314
+
315
+ // Menu step: one row a notch of angleDelta, one row per row height of touchpad travel or phaseless pixels, no tail, always consumed.
316
+ function stepWheel(wheel, phase) {
317
+ if (Scroll.isTouchpad(phase)) {
318
+ if (phase === Qt.ScrollBegin)
319
+ root.stepAccum = 0
320
+ var folded = MenuWheel.touchSteps(root.stepAccum, Scroll.touchDistance(wheel.pixelDelta.y),
321
+ root.stepRowHeight)
322
+ root.stepAccum = folded.rest
323
+ stepRows(folded.steps)
324
+ return true
325
+ }
326
+ if (Scroll.movesByPixels(phase, wheel.pixelDelta.y, wheel.angleDelta.y)) {
327
+ var held = MenuWheel.touchSteps(root.pixelAccum, Number(wheel.pixelDelta.y), root.stepRowHeight)
328
+ root.pixelAccum = held.rest
329
+ stepRows(held.steps)
330
+ return true
331
+ }
332
+ var notched = MenuWheel.notchSteps(root.notchAccum, Number(wheel.angleDelta.y) || 0)
333
+ root.notchAccum = notched.rest
334
+ stepRows(notched.steps)
335
+ return true
336
+ }
337
+
338
+ function handleWheel(wheel) {
339
+ var phase = wheel.phase !== undefined ? wheel.phase : Qt.NoScrollPhase
340
+ if (root.stepMode && root.stepBy !== null) {
341
+ wheel.accepted = root.stepWheel(wheel, phase)
342
+ return wheel.accepted
343
+ }
344
+ if ((wheel.modifiers & Qt.ControlModifier) && root.ctrlWheelAction !== null) {
345
+ wheel.accepted = root.ctrlWheelAction(wheel)
346
+ if (wheel.accepted) {
347
+ root.stopTail()
348
+ root.stopReturn(true)
349
+ return true
350
+ }
351
+ }
352
+ if (Scroll.isTouchpad(phase)) {
353
+ // A new stroke ends the old tail; an End never stops a live tail on one view.
354
+ if (phase === Qt.ScrollBegin) {
355
+ root.stopTail()
356
+ root.stopReturn(true)
357
+ // The Begin carries no pixels and anchors the lift's span.
358
+ Scroll.pushSample(root.flickable, Scroll.now(), 0, 0)
359
+ } else if (phase !== Qt.ScrollEnd && root.tailActive()) {
360
+ root.stopTail()
361
+ } else if (root.returnActive()) {
362
+ root.stopReturn(true)
363
+ }
364
+ var down = Scroll.touchDistance(wheel.pixelDelta.y)
365
+ var across = Scroll.touchDistance(wheel.pixelDelta.x)
366
+ // A dead axis takes no delta, so samples and overscroll never name it.
367
+ if (!root.scrollsY())
368
+ down = 0
369
+ if (!root.scrollsX())
370
+ across = 0
371
+ if ((down === 0 && across === 0) || !root.flickable.interactive) {
372
+ if (phase === Qt.ScrollEnd && root.flickable.interactive) {
373
+ // An accepted End stops at the first handler, so a second one never kills its tail.
374
+ // Left unaccepted, the view snaps to the bound in the same delivery and kills the return.
375
+ if (root.overscrolled()) {
376
+ root.startReturn()
377
+ wheel.accepted = true
378
+ return true
379
+ }
380
+ root.startTail()
381
+ if (root.tailActive()) {
382
+ wheel.accepted = true
383
+ return true
384
+ }
385
+ }
386
+ wheel.accepted = false
387
+ return false
388
+ }
389
+ Scroll.pushSample(root.flickable, Scroll.now(), across, down)
390
+ var previousY = root.flickable.contentY
391
+ var previousX = root.flickable.contentX
392
+ root.flickable.cancelFlick()
393
+ if (down !== 0)
394
+ touchAxis(down, root.axisY)
395
+ // A tilt or a diagonal touchpad stroke pans a content wider than the view, a zoomed PDF page.
396
+ if (across !== 0)
397
+ touchAxis(across, root.axisX)
398
+ wheel.accepted = Scroll.moved(previousY, root.flickable.contentY) || Scroll.moved(previousX, root.flickable.contentX)
399
+ if (phase === Qt.ScrollEnd) {
400
+ if (root.overscrolled())
401
+ root.startReturn()
402
+ else
403
+ root.startTail()
404
+ // A tail started here is accepted above by movement, or here when nothing moved.
405
+ if (root.tailActive())
406
+ wheel.accepted = true
407
+ }
408
+ return wheel.accepted
409
+ }
410
+ if (root.tailActive())
411
+ root.stopTail()
412
+ if (root.returnActive())
413
+ root.stopReturn(true)
414
+ var notchDown = root.scrollDistance(wheel.pixelDelta.y, wheel.angleDelta.y)
415
+ var notchAcross = root.scrollDistance(wheel.pixelDelta.x, wheel.angleDelta.x)
416
+ if ((notchDown === 0 && notchAcross === 0) || !root.flickable.interactive) {
417
+ wheel.accepted = false
418
+ return false
419
+ }
420
+ var notchY = root.flickable.contentY
421
+ var notchX = root.flickable.contentX
422
+ root.flickable.cancelFlick()
423
+ if (notchDown !== 0)
424
+ writeAxis(notchY - notchDown, root.axisY)
425
+ if (notchAcross !== 0)
426
+ writeAxis(notchX - notchAcross, root.axisX)
427
+ wheel.accepted = Scroll.moved(notchY, root.flickable.contentY) || Scroll.moved(notchX, root.flickable.contentX)
428
+ return wheel.accepted
429
+ }
430
+
431
+ // A wheel is the operator moving the view, ahead of the write it makes.
432
+ signal wheeled()
433
+ onWheel: function (wheel) { root.wheeled(); root.handleWheel(wheel) }
434
+ // A press stops the tail and the return where they are for the row Qt picked; left
435
+ // unaccepted it takes no grab, so the view's own release fixup returns the held overscroll.
436
+ function handlePress(mouse) { root.stopTail(); root.stopReturn(false); mouse.accepted = false }
437
+ onPressed: function (mouse) { root.handlePress(mouse) }
438
+
439
+ Connections {
440
+ target: root.flickable
441
+ // Any content write the tail or the return did not make ends it: showCursor, restore,
442
+ // cursor keys, the band. Each records every value it writes, so any other value is another.
443
+ function onContentYChanged() {
444
+ var found = Scroll.tailState(root.flickable, false)
445
+ if (found === null)
446
+ return
447
+ if (found.active && root.flickable.contentY !== found.lastY)
448
+ root.stopTail()
449
+ else if (found.retActive && root.flickable.contentY !== found.lastY)
450
+ root.stopReturn(false)
451
+ }
452
+ function onContentXChanged() {
453
+ var found = Scroll.tailState(root.flickable, false)
454
+ if (found === null)
455
+ return
456
+ if (found.active && root.flickable.contentX !== found.lastX)
457
+ root.stopTail()
458
+ else if (found.retActive && root.flickable.contentX !== found.lastX)
459
+ root.stopReturn(false)
460
+ }
461
+ function onMovementStarted() { root.stopTail(); root.stopReturn(true) }
462
+ }
463
+
464
+ FrameAnimation {
465
+ running: root.tailRunning || root.returnRunning
466
+ // frameTime is seconds; both animations integrate milliseconds.
467
+ onTriggered: {
468
+ if (root.tailRunning)
469
+ root.advanceTail(frameTime * 1000)
470
+ else if (root.returnRunning)
471
+ root.advanceReturn(frameTime * 1000)
472
+ }
473
+ }
474
+
475
+ Component.onDestruction: Scroll.forgetTail(root.flickable)
476
+ }