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,23 @@
1
+ import QtQuick
2
+
3
+ // A context menu's flyout fade, built by its first flyout; it holds the flyout's rows, place and action at their last open values while it fades out.
4
+ QtObject {
5
+ id: root
6
+
7
+ required property var menu
8
+
9
+ property Reveal reveal: Reveal { target: root.menu.submenuFrameItem; shown: root.menu.submenuOpen }
10
+ // The rows are copied while the flyout is open, on a change of its entries or of its openness, never by a Binding: that one re-reads the emptied rows of a closing flyout before its own `when` goes false.
11
+ property Connections heldRows: Connections {
12
+ target: root.menu
13
+ function onSubmenuEntriesChanged() { root.holdRows() }
14
+ function onSubmenuOpenChanged() { root.holdRows() }
15
+ }
16
+ property Binding heldOffset: Binding { target: root.menu; property: "heldOffset"; value: root.menu.submenuOffset(); when: root.menu.submenuOpen; restoreMode: Binding.RestoreNone }
17
+ property Binding heldAction: Binding { target: root.menu; property: "heldAction"; value: root.menu.submenuAction(); when: root.menu.submenuOpen; restoreMode: Binding.RestoreNone }
18
+
19
+ function holdRows() {
20
+ if (root.menu.submenuOpen) root.menu.heldRows = root.menu.submenuEntries
21
+ }
22
+ Component.onCompleted: root.holdRows()
23
+ }
@@ -0,0 +1,170 @@
1
+ pragma ComponentBehavior: Bound
2
+ import QtQuick
3
+ import "." as Flea
4
+ import "js/Kinds.js" as Kinds
5
+ import "js/Ops.js" as Ops
6
+
7
+ // The font page: Quick Look's bar, the sample at three sizes and the facts line, all drawn in the frame the backend's answer lands in.
8
+ Item {
9
+ id: root
10
+
11
+ property bool active: false
12
+ property string path: ""
13
+ property int size: 0
14
+ property var backend: null
15
+
16
+ signal closeRequested
17
+
18
+ // "loading" until the answer, "font" once the page draws, and the unsupported sentence for a font the backend refused.
19
+ readonly property string status: root.failed ? "This file cannot be previewed." : (root.drawn ? "font" : "loading")
20
+ readonly property bool drawn: root.look !== null && root.look.path === root.path
21
+ readonly property bool failed: root.failedPath === root.path
22
+ property string failedPath: ""
23
+ // The last good answer. A theme change asks again and the old images stay up until the new three replace them at once.
24
+ property var look: null
25
+ property int pending: 0
26
+ // The path the pending ask carried, so an answer is read against its own request and not the path at answer time.
27
+ property string pendingPath: ""
28
+ property string askedKey: ""
29
+
30
+ // The board's sizes before the text-size ratio, then the pixels the image is drawn with at this window's pixel ratio.
31
+ readonly property real ratio: Screen.devicePixelRatio
32
+ readonly property var physical: Kinds.SAMPLE_SIZES.map(function (px) { return Math.round(Math.round(px * Theme.sizeRatio) * root.ratio) })
33
+ readonly property string fg: root.hex(Theme.color.foreground)
34
+ // The card's own colour, so the images carry no box of another one.
35
+ readonly property string bg: root.hex(Theme.color.surface)
36
+ readonly property string askKey: root.active && root.path !== "" && root.backend !== null
37
+ ? [root.path, root.fg, root.bg, root.physical.join(",")].join("\n") : ""
38
+ readonly property string factsLine: root.drawn
39
+ ? Kinds.fontLine(root.look.message.family || "", root.look.message.style || "", root.size, root.look.message.glyphs || 0, Ops.pluralWord) : ""
40
+
41
+ function hex(c) {
42
+ return "#" + [c.r, c.g, c.b].map(function (v) { return ("0" + Math.round(v * 255).toString(16)).slice(-2) }).join("")
43
+ }
44
+ // A theme load moves the surface before the foreground, so the ask goes out once from a zero timer, never with a mixed palette.
45
+ onAskKeyChanged: askTimer.restart()
46
+
47
+ Timer {
48
+ id: askTimer
49
+ interval: 0
50
+ onTriggered: root.ask()
51
+ }
52
+
53
+ // The id comes from one count shared by every font pane, so an older answer is dropped even across a Loader rebuild.
54
+ function ask() {
55
+ if (root.askKey === "" || root.askKey === root.askedKey) return
56
+ root.askedKey = root.askKey
57
+ root.pending = Kinds.nextLookId()
58
+ root.pendingPath = root.path
59
+ root.backend.send({ c: "fontlook", id: root.pending, path: root.path, fg: root.fg, bg: root.bg, sizes: root.physical, text: Kinds.SAMPLE_TEXT })
60
+ }
61
+
62
+ Connections {
63
+ target: root.backend
64
+ function onFontLooked(message) {
65
+ if (message.id !== root.pending) return
66
+ if (message.err) {
67
+ root.failedPath = root.pendingPath
68
+ // The old page goes with a refusal, so it never draws beside the unsupported state.
69
+ root.look = null
70
+ } else {
71
+ root.failedPath = ""
72
+ root.look = { path: root.pendingPath, message: message }
73
+ }
74
+ }
75
+ }
76
+
77
+ // Until the answer Quick Look draws its loading state, so the bar, the images and the facts never appear apart.
78
+ visible: root.drawn
79
+
80
+ // No fill of its own: Quick Look's surface is already the chrome colour and rounds the corners this bar sits under.
81
+ Item {
82
+ id: bar
83
+ anchors.top: parent.top
84
+ anchors.left: parent.left
85
+ anchors.right: parent.right
86
+ height: Theme.chromeHeight
87
+
88
+ Rectangle {
89
+ anchors.bottom: parent.bottom
90
+ anchors.left: parent.left
91
+ anchors.right: parent.right
92
+ height: Theme.spacing.hairline
93
+ color: Theme.color.foreground
94
+ opacity: 0.12
95
+ }
96
+
97
+ Flea.Glyph {
98
+ id: barMark
99
+ anchors.left: parent.left
100
+ anchors.leftMargin: Theme.spacing.rowPaddingX
101
+ y: Math.round((parent.height - Theme.spacing.hairline - height) / 2)
102
+ width: Theme.chromeMarkSize
103
+ height: Theme.chromeMarkSize
104
+ name: "type"
105
+ color: Theme.color.foreground
106
+ }
107
+
108
+ // corner: a filename is arbitrary text, so PlainText, the same rule every name on this surface follows.
109
+ Text {
110
+ id: barName
111
+ anchors.left: barMark.right
112
+ anchors.leftMargin: Theme.spacing.gap
113
+ anchors.verticalCenter: parent.verticalCenter
114
+ width: Math.min(implicitWidth, Math.max(0, barClose.x - x - 2 * Theme.spacing.gap))
115
+ text: root.path.substring(root.path.lastIndexOf("/") + 1)
116
+ color: Theme.color.foreground
117
+ font.family: Theme.font.family
118
+ font.pixelSize: Theme.font.caption
119
+ textFormat: Text.PlainText
120
+ elide: Text.ElideMiddle
121
+ }
122
+
123
+ Flea.ChromeButton {
124
+ id: barClose
125
+ gesturePolicy: TapHandler.ReleaseWithinBounds
126
+ ruleRows: Theme.spacing.hairline
127
+ anchors.right: parent.right
128
+ anchors.rightMargin: Theme.spacing.rowPaddingX
129
+ anchors.verticalCenter: parent.verticalCenter
130
+ glyph: "x"
131
+ accessName: "Close"
132
+ onActivated: root.closeRequested()
133
+ }
134
+ }
135
+
136
+ // One left-aligned column, centred between the bar and the foot, 24 px above and below and 40 px at the sides.
137
+ Column {
138
+ id: page
139
+ x: Math.round(40 * Theme.sizeRatio)
140
+ width: parent.width - 2 * x
141
+ y: bar.height + Math.max(Math.round(24 * Theme.sizeRatio), Math.round((parent.height - bar.height - height) / 2))
142
+ spacing: Math.round(18 * Theme.sizeRatio)
143
+
144
+ Repeater {
145
+ model: root.drawn ? Kinds.SAMPLE_SIZES.length : 0
146
+ // Drawn at its logical size from its own pixels, so a fractional pixel ratio leaves it unscaled.
147
+ Image {
148
+ id: sample
149
+ required property int index
150
+ source: "file://" + root.look.message.files[sample.index]
151
+ width: sample.implicitWidth / root.ratio
152
+ height: sample.implicitHeight / root.ratio
153
+ fillMode: Image.Pad
154
+ smooth: false
155
+ cache: false
156
+ }
157
+ }
158
+
159
+ Text {
160
+ width: parent.width
161
+ text: root.factsLine
162
+ color: Theme.color.muted
163
+ font.family: Theme.font.family
164
+ font.pixelSize: Theme.font.caption
165
+ font.features: { "tnum": 1 }
166
+ textFormat: Text.PlainText
167
+ elide: Text.ElideRight
168
+ }
169
+ }
170
+ }
package/ui/Glass.qml ADDED
@@ -0,0 +1,114 @@
1
+ pragma Singleton
2
+ import QtQuick
3
+ import Quickshell
4
+ import Quickshell.Io
5
+ import qs.Commons
6
+ import qs.Commons as Commons
7
+ import "js/Material.js" as Material
8
+
9
+ // shell.toml's [flea] background-alpha through Omarchy's reader, and Omarchy's Window Transparency mode: one plane per pixel, content opaque; AGENTS.md "Theme roles and sources".
10
+ QtObject {
11
+ id: root
12
+
13
+ readonly property string key: "flea.background-alpha"
14
+ // Pick candidate A: match Nautilus's 0.75 ground, lifting text rather than fading it like window opacity does.
15
+ property real glassAlpha: root.mode === "glassy" && root.usesDefault ? Material.floor(Theme.color.opaquePalette, Theme.textContrast) / 255 : 1
16
+ property bool focused: Qt.application.active
17
+ readonly property bool split: true
18
+ readonly property bool usesDefault: root.valueIn(Commons.Color.userShellValues) < 0 && root.valueIn(Commons.Color.themeShellValues) < 0
19
+ // "opaque", "glassy" or "transparent" (Omarchy's default), read from its toggle files by reread().
20
+ property string mode: "transparent"
21
+ property bool hasOpaque: false
22
+ property bool hasGlassy: false
23
+ // Set once by launch(), before the window exists, because a Wayland surface's format is fixed at creation.
24
+ property bool clear: false
25
+ // In whole 8-bit steps, so a value that rounds to 1 is 1; a launch a [flea] value pins opaque holds 1 until the next launch.
26
+ readonly property real alpha: root.clear ? root.stepped(root.wanted()) : 1
27
+ // False keeps every plane on its own opaque role, so a stock theme draws exactly what it drew before.
28
+ readonly property bool on: root.alpha < 1
29
+ readonly property color background: root.on ? Util.alpha(Theme.color.background, root.alpha) : Theme.color.background
30
+ readonly property color surface: root.on ? Util.alpha(Theme.color.surface, root.alpha) : Theme.color.surface
31
+ readonly property real listAlpha: root.on && root.usesDefault && root.mode === "glassy" && root.split ? Math.max(root.alpha, Material.listFloor(Theme.color.opaquePalette, Theme.textContrast) / 255) : root.alpha
32
+ readonly property color listBackground: root.on ? Util.alpha(Theme.color.background, root.listAlpha) : Theme.color.background
33
+
34
+ readonly property string toggleDir: (Quickshell.env("XDG_STATE_HOME") || Quickshell.env("HOME") + "/.local/state") + "/omarchy/toggles/hypr"
35
+ // A file test and not omarchy-hyprland-window-transparency, which needs OMARCHY_PATH that ssh and some launchers lack.
36
+ property FileView opaqueFile: FileView {
37
+ path: root.toggleDir + "/window-opaque.lua"
38
+ printErrors: false
39
+ onLoaded: root.hasOpaque = true
40
+ onLoadFailed: root.hasOpaque = false
41
+ }
42
+ property FileView glassyFile: FileView {
43
+ path: root.toggleDir + "/window-glassy.lua"
44
+ printErrors: false
45
+ onLoaded: root.hasGlassy = true
46
+ onLoadFailed: root.hasGlassy = false
47
+ }
48
+ // Hyprland reloads its config for a Window Transparency change, with no theme switch.
49
+ property Connections reloads: Connections {
50
+ target: Theme
51
+ function onConfigReloaded() { root.reread(); root.retag() }
52
+ function onFleaWindowOpened() { root.startTagger() }
53
+ }
54
+ // Only inside Hyprland, as ui/Theme.qml's event hookup: a headless run has no compositor to ask.
55
+ readonly property bool inHyprland: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE") !== null
56
+ // ui/GlassTagger.qml, made when Hyprland opens the first Flea window, so it costs nothing before the first rows.
57
+ property QtObject tagger: null
58
+ onModeChanged: root.retag()
59
+ onUsesDefaultChanged: root.retag()
60
+
61
+ // Sample input: 0.34 answers 87/255, 0.999 answers 1.
62
+ function stepped(value) { return Math.round(value * 255) / 255 }
63
+
64
+ // One shell.toml's value: -1 when it sets none, the clamped number, or 1 for what is not a number.
65
+ function valueIn(values) {
66
+ var v = values ? values[root.key] : undefined
67
+ if (typeof v !== "string" || v.length === 0) return -1
68
+ var n = Number(v)
69
+ return isFinite(n) ? Util.clampAlpha(n) : 1
70
+ }
71
+ // User and theme values keep their precedence; bare Transparent is opaque: no shipped theme sets an opacity of its own, and no toggle file means transparency was never chosen.
72
+ function wanted() {
73
+ var user = root.valueIn(Commons.Color.userShellValues)
74
+ if (user >= 0) return user
75
+ if (root.mode === "opaque") return 1
76
+ var theme = root.valueIn(Commons.Color.themeShellValues)
77
+ if (theme >= 0) return theme
78
+ return root.mode === "glassy" ? root.glassAlpha : 1
79
+ }
80
+
81
+ function reread() {
82
+ root.opaqueFile.reload()
83
+ root.glassyFile.reload()
84
+ root.opaqueFile.waitForJob()
85
+ root.glassyFile.waitForJob()
86
+ root.mode = root.hasGlassy ? "glassy" : root.hasOpaque ? "opaque" : "transparent"
87
+ }
88
+
89
+ // A [flea] value that pins 1 keeps an opaque surface; every other launch is made clear, so each Window Transparency switch shows live.
90
+ function pinsOpaque() {
91
+ var user = root.valueIn(Commons.Color.userShellValues)
92
+ if (user >= 0) return root.stepped(user) >= 1
93
+ var theme = root.valueIn(Commons.Color.themeShellValues)
94
+ return theme >= 0 && root.stepped(theme) >= 1
95
+ }
96
+
97
+ // Color's two shell readers load asynchronously; waiting here lands both before the decision.
98
+ function launch() {
99
+ Commons.Color.shellFile.waitForJob()
100
+ Commons.Color.userShellFile.waitForJob()
101
+ root.reread()
102
+ root.clear = !root.pinsOpaque()
103
+ }
104
+
105
+ function startTagger() {
106
+ if (!root.inHyprland) return
107
+ if (!root.tagger) root.tagger = Qt.createComponent("GlassTagger.qml").createObject(root, {
108
+ mode: Qt.binding(function () { return root.mode }),
109
+ usesDefault: Qt.binding(function () { return root.usesDefault })
110
+ })
111
+ root.retag()
112
+ }
113
+ function retag() { if (root.tagger) root.tagger.retag() }
114
+ }
@@ -0,0 +1,59 @@
1
+ import QtQuick
2
+ import Quickshell
3
+ import Quickshell.Io
4
+ import "js/GlassTag.js" as GlassTag
5
+
6
+ // Omarchy's Transparent mode is Hyprland's to draw: a Flea window Hyprland leaves at 1 takes the transparency hotkey's tag, so no alpha stacks.
7
+ // ui/Glass.qml makes this when Hyprland opens the first Flea window, after the first rows, and binds the mode to it.
8
+ QtObject {
9
+ id: root
10
+
11
+ property string mode: "transparent"
12
+ property bool usesDefault: true
13
+ // The addresses this process tagged, so a tag the user set with the hotkey is never taken away.
14
+ property var tagged: ({})
15
+ // A request that lands mid-run waits this long and asks again, until every process has finished.
16
+ readonly property int rerunGapMs: 100
17
+ readonly property bool busy: root.clients.running || root.props.running || root.tags.running
18
+
19
+ property Process clients: Process {
20
+ command: ["hyprctl", "clients", "-j"]
21
+ stdout: StdioCollector {
22
+ waitForEnd: true
23
+ onStreamFinished: root.probe(GlassTag.ownAddresses(text, Quickshell.processId))
24
+ }
25
+ }
26
+ property Process props: Process {
27
+ stdout: StdioCollector {
28
+ waitForEnd: true
29
+ onStreamFinished: root.apply(text)
30
+ }
31
+ }
32
+ property Process tags: Process {}
33
+ property Timer rerun: Timer {
34
+ interval: root.rerunGapMs
35
+ onTriggered: root.retag()
36
+ }
37
+
38
+ function retag() {
39
+ if (root.busy) {
40
+ root.rerun.restart()
41
+ return
42
+ }
43
+ root.clients.running = true
44
+ }
45
+ function probe(addresses) {
46
+ if (addresses.length === 0)
47
+ return
48
+ root.props.command = ["sh", "-c", GlassTag.PROBE, "sh"].concat(addresses)
49
+ root.props.running = true
50
+ }
51
+ function apply(text) {
52
+ var plan = GlassTag.plan(text, root.mode, root.usesDefault, root.tagged)
53
+ root.tagged = plan.tagged
54
+ if (plan.pairs.length === 0)
55
+ return
56
+ root.tags.command = ["sh", "-c", GlassTag.DISPATCH, "sh"].concat(plan.pairs)
57
+ root.tags.running = true
58
+ }
59
+ }
package/ui/Glyph.qml ADDED
@@ -0,0 +1,64 @@
1
+ import QtQuick
2
+ import QtQuick.Shapes
3
+ import qs.Commons
4
+ import "js/Icons.js" as Icons
5
+
6
+ // One row or sidebar mark, chosen by name. Lucide's grid is 24 units at stroke 2, scaled to the slot.
7
+ Item {
8
+ id: root
9
+
10
+ property string name: "file"
11
+ property color color: "transparent"
12
+ // Lucide draws on a 24 unit grid, so every path in Icons.js is in those units.
13
+ readonly property real grid: 24
14
+ // The mark's ceiling. Default is the row and menu mark; a surface drawing a mark alone passes its own.
15
+ property real maxSize: Theme.markSize
16
+ // The min() against the slot is the icon spec's own rule, so a smaller caller slot still wins
17
+ // (the Network "+" at the caption token needs it) and no container can ever enlarge a mark.
18
+ readonly property real markSize: Math.min(root.maxSize, root.width, root.height)
19
+ // Its own name: "scale" would shadow Item.scale, which qmllint flagged.
20
+ readonly property real gridScale: root.markSize / root.grid
21
+ property real strokeWidth: Theme.strokeWidth
22
+ // The solid part of the mark (Icons.js FILLED), empty for every mark but the few that have one.
23
+ readonly property string filledPath: Icons.filledPathFor(root.name)
24
+ // Built the first time a mark names a solid part: a plain glyph owns no object for it, which tests/rowcost.qml counts.
25
+ property Item solid: null
26
+ function syncSolid() {
27
+ if (root.solid === null && root.filledPath.length > 0)
28
+ root.solid = Qt.createComponent("GlyphSolid.qml").createObject(root, { glyph: root })
29
+ }
30
+ // filledPath starts empty, so its first non-empty value, on a build or a reuse, lands here.
31
+ onFilledPathChanged: root.syncSolid()
32
+ // An emoji mark draws as text in the same slot; Icons.isEmoji says which a name is.
33
+ readonly property bool emoji: Icons.isEmoji(root.name)
34
+
35
+ Text {
36
+ visible: root.emoji
37
+ anchors.centerIn: parent
38
+ text: root.emoji ? root.name : ""
39
+ font.pixelSize: root.markSize
40
+ }
41
+
42
+ // The Shape is sized in grid units pre-transform; Scale's origin defaults to (0,0), so this
43
+ // offset is what re-centers the scaled-down box in root's slot instead of pinning it top-left.
44
+ Shape {
45
+ visible: !root.emoji
46
+ width: root.grid
47
+ height: root.grid
48
+ x: (root.width - root.markSize) / 2
49
+ y: (root.height - root.markSize) / 2
50
+ preferredRendererType: Shape.CurveRenderer
51
+ transform: Scale { xScale: root.gridScale; yScale: root.gridScale }
52
+
53
+ ShapePath {
54
+ strokeColor: root.color
55
+ fillColor: "transparent"
56
+ strokeWidth: root.strokeWidth
57
+ // The Omarchy cut: square caps and mitered joins, the edge of the brand spiral; Icons.js paths are redrawn sharp to match.
58
+ capStyle: ViewState.hyprlandIcons && Style.cornerRadius > 0 ? ShapePath.RoundCap : ShapePath.SquareCap
59
+ joinStyle: ViewState.hyprlandIcons && Style.cornerRadius > 0 ? ShapePath.RoundJoin : ShapePath.MiterJoin
60
+ // A mark with more than one stroke is one multi-subpath SVG string; see Icons.js "Lucide path data".
61
+ PathSvg { path: Icons.pathFor(root.name) }
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,22 @@
1
+ import QtQuick
2
+ import QtQuick.Shapes
3
+
4
+ // The solid part of a mark, drawn over its stroke in the same ink; ui/Glyph.qml builds it only for a mark that names one.
5
+ Shape {
6
+ id: root
7
+
8
+ required property Glyph glyph
9
+
10
+ width: root.glyph.grid
11
+ height: root.glyph.grid
12
+ x: (root.glyph.width - root.glyph.markSize) / 2
13
+ y: (root.glyph.height - root.glyph.markSize) / 2
14
+ preferredRendererType: Shape.CurveRenderer
15
+ transform: Scale { xScale: root.glyph.gridScale; yScale: root.glyph.gridScale }
16
+
17
+ ShapePath {
18
+ strokeColor: "transparent"
19
+ fillColor: root.glyph.color
20
+ PathSvg { path: root.glyph.filledPath }
21
+ }
22
+ }