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,152 @@
1
+ pragma Singleton
2
+ import QtQuick
3
+ import Quickshell
4
+ import Quickshell.Io
5
+ import Quickshell.Services.Pipewire
6
+ import "AudioNodesModel.js" as Model
7
+
8
+ // Volume and mute of the default input when Quickshell gives it no
9
+ // PwNode.audio: Quickshell types only exact media classes, so a virtual source
10
+ // (an Audio/Source/Virtual, such as EasyEffects' or a platform's microphone
11
+ // mapping) has no volume or mute there. They go through wpctl instead, once for
12
+ // the whole shell. Reads and writes name the node by id, a reply for a node no
13
+ // longer tracked is dropped, and writes run one at a time with only the latest
14
+ // volume kept, so a slider drag cannot land on another input later.
15
+ Singleton {
16
+ id: root
17
+
18
+ readonly property var source: Pipewire.defaultAudioSource
19
+ // The default input is untyped, so this drives it.
20
+ readonly property bool active: !!source && !source.audio
21
+ // Every handler reads nodeId itself: a property bound to it could still hold
22
+ // its old value when onNodeIdChanged runs.
23
+ readonly property int nodeId: active ? source.id : -1
24
+
25
+ property bool known: false
26
+ property real volume: 0
27
+ property bool muted: false
28
+
29
+ property int generation: 0
30
+ property int readGeneration: -1
31
+ property bool readAgain: false
32
+ property var pendingVolume: null
33
+ property var pendingMute: null
34
+
35
+ // pactl subscribe is started again when it ends, unless it keeps ending at
36
+ // once (no pipewire-pulse), which would only respawn it forever.
37
+ property real subscribedAt: 0
38
+ property int quickExits: 0
39
+
40
+ onNodeIdChanged: reset()
41
+ Component.onCompleted: reset()
42
+
43
+ function reset() {
44
+ generation++
45
+ known = false
46
+ pendingVolume = null
47
+ pendingMute = null
48
+ quickExits = 0
49
+ events.running = nodeId >= 0
50
+ refresh()
51
+ }
52
+
53
+ function refresh() {
54
+ if (nodeId < 0) return
55
+ if (reader.running || writer.running) {
56
+ readAgain = true
57
+ return
58
+ }
59
+ readGeneration = generation
60
+ reader.command = ["wpctl", "get-volume", String(nodeId)]
61
+ reader.running = true
62
+ }
63
+
64
+ function setVolume(value) {
65
+ if (nodeId < 0) return
66
+ volume = Math.max(0, Math.min(1, value))
67
+ pendingVolume = [String(nodeId), volume.toFixed(2)]
68
+ flush()
69
+ }
70
+
71
+ function setMuted(value) {
72
+ if (nodeId < 0 || !known) return
73
+ muted = value
74
+ pendingMute = [String(nodeId), value ? "1" : "0"]
75
+ flush()
76
+ }
77
+
78
+ function flush() {
79
+ if (reader.running || writer.running) return true
80
+ var args = null
81
+ if (pendingMute !== null) {
82
+ args = ["wpctl", "set-mute"].concat(pendingMute)
83
+ pendingMute = null
84
+ } else if (pendingVolume !== null) {
85
+ args = ["wpctl", "set-volume"].concat(pendingVolume)
86
+ pendingVolume = null
87
+ }
88
+ if (!args) return false
89
+ writer.command = args
90
+ writer.running = true
91
+ return true
92
+ }
93
+
94
+ function settle() {
95
+ if (flush()) return
96
+ if (readAgain) {
97
+ readAgain = false
98
+ refresh()
99
+ }
100
+ }
101
+
102
+ Process {
103
+ id: reader
104
+ stdout: StdioCollector {
105
+ waitForEnd: true
106
+ onStreamFinished: {
107
+ var level = Model.parseWpctlVolume(text)
108
+ if (!level || root.nodeId < 0 || root.readGeneration !== root.generation) return
109
+ if (root.pendingVolume !== null || root.pendingMute !== null || writer.running) return
110
+ root.volume = level.volume
111
+ root.muted = level.muted
112
+ root.known = true
113
+ }
114
+ }
115
+ onExited: root.settle()
116
+ }
117
+
118
+ Process {
119
+ id: writer
120
+ onExited: {
121
+ root.readAgain = true
122
+ root.settle()
123
+ }
124
+ }
125
+
126
+ // The volume keys, the mute key and other apps change the node too. pactl
127
+ // translates its events, so they are read in the C locale.
128
+ Process {
129
+ id: events
130
+ command: ["pactl", "subscribe"]
131
+ environment: ({ LC_ALL: "C" })
132
+ onRunningChanged: if (running) root.subscribedAt = Date.now()
133
+ onExited: {
134
+ root.quickExits = Date.now() - root.subscribedAt < 1000 ? root.quickExits + 1 : 0
135
+ if (root.nodeId >= 0 && root.quickExits < 5) resubscribe.start()
136
+ }
137
+ stdout: SplitParser {
138
+ onRead: function(line) {
139
+ if (String(line).indexOf(" on source #") !== -1) root.refresh()
140
+ }
141
+ }
142
+ }
143
+
144
+ Timer {
145
+ id: resubscribe
146
+ interval: 2000
147
+ onTriggered: if (root.nodeId >= 0 && !events.running) {
148
+ events.running = true
149
+ root.refresh()
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,188 @@
1
+ pragma Singleton
2
+ import Quickshell
3
+ import QtQuick
4
+
5
+ // Shared utility helpers used across plugins. Pure functions only — no
6
+ // state. Anything stateful belongs on Color, Style, or a service.
7
+ QtObject {
8
+ id: root
9
+
10
+ // Manual click forwarding must honor the same clipping as Qt's hit test.
11
+ // Collapsed drawers keep their children laid out beyond the visible edge.
12
+ function itemContainsPoint(target, source, x, y) {
13
+ if (!target || !target.contains(target.mapFromItem(source, x, y))) return false
14
+ for (var item = target; item; item = item.parent) {
15
+ if (!item.visible || item.opacity === 0 || !item.enabled) return false
16
+ if (item.clip && !item.contains(item.mapFromItem(source, x, y))) return false
17
+ }
18
+ return true
19
+ }
20
+
21
+ function clamp(value, min, max) {
22
+ var n = Number(value)
23
+ if (!isFinite(n)) return min
24
+ return Math.max(min, Math.min(max, n))
25
+ }
26
+
27
+ function clampAlpha(value) {
28
+ return clamp(value, 0, 1)
29
+ }
30
+
31
+ function wheelSteps(accumulator, delta) {
32
+ // Some mouse/compositor combinations scale a single notch well beyond
33
+ // Qt's conventional 120 units. Keep one event to one step while still
34
+ // accumulating the smaller deltas emitted by touchpads.
35
+ delta = Math.max(-120, Math.min(120, delta))
36
+ if (accumulator * delta < 0) accumulator = 0
37
+ var total = accumulator + delta
38
+ var steps = total < 0 ? Math.ceil(total / 120) : Math.floor(total / 120)
39
+ return { steps: steps, remainder: total - steps * 120 }
40
+ }
41
+
42
+ // Compose a base color with an opacity. Accepts a color object or a hex
43
+ // string; null/undefined yields transparent black at the requested alpha.
44
+ function alpha(c, opacity) {
45
+ var a = clampAlpha(opacity)
46
+ if (!c) return Qt.rgba(0, 0, 0, a)
47
+ if (typeof c === "string") c = Qt.color(c)
48
+ return Qt.rgba(c.r, c.g, c.b, a)
49
+ }
50
+
51
+ // file:// URL with each path segment percent-encoded so spaces and
52
+ // special chars in user paths don't break Image.source.
53
+ function fileUrl(path) {
54
+ if (!path) return ""
55
+ return "file://" + String(path).split("/").map(encodeURIComponent).join("/")
56
+ }
57
+
58
+ function isVideoPath(path) {
59
+ return /\.(mp4|m4v|mov|webm|mkv|avi)$/i.test(String(path || ""))
60
+ }
61
+
62
+ // Single-quote a string for bash. The replace handles embedded single
63
+ // quotes by closing, escaping, and re-opening the literal.
64
+ function shellQuote(value) {
65
+ return "'" + String(value || "").replace(/'/g, "'\\''") + "'"
66
+ }
67
+
68
+ function execDetached(command) {
69
+ Quickshell.execDetached(["bash", "-lc", command])
70
+ }
71
+
72
+ // Run an argv vector without a shell interpreting it: the constant `exec "$@"`
73
+ // means the args only ever land in positional parameters, which bash expands
74
+ // without re-tokenizing — so untrusted data ($(id), a filename) stays literal.
75
+ // The login shell (-l) keeps the PATH/session env GUI targets (omasnap, mpv,
76
+ // xdg-open) need. Prefer this over execDetached for anything built from input.
77
+ function execArgv(argv) {
78
+ Quickshell.execDetached(["bash", "-lc", 'exec "$@"', "bash"].concat(argv))
79
+ }
80
+
81
+ function isPlainObject(value) {
82
+ return value !== null && typeof value === "object" && !Array.isArray(value)
83
+ }
84
+
85
+ function canonicalWidgetId(id) {
86
+ return String(id || "")
87
+ }
88
+
89
+ // Best-effort base64 decode. Returns "" on parse failure rather than
90
+ // surfacing garbage downstream.
91
+ function decodeBase64(value) {
92
+ var s = String(value || "")
93
+ if (!s) return ""
94
+ try { return Qt.atob(s) } catch (e) { return "" }
95
+ }
96
+
97
+ function cloneJson(value) {
98
+ return JSON.parse(JSON.stringify(value === undefined ? null : value))
99
+ }
100
+
101
+ // Parse the last line of a custom-module / indicator process output as
102
+ // waybar-style JSON ({text, class, tooltip, ...}). Falls back to {text: raw}
103
+ // when the output isn't JSON, and {} for empty output.
104
+ function parseModuleJson(raw) {
105
+ var text = String(raw || "").trim()
106
+ if (!text) return {}
107
+ var lines = text.split("\n")
108
+ try {
109
+ return JSON.parse(lines[lines.length - 1])
110
+ } catch (e) {
111
+ return { text: text }
112
+ }
113
+ }
114
+
115
+ // Standard Qt text-editing keys shared by every searchable panel's filter:
116
+ // Backspace delete previous character
117
+ // Ctrl+Backspace delete previous word (Qt DeleteStartOfWord)
118
+ // Ctrl+U clear the whole field
119
+ // True only when the event would actually change the text, so an empty
120
+ // filter never swallows the key — panels keep their own empty-filter
121
+ // fallbacks (e.g. menu back-navigation) in later branches.
122
+ // The arrow a horizontal key press means along the reading direction: in a
123
+ // right-to-left layout, mirrored, Left moves forward and Right back. With
124
+ // vim set, h and l count as Left and Right too.
125
+ function readingKey(event, vim) {
126
+ var key = event.key
127
+ if (vim && (key === Qt.Key_H || event.text === "h")) key = Qt.Key_Left
128
+ else if (vim && (key === Qt.Key_L || event.text === "l")) key = Qt.Key_Right
129
+ if (I18n.rightToLeft) {
130
+ if (key === Qt.Key_Left) return Qt.Key_Right
131
+ if (key === Qt.Key_Right) return Qt.Key_Left
132
+ }
133
+ return key
134
+ }
135
+
136
+ function editsFilter(event, text) {
137
+ if (!text) return false
138
+ // Alt/Meta-modified sequences belong to other shortcuts — never edit here.
139
+ if (event.modifiers & (Qt.AltModifier | Qt.MetaModifier)) return false
140
+ if (event.key === Qt.Key_U) // Ctrl+U only (not Ctrl+Shift+U → Unicode input)
141
+ return event.modifiers === Qt.ControlModifier
142
+ return event.key === Qt.Key_Backspace // plain, Shift, or Ctrl Backspace
143
+ }
144
+
145
+ // New filter text after applying an edit key. Assumes editsFilter(event, text).
146
+ function editedFilter(event, text) {
147
+ if (event.key === Qt.Key_U) return "" // Ctrl+U: clear
148
+ if (event.modifiers & Qt.ControlModifier) // Ctrl+Backspace: word
149
+ return text.replace(/\s+$/, "").replace(/\S+$/, "")
150
+ return text.slice(0, -1) // Backspace: char
151
+ }
152
+
153
+ // Layout normalization shared by bar config consumers
154
+ // so the two never drift. Entries are deep-cloned to decouple from the
155
+ // input config; consumers can mutate without leaking back to shell.json.
156
+ function normalizeLayoutEntry(entry) {
157
+ if (typeof entry === "string") return { id: canonicalWidgetId(entry) }
158
+ if (isPlainObject(entry) && entry.id) {
159
+ var copy = cloneJson(entry)
160
+ copy.id = canonicalWidgetId(copy.id)
161
+ return copy
162
+ }
163
+ return null
164
+ }
165
+
166
+ function normalizeLayoutSection(list) {
167
+ if (!Array.isArray(list)) return []
168
+ var out = []
169
+ for (var i = 0; i < list.length; i++) {
170
+ var e = normalizeLayoutEntry(list[i])
171
+ if (e) out.push(e)
172
+ }
173
+ return out
174
+ }
175
+
176
+ // The bar's sections in the order they run along it, and tray, drawn
177
+ // inside the tray's drawer. The center box sits in the middle of the bar;
178
+ // centerBegin and centerEnd hang off its two edges.
179
+ readonly property var barSections: ["left", "centerBegin", "center", "centerEnd", "right", "tray"]
180
+
181
+ function normalizeLayout(layout) {
182
+ var src = isPlainObject(layout) ? layout : {}
183
+ var out = {}
184
+ for (var i = 0; i < barSections.length; i++)
185
+ out[barSections[i]] = normalizeLayoutSection(src[barSections[i]])
186
+ return out
187
+ }
188
+ }
@@ -0,0 +1,13 @@
1
+ module qs.Commons
2
+ singleton AudioNodes 1.0 AudioNodes.qml
3
+ singleton Border 1.0 Border.qml
4
+ singleton Color 1.0 Color.qml
5
+ singleton I18n 1.0 I18n.qml
6
+ singleton InputDevices 1.0 InputDevices.qml
7
+ singleton IpcRegistry 1.0 IpcRegistry.qml
8
+ singleton InputMethodState 1.0 InputMethodState.qml
9
+ singleton Style 1.0 Style.qml
10
+ singleton UntypedInput 1.0 UntypedInput.qml
11
+ singleton Util 1.0 Util.qml
12
+ ShellIpc 1.0 ShellIpc.qml
13
+ Translations 1.0 Translations.qml
@@ -0,0 +1,20 @@
1
+ Copyright (c) David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,49 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+
4
+ // The shell draws stills only. OWE owns video backgrounds on the desktop, and
5
+ // it feeds the lock screen through its own socket.
6
+ Item {
7
+ id: root
8
+
9
+ property string path: ""
10
+ property int version: 0
11
+ // Unversioned images cache by path. A caller whose version changes with every
12
+ // new file, as the lock's does, may cache too: the version is in the URL.
13
+ property bool cached: version === 0
14
+ // A caller that knows the size its screen needs, in physical pixels, sets
15
+ // constrainDecode and decodeSize. The image then waits for that size rather
16
+ // than decoding at the file's native size first.
17
+ property bool constrainDecode: false
18
+ property size decodeSize: Qt.size(0, 0)
19
+ readonly property var current: imageLoader.item
20
+ readonly property bool ready: current ? current.ready : false
21
+ // The file behind path could not be loaded, as when it was deleted.
22
+ readonly property bool failed: current ? current.failed : false
23
+ readonly property bool video: Util.isVideoPath(path)
24
+ // Cache-bust images selected in a running lock session, so a theme switch
25
+ // that replaces the file behind an unchanged path shows the new pixels.
26
+ readonly property url imageUrl: path && !video ? Util.fileUrl(path) + (version ? "?v=" + version : "") : ""
27
+
28
+ Loader {
29
+ id: imageLoader
30
+ anchors.fill: parent
31
+ active: root.path !== "" && !root.video
32
+ sourceComponent: imageComponent
33
+ }
34
+
35
+ Component {
36
+ id: imageComponent
37
+
38
+ Image {
39
+ readonly property bool ready: status === Image.Ready
40
+ readonly property bool failed: status === Image.Error
41
+ source: !root.constrainDecode || root.decodeSize.width > 0 ? root.imageUrl : ""
42
+ fillMode: Image.PreserveAspectCrop
43
+ asynchronous: true
44
+ cache: root.cached
45
+ sourceSize.width: root.constrainDecode ? root.decodeSize.width : (root.version > 0 ? width : 0)
46
+ sourceSize.height: root.constrainDecode ? root.decodeSize.height : (root.version > 0 ? height : 0)
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,106 @@
1
+ import QtQuick
2
+ import Quickshell
3
+ import qs.Commons
4
+
5
+ WidgetButton {
6
+ id: root
7
+
8
+ property Component iconComponent: null
9
+ property real slotSize: Style.bar.iconSlot
10
+ property real opticalSize: Style.bar.iconCanvas
11
+ property real iconSize: Math.min(Style.bar.iconSize, opticalSize)
12
+ readonly property real visualIconSize: Style.bar.iconSize
13
+ readonly property real canvasSize: Math.max(visualIconSize, opticalSize)
14
+ property string labelText: ""
15
+ property bool debugOpticalBounds: Quickshell.env("OMARCHY_DEBUG_BAR_ICONS") === "1"
16
+ // A label shifts the icon within the centered group.
17
+ readonly property real opticalCenterErrorX:
18
+ content.x + opticalCanvas.x + (glyph.visible ? glyph.paintedCenterX : customIcon.width / 2 + customIcon.centerErrorX) - root.width / 2
19
+ - (label.visible ? (label.implicitWidth + Style.space(4)) / 2 : 0)
20
+ readonly property real opticalCenterErrorY:
21
+ content.y + (glyph.visible ? glyph.paintedCenterY : customIcon.height / 2 + customIcon.centerErrorY) - root.height / 2
22
+ readonly property real glyphPaintedWidth: glyph.visible ? glyph.paintedWidth : 0
23
+ readonly property real glyphPaintedHeight: glyph.visible ? glyph.paintedHeight : 0
24
+ readonly property real glyphBaselineY: glyph.visible ? glyph.baselineY : 0
25
+ readonly property int glyphFontSize: glyph.visible ? glyph.renderedFontSize : 0
26
+ readonly property real componentPaintedWidth: customIcon.visible ? customIcon.paintedWidth : 0
27
+ readonly property real componentPaintedHeight: customIcon.visible ? customIcon.paintedHeight : 0
28
+ readonly property rect componentSourceBounds: customIcon.sourceBounds
29
+
30
+ labelVisible: false
31
+ hasVisualContent: text !== "" || iconComponent !== null || labelText !== ""
32
+ fontSize: Style.bar.iconFont
33
+ fixedWidth: vertical ? -1 : slotSize
34
+ fixedHeight: vertical ? slotSize : -1
35
+
36
+ Item {
37
+ id: content
38
+ // Exact coordinates preserve the center of odd-width slots.
39
+ x: (root.width - width) / 2
40
+ y: (root.height - height) / 2
41
+ width: root.canvasSize + (label.visible ? label.implicitWidth + Style.space(4) : 0)
42
+ height: root.canvasSize
43
+
44
+ Text {
45
+ id: label
46
+ visible: root.labelText !== ""
47
+ textFormat: Text.PlainText
48
+ text: root.labelText
49
+ font.family: root.fontFamily
50
+ font.pixelSize: root.fontSize
51
+ color: root.active && root.useActiveColor ? root.activeColor : root.foreground
52
+ y: (parent.height - height) / 2
53
+ + (labelMetrics.descent - labelMetrics.ascent + labelMetrics.tightBoundingRect("0").height) / 2
54
+ renderType: Text.NativeRendering
55
+ }
56
+
57
+ FontMetrics {
58
+ id: labelMetrics
59
+ font: label.font
60
+ }
61
+
62
+ Item {
63
+ id: opticalCanvas
64
+ x: label.visible ? label.implicitWidth + Style.space(4) : 0
65
+ width: root.canvasSize
66
+ height: root.canvasSize
67
+
68
+ OpticalGlyph {
69
+ id: glyph
70
+ anchors.fill: parent
71
+ visible: root.iconComponent === null
72
+ text: root.text
73
+ fontFamily: root.fontFamily
74
+ fontSize: root.fontSize
75
+ paintedSize: root.visualIconSize
76
+ color: root.active && root.useActiveColor ? root.activeColor : root.foreground
77
+ rotation: root.textRotation
78
+ debugBounds: root.debugOpticalBounds
79
+ }
80
+
81
+ BarIconContent {
82
+ id: customIcon
83
+ anchors.fill: parent
84
+ visible: root.iconComponent !== null
85
+ sourceComponent: root.iconComponent
86
+ sourceSize: root.opticalSize
87
+ }
88
+
89
+ Rectangle {
90
+ visible: root.debugOpticalBounds && root.iconComponent !== null
91
+ anchors.fill: parent
92
+ color: "transparent"
93
+ border.width: 1
94
+ border.color: "#4488ff"
95
+ }
96
+ }
97
+ }
98
+
99
+ Rectangle {
100
+ visible: root.debugOpticalBounds
101
+ anchors.fill: parent
102
+ color: "transparent"
103
+ border.width: 1
104
+ border.color: "#ff4455"
105
+ }
106
+ }
@@ -0,0 +1,38 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+
4
+ Item {
5
+ id: root
6
+
7
+ property Component sourceComponent: null
8
+ property real sourceSize: Style.bar.iconCanvas
9
+ readonly property rect sourceBounds: bounds.mappedBounds
10
+ readonly property real contentScale: sourceBounds.width > 0 && sourceBounds.height > 0
11
+ ? Style.bar.iconSize / Math.max(sourceBounds.width, sourceBounds.height) : 1
12
+ readonly property real paintedWidth: sourceBounds.width * contentScale
13
+ readonly property real paintedHeight: sourceBounds.height * contentScale
14
+ readonly property real centerErrorX: content.x + (sourceBounds.x + sourceBounds.width / 2) * contentScale - width / 2
15
+ readonly property real centerErrorY: content.y + (sourceBounds.y + sourceBounds.height / 2) * contentScale - height / 2
16
+
17
+ Loader {
18
+ id: content
19
+ sourceComponent: root.sourceComponent
20
+ onLoaded: {
21
+ // Keep declared dimensions. Empty wrapper items receive a source canvas.
22
+ if (!(item instanceof Image)) {
23
+ if (item.width <= 0) item.width = Qt.binding(function() { return root.sourceSize })
24
+ if (item.height <= 0) item.height = Qt.binding(function() { return root.sourceSize })
25
+ }
26
+ }
27
+ transformOrigin: Item.TopLeft
28
+ scale: root.contentScale
29
+ x: root.width / 2 - (root.sourceBounds.x + root.sourceBounds.width / 2) * scale
30
+ y: root.height / 2 - (root.sourceBounds.y + root.sourceBounds.height / 2) * scale
31
+ }
32
+
33
+ IconContentBounds {
34
+ id: bounds
35
+ sourceItem: content.item
36
+ boundsParent: content
37
+ }
38
+ }
@@ -0,0 +1,53 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+
4
+ BarIconButton {
5
+ id: root
6
+
7
+ property string moduleName: ""
8
+ property var settings: ({})
9
+ property string activeText: ""
10
+ property string inactiveText: activeText
11
+ property string activeTooltipText: ""
12
+ property string inactiveTooltipText: activeTooltipText
13
+ property string indicatorBlock: "single"
14
+ property var indicatorHost: null
15
+ property var activeOverride: null
16
+ // An indicator with nothing to turn on, such as a remote session, shows only
17
+ // while it is active, never among the inactive ones a hover reveals.
18
+ property bool revealWhenInactive: true
19
+ readonly property bool effectiveActive: activeOverride === null || activeOverride === undefined ? active : activeOverride === true
20
+ readonly property bool belongsInBlock: indicatorBlock === "active" ? effectiveActive : (indicatorBlock === "inactive" ? !effectiveActive && revealWhenInactive : true)
21
+ readonly property bool inactiveRevealed: !effectiveActive && revealWhenInactive && !!indicatorHost && indicatorHost.revealInactiveIndicators
22
+
23
+ function extractData(raw) {
24
+ return Util.parseModuleJson(raw)
25
+ }
26
+
27
+ function syncIndicatorOpacity() {
28
+ root.opacity = !belongsInBlock ? 0 : (effectiveActive ? 1 : (inactiveRevealed ? 0.45 : 0))
29
+ }
30
+
31
+ Component.onCompleted: syncIndicatorOpacity()
32
+ onActiveChanged: syncIndicatorOpacity()
33
+ onEffectiveActiveChanged: syncIndicatorOpacity()
34
+ onBarChanged: syncIndicatorOpacity()
35
+ onBelongsInBlockChanged: syncIndicatorOpacity()
36
+ onInactiveRevealedChanged: syncIndicatorOpacity()
37
+ onIndicatorBlockChanged: syncIndicatorOpacity()
38
+
39
+ visible: belongsInBlock && (text !== "" || keepSpace)
40
+ text: effectiveActive ? activeText : inactiveText
41
+ tooltipText: effectiveActive ? activeTooltipText : inactiveTooltipText
42
+ keepSpace: true
43
+ dimmed: !effectiveActive
44
+ concealed: !effectiveActive && !inactiveRevealed
45
+ interactive: belongsInBlock && (effectiveActive || indicatorBlock === "inactive" || inactiveRevealed)
46
+ useActiveColor: false
47
+ maintainIndicatorReveal: indicatorBlock === "inactive"
48
+ revealHost: indicatorHost
49
+ horizontalMargin: 5
50
+ verticalPadding: 5
51
+ fixedWidth: vertical ? -1 : Style.bar.statusSlot
52
+ fixedHeight: vertical ? Style.bar.statusSlot : -1
53
+ }
@@ -0,0 +1,50 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+
4
+ // Base item every bar widget extends. Codifies the properties the bar host
5
+ // injects into each widget slot:
6
+ // bar - the host Bar instance (foreground/background/run/etc).
7
+ // moduleName - widget's canonical id, used by the host registry to look
8
+ // up settings and to disambiguate inline IPC routes.
9
+ // settings - per-widget overrides read from shell.json's layout entry.
10
+ // fixedEdge - the edge of the widget that stays put when it grows:
11
+ // "start" (left, or top on a vertical bar), "end", or
12
+ // "center" when it grows both ways. Content laid out
13
+ // against it stays put while the widget grows.
14
+ //
15
+ // Widgets are free to add their own properties, signals, and child items.
16
+ Item {
17
+ id: root
18
+
19
+ property QtObject bar: null
20
+ property string moduleName: ""
21
+ property var settings: ({})
22
+ property string fixedEdge: "center"
23
+
24
+ // Bar geometry, lifted off the host. Widgets read these constantly to pick
25
+ // between horizontal/vertical layouts; defining them on the base keeps the
26
+ // `bar ? bar.x : fallback` ternary out of every widget body.
27
+ readonly property bool vertical: bar ? bar.vertical : false
28
+ readonly property int barSize: bar ? bar.barSize : Style.bar.sizeHorizontal
29
+
30
+ // Run `method` on every live instance of this widget. An IPC target only
31
+ // ever routes to one handler, but a bar surface exists per monitor, so the
32
+ // instance that owns the target relays the call to its peers — otherwise a
33
+ // refresh would land on a single screen and leave the others stale.
34
+ function broadcast(method) {
35
+ var items = bar && typeof bar.moduleWidgets === "function"
36
+ ? bar.moduleWidgets(moduleName) : [root]
37
+ for (var i = 0; i < items.length; i++) {
38
+ if (items[i] && typeof items[i][method] === "function") items[i][method]()
39
+ }
40
+ }
41
+
42
+ // Read a single value from this widget's inline shell.json entry, with a
43
+ // fallback for missing/null values. Every widget that takes user-tunable
44
+ // settings needs this; defining it once on the base keeps the wiring
45
+ // consistent.
46
+ function setting(name, fallback) {
47
+ var value = settings ? settings[name] : undefined
48
+ return value === undefined || value === null ? fallback : value
49
+ }
50
+ }