flea-qml 0.0.0-stage → 0.1.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 (625) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +478 -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 +402 -0
  51. package/src/archiveops.js +697 -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 +129 -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/transfer.js +669 -0
  82. package/src/trash-record.js +41 -0
  83. package/src/trash.js +210 -0
  84. package/src/trashbrowse.js +326 -0
  85. package/src/uistate.js +393 -0
  86. package/src/uistore.js +168 -0
  87. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  88. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  89. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  90. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  91. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  92. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  93. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  94. package/src/vendor/pele.js +145 -0
  95. package/src/vendor/temml.mjs +14708 -0
  96. package/src/watch.js +98 -0
  97. package/src/wayland/client.js +109 -0
  98. package/src/wayland/protocol.js +55 -0
  99. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  100. package/src/wayland/protocols/wayland.xml +3248 -0
  101. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  102. package/src/wayland/resource-io.js +6 -0
  103. package/src/wayland/socket-discovery.js +26 -0
  104. package/src/wayland/transport-posix.js +120 -0
  105. package/src/wayland/transport-win32.js +11 -0
  106. package/src/wayland/transport.js +3 -0
  107. package/src/wayland/win32-resources.js +80 -0
  108. package/src/wayland/win32-wire.js +62 -0
  109. package/test/archive.test.js +80 -0
  110. package/test/bench-markdown-scroll.mjs +190 -0
  111. package/test/clip-host.test.js +113 -0
  112. package/test/code-preview.test.js +35 -0
  113. package/test/compare-ui-paths.test.js +24 -0
  114. package/test/compare.test.js +54 -0
  115. package/test/delete-trash.test.js +67 -0
  116. package/test/dirsize.test.js +138 -0
  117. package/test/file-ops.test.js +241 -0
  118. package/test/find-contents.test.js +161 -0
  119. package/test/find-input.test.js +66 -0
  120. package/test/fixtures/pele-parity.json +1006 -0
  121. package/test/highlight-launcher.test.js +35 -0
  122. package/test/html-preview.test.js +22 -0
  123. package/test/input.test.js +15 -0
  124. package/test/keymap.test.js +26 -0
  125. package/test/language-icons.test.js +36 -0
  126. package/test/launcher.test.js +51 -0
  127. package/test/manual-code-scroll.mjs +28 -0
  128. package/test/manual-column-scroll.mjs +24 -0
  129. package/test/manual-compare-ui.mjs +20 -0
  130. package/test/manual-find-status.mjs +37 -0
  131. package/test/manual-html-security.mjs +23 -0
  132. package/test/manual-html-ui.mjs +30 -0
  133. package/test/manual-syntax-preview.mjs +26 -0
  134. package/test/manual-trash-ui.mjs +86 -0
  135. package/test/markdown-diagrams.test.js +93 -0
  136. package/test/markdown-html.test.js +105 -0
  137. package/test/mathml.test.js +92 -0
  138. package/test/menu-transfer.test.js +57 -0
  139. package/test/office-preview.test.js +154 -0
  140. package/test/pele-parity.test.js +28 -0
  141. package/test/places.test.js +134 -0
  142. package/test/preview-keys.test.js +60 -0
  143. package/test/preview-language.test.js +22 -0
  144. package/test/status-filename.test.js +20 -0
  145. package/test/transfer-replace-merge.test.js +187 -0
  146. package/test/trash-address.test.js +23 -0
  147. package/test/trash-view.test.js +37 -0
  148. package/test/trashbrowse.test.js +135 -0
  149. package/ui/AboutFacts.qml +78 -0
  150. package/ui/ArchiveCards.qml +68 -0
  151. package/ui/ArchiveCompressDialog.qml +378 -0
  152. package/ui/ArchivePasswordDialog.qml +257 -0
  153. package/ui/Backend.qml +771 -0
  154. package/ui/BulkOldNames.qml +47 -0
  155. package/ui/BulkRenameDialog.qml +380 -0
  156. package/ui/CardFrame.qml +67 -0
  157. package/ui/CardScroll.qml +79 -0
  158. package/ui/CheckBox.qml +73 -0
  159. package/ui/ChromeBar.qml +360 -0
  160. package/ui/ChromeButton.qml +131 -0
  161. package/ui/ChromeModes.qml +43 -0
  162. package/ui/CodeLines.qml +256 -0
  163. package/ui/CodeRefusal.qml +52 -0
  164. package/ui/CollideConfirm.qml +147 -0
  165. package/ui/CollideHost.qml +167 -0
  166. package/ui/ColumnPane.qml +523 -0
  167. package/ui/ColumnRow.qml +380 -0
  168. package/ui/ColumnsArea.qml +594 -0
  169. package/ui/ColumnsLanding.qml +147 -0
  170. package/ui/CompareView.qml +321 -0
  171. package/ui/ContextMenu.qml +743 -0
  172. package/ui/ConvertDialog.qml +456 -0
  173. package/ui/CountedWorker.qml +7 -0
  174. package/ui/Crumb.qml +64 -0
  175. package/ui/CrumbDrop.qml +25 -0
  176. package/ui/CsvTable.qml +394 -0
  177. package/ui/CursorMark.qml +41 -0
  178. package/ui/DefaultClaim.qml +130 -0
  179. package/ui/DeviceLock.qml +47 -0
  180. package/ui/DeviceMounts.qml +540 -0
  181. package/ui/DialogButton.qml +150 -0
  182. package/ui/DialogField.qml +147 -0
  183. package/ui/DialogHeader.qml +31 -0
  184. package/ui/DialogScrim.qml +20 -0
  185. package/ui/DialogTitle.qml +37 -0
  186. package/ui/Divider.qml +9 -0
  187. package/ui/DropInto.qml +126 -0
  188. package/ui/DropTarget.qml +35 -0
  189. package/ui/DropboxMark.qml +60 -0
  190. package/ui/EmptyState.qml +150 -0
  191. package/ui/EscapeHint.qml +11 -0
  192. package/ui/FactsTable.qml +54 -0
  193. package/ui/FastScrollHandler.qml +476 -0
  194. package/ui/FatNamesConfirm.qml +157 -0
  195. package/ui/Favourites.qml +143 -0
  196. package/ui/FigureService.qml +120 -0
  197. package/ui/FileDrag.qml +267 -0
  198. package/ui/FilterStrip.qml +133 -0
  199. package/ui/FitMetrics.qml +22 -0
  200. package/ui/FlashDriveRows.qml +137 -0
  201. package/ui/FlashHost.qml +72 -0
  202. package/ui/FlashImageRow.qml +104 -0
  203. package/ui/FlashRunner.qml +119 -0
  204. package/ui/FlashStepRow.qml +172 -0
  205. package/ui/FlashStrip.qml +38 -0
  206. package/ui/FlashView.qml +397 -0
  207. package/ui/FleaMark.qml +88 -0
  208. package/ui/FlyoutFade.qml +23 -0
  209. package/ui/FontPane.qml +170 -0
  210. package/ui/Glass.qml +114 -0
  211. package/ui/GlassTagger.qml +59 -0
  212. package/ui/Glyph.qml +64 -0
  213. package/ui/GlyphSolid.qml +22 -0
  214. package/ui/GridArea.qml +664 -0
  215. package/ui/GridTile.qml +325 -0
  216. package/ui/GvfsBridge.qml +164 -0
  217. package/ui/Header.qml +433 -0
  218. package/ui/HoverTimers.qml +39 -0
  219. package/ui/HtmlClip.qml +30 -0
  220. package/ui/HtmlPane.qml +63 -0
  221. package/ui/HyprlandMark.qml +45 -0
  222. package/ui/Ipc.qml +1005 -0
  223. package/ui/IpcControls.qml +7 -0
  224. package/ui/IpcMenuState.qml +48 -0
  225. package/ui/IpcPreviewState.qml +185 -0
  226. package/ui/JumpPath.qml +51 -0
  227. package/ui/KeymapSheet.qml +561 -0
  228. package/ui/KeymapSheetResult.qml +89 -0
  229. package/ui/KindStack.qml +40 -0
  230. package/ui/LangMark.qml +51 -0
  231. package/ui/LangMarkLoader.qml +26 -0
  232. package/ui/List.qml +480 -0
  233. package/ui/LoadingState.qml +54 -0
  234. package/ui/LocalSend.qml +56 -0
  235. package/ui/LocalSendMark.qml +73 -0
  236. package/ui/MarkdownBlockView.qml +311 -0
  237. package/ui/MarkdownBlocks.qml +35 -0
  238. package/ui/MarkdownFigure.qml +254 -0
  239. package/ui/MarkdownImages.qml +72 -0
  240. package/ui/MarkdownList.qml +81 -0
  241. package/ui/MarkdownMathsText.qml +97 -0
  242. package/ui/MarkdownPane.qml +83 -0
  243. package/ui/MarkdownPictures.qml +41 -0
  244. package/ui/MarkdownQuote.qml +52 -0
  245. package/ui/MarkdownRemote.qml +82 -0
  246. package/ui/MarkdownSource.qml +155 -0
  247. package/ui/MarkdownTable.qml +222 -0
  248. package/ui/MarkdownTableScroll.qml +64 -0
  249. package/ui/MarkdownTableWheel.qml +126 -0
  250. package/ui/MarkdownText.qml +87 -0
  251. package/ui/MarkdownWorker.js +132 -0
  252. package/ui/MatchText.qml +99 -0
  253. package/ui/MediaSession.qml +38 -0
  254. package/ui/MediaSound.qml +26 -0
  255. package/ui/MediaStrip.qml +191 -0
  256. package/ui/MediaTrack.qml +36 -0
  257. package/ui/MediaVolume.qml +54 -0
  258. package/ui/MenuActionDialog.qml +396 -0
  259. package/ui/MenuEdgeFade.qml +24 -0
  260. package/ui/MenuHost.qml +227 -0
  261. package/ui/MenuRow.qml +351 -0
  262. package/ui/MountListing.qml +100 -0
  263. package/ui/NetworkDialog.qml +435 -0
  264. package/ui/NetworkForm.qml +426 -0
  265. package/ui/NetworkMounts.qml +913 -0
  266. package/ui/NetworkPlaces.qml +127 -0
  267. package/ui/OpenWithDialog.qml +613 -0
  268. package/ui/Opener.qml +115 -0
  269. package/ui/Pane.qml +1296 -0
  270. package/ui/PaneMenuActions.qml +527 -0
  271. package/ui/PanePath.qml +90 -0
  272. package/ui/PaneRail.qml +239 -0
  273. package/ui/PaneStates.qml +88 -0
  274. package/ui/PaneSwap.qml +339 -0
  275. package/ui/PaneWire.qml +605 -0
  276. package/ui/ParkedWait.qml +9 -0
  277. package/ui/PathEntry.qml +186 -0
  278. package/ui/PathJump.qml +400 -0
  279. package/ui/PdfViewer.qml +297 -0
  280. package/ui/PermissionsDialog.qml +658 -0
  281. package/ui/PermissionsHeadings.qml +31 -0
  282. package/ui/PhoneMounts.qml +67 -0
  283. package/ui/PickerAnswers.qml +75 -0
  284. package/ui/PickerBox.qml +26 -0
  285. package/ui/PickerChrome.qml +295 -0
  286. package/ui/PickerFilter.qml +97 -0
  287. package/ui/PickerGrid.qml +308 -0
  288. package/ui/PickerHeader.qml +28 -0
  289. package/ui/PickerLifecycle.qml +27 -0
  290. package/ui/PickerList.qml +218 -0
  291. package/ui/PickerListing.qml +149 -0
  292. package/ui/PickerPathBar.qml +127 -0
  293. package/ui/PickerPlaces.qml +189 -0
  294. package/ui/PickerRecent.qml +92 -0
  295. package/ui/PickerSave.qml +101 -0
  296. package/ui/PickerSelection.qml +155 -0
  297. package/ui/PickerWindow.qml +846 -0
  298. package/ui/PowerSectorsReader.qml +10 -0
  299. package/ui/PrebuildDriver.qml +146 -0
  300. package/ui/Preview.qml +1004 -0
  301. package/ui/PreviewAnimation.qml +24 -0
  302. package/ui/PreviewArchive.qml +66 -0
  303. package/ui/PreviewColumn.qml +551 -0
  304. package/ui/PreviewEdge.qml +63 -0
  305. package/ui/PreviewFacts.qml +30 -0
  306. package/ui/PreviewFactsLine.qml +34 -0
  307. package/ui/PreviewHtml.qml +233 -0
  308. package/ui/PreviewImage.qml +253 -0
  309. package/ui/PreviewImagePan.qml +13 -0
  310. package/ui/PreviewImageSharp.qml +32 -0
  311. package/ui/PreviewLines.qml +106 -0
  312. package/ui/PreviewMarkdown.qml +706 -0
  313. package/ui/PreviewMedia.qml +250 -0
  314. package/ui/PreviewPdf.qml +482 -0
  315. package/ui/PreviewScroll.qml +201 -0
  316. package/ui/PreviewSwap.qml +335 -0
  317. package/ui/PreviewText.qml +149 -0
  318. package/ui/ProtocolChip.qml +18 -0
  319. package/ui/QuickLookArchive.qml +38 -0
  320. package/ui/QuickLookBar.qml +103 -0
  321. package/ui/QuickLookPrepare.qml +355 -0
  322. package/ui/QuickLookSwap.qml +10 -0
  323. package/ui/QuickLookWarm.qml +65 -0
  324. package/ui/RailDrop.qml +155 -0
  325. package/ui/RailHeading.qml +19 -0
  326. package/ui/RailPlaces.qml +38 -0
  327. package/ui/RailTrashRow.qml +67 -0
  328. package/ui/RenameField.qml +353 -0
  329. package/ui/RendererRetry.qml +11 -0
  330. package/ui/ResizeHandle.qml +52 -0
  331. package/ui/Reveal.qml +54 -0
  332. package/ui/Row.qml +476 -0
  333. package/ui/RowDrag.qml +213 -0
  334. package/ui/RowDropTarget.qml +27 -0
  335. package/ui/RunCard.qml +286 -0
  336. package/ui/Scripts.qml +65 -0
  337. package/ui/SearchStrip.qml +232 -0
  338. package/ui/SelectionBand.qml +140 -0
  339. package/ui/SelectionPreview.qml +370 -0
  340. package/ui/SettingsFavourite.qml +122 -0
  341. package/ui/SettingsGroup.qml +96 -0
  342. package/ui/SettingsHint.qml +12 -0
  343. package/ui/SettingsMetrics.qml +29 -0
  344. package/ui/SettingsPane.qml +178 -0
  345. package/ui/SettingsPanel.qml +547 -0
  346. package/ui/SettingsRail.qml +128 -0
  347. package/ui/SettingsRow.qml +409 -0
  348. package/ui/SettingsRuler.qml +85 -0
  349. package/ui/SettingsSegment.qml +85 -0
  350. package/ui/ShareBrowser.qml +113 -0
  351. package/ui/ShareLink.qml +67 -0
  352. package/ui/ShelfPins.qml +101 -0
  353. package/ui/Sidebar.qml +732 -0
  354. package/ui/SidebarRow.qml +358 -0
  355. package/ui/Spinner.qml +60 -0
  356. package/ui/StableModel.qml +89 -0
  357. package/ui/StateMessage.qml +84 -0
  358. package/ui/StatusBar.qml +512 -0
  359. package/ui/StatusFileName.qml +27 -0
  360. package/ui/TabBar.qml +673 -0
  361. package/ui/TabDragGeometry.qml +60 -0
  362. package/ui/TagMenuMark.qml +52 -0
  363. package/ui/TagRailSection.qml +53 -0
  364. package/ui/TagSlot.qml +40 -0
  365. package/ui/TagState.qml +150 -0
  366. package/ui/TagSwatch.qml +28 -0
  367. package/ui/Taildrop.qml +86 -0
  368. package/ui/TailscaleMark.qml +50 -0
  369. package/ui/Theme.qml +460 -0
  370. package/ui/ThemeColors.qml +43 -0
  371. package/ui/TransferCard.qml +239 -0
  372. package/ui/TrashConfirm.qml +129 -0
  373. package/ui/TrashDropHandler.qml +11 -0
  374. package/ui/TrashHost.qml +202 -0
  375. package/ui/TrashMonitor.qml +30 -0
  376. package/ui/TrashToolbar.qml +19 -0
  377. package/ui/TrashView.qml +492 -0
  378. package/ui/UnlockDialog.qml +450 -0
  379. package/ui/UnlockHost.qml +206 -0
  380. package/ui/UpdateCheck.qml +97 -0
  381. package/ui/UserDirs.qml +25 -0
  382. package/ui/ViewState.qml +565 -0
  383. package/ui/ViewportScrollBar.qml +195 -0
  384. package/ui/ViewportScrollBars.qml +25 -0
  385. package/ui/WebPreview.qml +33 -0
  386. package/ui/WebPreviewView.qml +26 -0
  387. package/ui/WindowBody.qml +827 -0
  388. package/ui/WindowDrag.qml +35 -0
  389. package/ui/boot/Commons/AudioNodes.qml +50 -0
  390. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  391. package/ui/boot/Commons/Border.qml +243 -0
  392. package/ui/boot/Commons/BorderGeometry.js +373 -0
  393. package/ui/boot/Commons/Color.qml +258 -0
  394. package/ui/boot/Commons/I18n.qml +118 -0
  395. package/ui/boot/Commons/InputDevices.qml +112 -0
  396. package/ui/boot/Commons/InputMethodState.qml +38 -0
  397. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  398. package/ui/boot/Commons/Numbers.js +19 -0
  399. package/ui/boot/Commons/Plural.js +91 -0
  400. package/ui/boot/Commons/ShellIpc.qml +12 -0
  401. package/ui/boot/Commons/Style.qml +561 -0
  402. package/ui/boot/Commons/Translations.qml +100 -0
  403. package/ui/boot/Commons/UntypedInput.qml +152 -0
  404. package/ui/boot/Commons/Util.qml +188 -0
  405. package/ui/boot/Commons/qmldir +13 -0
  406. package/ui/boot/LICENSE-omarchy +20 -0
  407. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  408. package/ui/boot/Ui/BarIconButton.qml +106 -0
  409. package/ui/boot/Ui/BarIconContent.qml +38 -0
  410. package/ui/boot/Ui/BarIndicator.qml +53 -0
  411. package/ui/boot/Ui/BarWidget.qml +50 -0
  412. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  413. package/ui/boot/Ui/BorderSurface.qml +40 -0
  414. package/ui/boot/Ui/Button.qml +224 -0
  415. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  416. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  417. package/ui/boot/Ui/CursorSurface.qml +42 -0
  418. package/ui/boot/Ui/Dropdown.qml +245 -0
  419. package/ui/boot/Ui/FilterInput.qml +26 -0
  420. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  421. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  422. package/ui/boot/Ui/MultiSelect.qml +624 -0
  423. package/ui/boot/Ui/NumberField.qml +86 -0
  424. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  425. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  426. package/ui/boot/Ui/Panel.qml +60 -0
  427. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  428. package/ui/boot/Ui/PanelController.qml +16 -0
  429. package/ui/boot/Ui/PanelHero.qml +112 -0
  430. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  431. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  432. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  433. package/ui/boot/Ui/PanelSlider.qml +156 -0
  434. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  435. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  436. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  437. package/ui/boot/Ui/PopupCard.qml +181 -0
  438. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  439. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  440. package/ui/boot/Ui/SizedImage.qml +125 -0
  441. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  442. package/ui/boot/Ui/TextField.qml +58 -0
  443. package/ui/boot/Ui/Toggle.qml +118 -0
  444. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  445. package/ui/boot/Ui/WidgetButton.qml +172 -0
  446. package/ui/boot/Ui/qmldir +41 -0
  447. package/ui/boot/fleatab.qml +50 -0
  448. package/ui/boot/picker.qml +39 -0
  449. package/ui/boot/shell.qml +122 -0
  450. package/ui/boot/tabtearoff.qml +51 -0
  451. package/ui/js/Anchor.js +379 -0
  452. package/ui/js/AnchorHold.js +162 -0
  453. package/ui/js/Archive.js +157 -0
  454. package/ui/js/ArchiveCard.js +44 -0
  455. package/ui/js/ArchiveOps.js +44 -0
  456. package/ui/js/BackReturn.js +118 -0
  457. package/ui/js/BulkRename.js +100 -0
  458. package/ui/js/Buttons.js +54 -0
  459. package/ui/js/ChromeKeys.js +116 -0
  460. package/ui/js/ClipMarks.js +73 -0
  461. package/ui/js/ClipSelection.js +67 -0
  462. package/ui/js/Clipboard.js +179 -0
  463. package/ui/js/Cloud.js +97 -0
  464. package/ui/js/CodeRuns.js +72 -0
  465. package/ui/js/Collide.js +212 -0
  466. package/ui/js/ColumnFit.js +28 -0
  467. package/ui/js/ColumnMenu.js +111 -0
  468. package/ui/js/Columns.js +298 -0
  469. package/ui/js/ColumnsCarry.js +103 -0
  470. package/ui/js/Compare.js +74 -0
  471. package/ui/js/Contrast.js +157 -0
  472. package/ui/js/ControlReader.js +42 -0
  473. package/ui/js/Convert.js +52 -0
  474. package/ui/js/CopyAs.js +52 -0
  475. package/ui/js/Crumbs.js +178 -0
  476. package/ui/js/Csv.js +231 -0
  477. package/ui/js/Density.js +44 -0
  478. package/ui/js/Devices.js +440 -0
  479. package/ui/js/DirSizes.js +180 -0
  480. package/ui/js/Drag.js +364 -0
  481. package/ui/js/DragOut.js +166 -0
  482. package/ui/js/DropDev.js +52 -0
  483. package/ui/js/Dropbox.js +41 -0
  484. package/ui/js/Eject.js +217 -0
  485. package/ui/js/Errors.js +188 -0
  486. package/ui/js/ExtThumbs.js +115 -0
  487. package/ui/js/Facts.js +402 -0
  488. package/ui/js/FigureDate.js +14 -0
  489. package/ui/js/Filter.js +285 -0
  490. package/ui/js/Find.js +46 -0
  491. package/ui/js/Flash.js +184 -0
  492. package/ui/js/FlashCard.js +79 -0
  493. package/ui/js/FlashEndings.js +125 -0
  494. package/ui/js/FlashPane.js +116 -0
  495. package/ui/js/FleaBin.js +12 -0
  496. package/ui/js/Focus.js +502 -0
  497. package/ui/js/FolderSorts.js +108 -0
  498. package/ui/js/FolderViews.js +44 -0
  499. package/ui/js/Format.js +305 -0
  500. package/ui/js/Fuzzy.js +141 -0
  501. package/ui/js/GlassTag.js +72 -0
  502. package/ui/js/Grid.js +33 -0
  503. package/ui/js/GridGeometry.js +90 -0
  504. package/ui/js/GridNames.js +153 -0
  505. package/ui/js/GvfsBridge.js +200 -0
  506. package/ui/js/HostClipboard.js +29 -0
  507. package/ui/js/Icons.js +218 -0
  508. package/ui/js/Input.js +50 -0
  509. package/ui/js/Jump.js +200 -0
  510. package/ui/js/KeyName.js +64 -0
  511. package/ui/js/Keymap.js +401 -0
  512. package/ui/js/Kinds.js +164 -0
  513. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  514. package/ui/js/LangMarkPaths.js +47 -0
  515. package/ui/js/LangMarks.js +120 -0
  516. package/ui/js/Lists.js +11 -0
  517. package/ui/js/LocalSend.js +39 -0
  518. package/ui/js/LockedMenu.js +63 -0
  519. package/ui/js/MakeDefault.js +186 -0
  520. package/ui/js/MarkBox.js +7 -0
  521. package/ui/js/Markdown.js +119 -0
  522. package/ui/js/MarkdownLists.js +86 -0
  523. package/ui/js/MarkdownMaths.js +58 -0
  524. package/ui/js/MarkdownPictures.js +32 -0
  525. package/ui/js/MarkdownPrepared.js +139 -0
  526. package/ui/js/MarkdownTableFit.js +34 -0
  527. package/ui/js/Marks.js +148 -0
  528. package/ui/js/Marquee.js +96 -0
  529. package/ui/js/Match.js +93 -0
  530. package/ui/js/Material.js +109 -0
  531. package/ui/js/MdBlocks.js +437 -0
  532. package/ui/js/MdBreak.js +71 -0
  533. package/ui/js/MdChunks.js +70 -0
  534. package/ui/js/MdContainer.js +137 -0
  535. package/ui/js/MdDocument.js +337 -0
  536. package/ui/js/MdEmph.js +97 -0
  537. package/ui/js/MdEntity.js +108 -0
  538. package/ui/js/MdEntityTable.js +223 -0
  539. package/ui/js/MdEscape.js +59 -0
  540. package/ui/js/MdFront.js +37 -0
  541. package/ui/js/MdHold.js +32 -0
  542. package/ui/js/MdHtml.js +307 -0
  543. package/ui/js/MdHtmlBlock.js +290 -0
  544. package/ui/js/MdHtmlHeading.js +53 -0
  545. package/ui/js/MdHtmlImage.js +179 -0
  546. package/ui/js/MdInline.js +154 -0
  547. package/ui/js/MdItems.js +212 -0
  548. package/ui/js/MdLeaf.js +309 -0
  549. package/ui/js/MdLink.js +196 -0
  550. package/ui/js/MdMath.js +67 -0
  551. package/ui/js/MdParagraphs.js +138 -0
  552. package/ui/js/MdRefs.js +232 -0
  553. package/ui/js/MdResolve.js +226 -0
  554. package/ui/js/MdRun.js +300 -0
  555. package/ui/js/MdUrl.js +226 -0
  556. package/ui/js/Menu.js +514 -0
  557. package/ui/js/MenuContext.js +85 -0
  558. package/ui/js/MenuFit.js +13 -0
  559. package/ui/js/MenuRefresh.js +74 -0
  560. package/ui/js/MenuWheel.js +35 -0
  561. package/ui/js/Messages.js +186 -0
  562. package/ui/js/Motion.js +16 -0
  563. package/ui/js/Mounts.js +320 -0
  564. package/ui/js/MouseNav.js +13 -0
  565. package/ui/js/Nav.js +329 -0
  566. package/ui/js/NetFs.js +26 -0
  567. package/ui/js/OpenWith.js +83 -0
  568. package/ui/js/Ops.js +585 -0
  569. package/ui/js/Palette.js +33 -0
  570. package/ui/js/PathBar.js +260 -0
  571. package/ui/js/Permissions.js +179 -0
  572. package/ui/js/Phones.js +112 -0
  573. package/ui/js/Picker.js +353 -0
  574. package/ui/js/PlaceMenu.js +96 -0
  575. package/ui/js/Places.js +265 -0
  576. package/ui/js/PreviewAsk.js +21 -0
  577. package/ui/js/PreviewKeys.js +155 -0
  578. package/ui/js/PreviewSettle.js +29 -0
  579. package/ui/js/PreviewSwap.js +101 -0
  580. package/ui/js/PropertyFacts.js +144 -0
  581. package/ui/js/Protocols.js +296 -0
  582. package/ui/js/QuickLookKinds.js +27 -0
  583. package/ui/js/QuickLookRect.js +24 -0
  584. package/ui/js/RailDrop.js +51 -0
  585. package/ui/js/RailKeys.js +87 -0
  586. package/ui/js/RailMenu.js +133 -0
  587. package/ui/js/Recent.js +135 -0
  588. package/ui/js/RecentMode.js +156 -0
  589. package/ui/js/Reload.js +60 -0
  590. package/ui/js/Renderer.js +9 -0
  591. package/ui/js/RunFile.js +143 -0
  592. package/ui/js/Scripts.js +28 -0
  593. package/ui/js/Scroll.js +304 -0
  594. package/ui/js/ScrollOff.js +69 -0
  595. package/ui/js/Search.js +478 -0
  596. package/ui/js/Selection.js +97 -0
  597. package/ui/js/Settings.js +476 -0
  598. package/ui/js/SettingsAbout.js +97 -0
  599. package/ui/js/SettingsShelf.js +52 -0
  600. package/ui/js/SheetKeys.js +42 -0
  601. package/ui/js/SheetQuery.js +281 -0
  602. package/ui/js/ShelfPile.js +27 -0
  603. package/ui/js/SlowClick.js +53 -0
  604. package/ui/js/SlowOp.js +6 -0
  605. package/ui/js/Sort.js +134 -0
  606. package/ui/js/Startup.js +63 -0
  607. package/ui/js/StateWords.js +17 -0
  608. package/ui/js/Status.js +238 -0
  609. package/ui/js/Swap.js +166 -0
  610. package/ui/js/TabMove.js +39 -0
  611. package/ui/js/Tabs.js +736 -0
  612. package/ui/js/Tags.js +134 -0
  613. package/ui/js/Taildrop.js +128 -0
  614. package/ui/js/Tap.js +174 -0
  615. package/ui/js/TextSize.js +107 -0
  616. package/ui/js/Thumbs.js +158 -0
  617. package/ui/js/Transfer.js +172 -0
  618. package/ui/js/Trash.js +81 -0
  619. package/ui/js/TrashDates.js +47 -0
  620. package/ui/js/TrashDrop.js +64 -0
  621. package/ui/js/UiState.js +438 -0
  622. package/ui/js/Unlock.js +152 -0
  623. package/ui/js/Update.js +130 -0
  624. package/ui/js/UserDirs.js +56 -0
  625. package/ui/qmldir +228 -0
@@ -0,0 +1,453 @@
1
+ import QtQuick
2
+ import Quickshell
3
+ import Quickshell.Wayland
4
+ import qs.Commons
5
+ import qs.Commons as Commons
6
+
7
+ // Layer-shell popup attached to a bar widget icon, designed for
8
+ // click-driven AND keyboard-driven panels (e.g. SUPER+CTRL+W summon).
9
+ //
10
+ // Built on PanelWindow with a brief WlrKeyboardFocus.Exclusive prime followed
11
+ // by OnDemand rather than PopupWindow (xdg-popup). The prime acquires focus
12
+ // both when the surface maps and when it reopens while still mapped for its
13
+ // fade-out. xdg-popups don't get that — they only receive keys after a
14
+ // click/hover routes focus through their parent surface — so keyboard-summoned
15
+ // popups fell flat without it.
16
+ //
17
+ // Exclusive would also grant map-time focus, but it makes Hyprland route
18
+ // *every* pointer event to the exclusive surface no matter which output
19
+ // the cursor is over, which leaves clicks on any other monitor unable to
20
+ // reach the dismissal surfaces below.
21
+ //
22
+ // API is a subset of Common.PopupCard: anchorItem, owner, bar, open,
23
+ // padding, margin, contentWidth/Height, centerOnBar, default contentItem.
24
+ // Missing on purpose (for now): triggerMode ("hover"), containsMouse.
25
+ //
26
+ // Positioning: full-screen layer-shell with the card placed inside at
27
+ // `cardOrigin`. We use the bar window's height/width for the perpendicular
28
+ // axis (away-from-bar) because mapToItem on the anchor returns
29
+ // bar-content-relative coords with internal layout offsets baked in
30
+ // (e.g. ~13px from the bar's vertical centering of its widget row). The
31
+ // parallel axis (along-the-bar) uses the anchor's content x/y since the
32
+ // bar spans full screen on that axis.
33
+ //
34
+ // Outside-click dismissal: an overlay MouseArea catches clicks, with the
35
+ // QsWindow.mask subtracting the bar strip so clicks on the bar still
36
+ // reach the bar widgets (activePopout coordinator hands off to another
37
+ // popup if the user clicks a different bar icon).
38
+ PanelWindow {
39
+ id: root
40
+
41
+ required property Item anchorItem
42
+ required property QtObject bar
43
+ property var owner: null
44
+ property int margin: Style.gapsOut
45
+ property int padding: Style.spacing.popupPadding
46
+ property int contentWidth: Style.space(280)
47
+ property int contentHeight: Style.space(200)
48
+ property var borderSpec: Border.surfaceSpec("popups", "border", Commons.Color.popups.border, Math.max(1, Style.space(2)))
49
+ property bool centerOnBar: false
50
+ property bool open: false
51
+ property int gap: Style.gapsOut // distance between bar edge and panel
52
+ property bool popoutSwitching: false
53
+ property bool popoutSwitchClosing: false
54
+ property bool focusPrimed: false
55
+
56
+ // Item that should take keyboard focus once the panel maps. Typically a
57
+ // PanelKeyCatcher inside the panel content. Layer-shell grants focus to the
58
+ // surface during the Exclusive prime, but Qt still needs an active-focus
59
+ // target inside the surface for Keys.onPressed handlers to fire. Schedule
60
+ // the focus through Qt.callLater so it runs after the surface is fully
61
+ // mapped and child items have completed layout.
62
+ property Item focusTarget: null
63
+
64
+ default property alias contentItem: contentHolder.children
65
+
66
+ // Lazy content. A panel that sets `content` to a Component gets it built
67
+ // the first time the panel opens instead of at shell startup, which is
68
+ // where most of a bar's memory and load time went: every panel's tree was
69
+ // built on every monitor whether or not it was ever opened. The content
70
+ // stays loaded after that first open, so reopening is instant and any
71
+ // state the content holds (scroll position, an edit in progress) survives
72
+ // a close. Root-level panel code reaches into it through `loadedContent`,
73
+ // which is null until then, so anything that must run while the panel is
74
+ // closed (timers, data, IPC) belongs outside the content. Panels that
75
+ // declare children directly keep the old eager behaviour.
76
+ property Component content: null
77
+ property bool contentRequested: false
78
+ readonly property Item loadedContent: contentLoader.item
79
+ readonly property real loadedContentHeight: contentLoader.item ? contentLoader.item.implicitHeight : 0
80
+
81
+ // Build the content without opening the panel, for callers that need to
82
+ // reach it first.
83
+ function ensureContent() {
84
+ if (content) contentRequested = true
85
+ return contentLoader.item
86
+ }
87
+
88
+ readonly property var coordinatorKey: owner || root
89
+ readonly property var anchorWindow: anchorItem ? anchorItem.QsWindow.window : null
90
+ readonly property string barPos: bar ? bar.position : "top"
91
+
92
+ function close() {
93
+ if (owner && "close" in owner) owner.close()
94
+ else root.open = false
95
+ }
96
+
97
+ function beginFocusPrime() {
98
+ if (open && backingWindowVisible) focusPrimeTimer.restart()
99
+ }
100
+
101
+ // --- screen + lifetime ---------------------------------------------------
102
+
103
+ screen: anchorWindow ? anchorWindow.screen : null
104
+ visible: open || card.opacity > 0 || popoutSwitching
105
+ color: "transparent"
106
+ exclusionMode: ExclusionMode.Ignore
107
+
108
+ WlrLayershell.namespace: "omarchy-keyboard-panel"
109
+ WlrLayershell.layer: WlrLayer.Overlay
110
+ // Keyboard focus follows `open` (NOT `visible`). The window remains
111
+ // mapped during the fade-out so the opacity animation has something to
112
+ // animate, but keyboard/click ownership must release the moment the
113
+ // logical close fires — otherwise the user is locked out for 140ms.
114
+ //
115
+ // Prime with Exclusive on every open, then settle on OnDemand. Hyprland
116
+ // focuses OnDemand when a surface first maps, but not when an already-mapped
117
+ // fade-out surface changes from None back to OnDemand. Exclusive also takes
118
+ // focus when the previously focused application has constrained the pointer.
119
+ // The brief prime covers both cases; OnDemand then releases compositor-wide
120
+ // pointer hit-testing so clicks can reach the dismissal windows below.
121
+ WlrLayershell.keyboardFocus: open
122
+ ? (focusPrimed ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.Exclusive)
123
+ : WlrKeyboardFocus.None
124
+
125
+ onBackingWindowVisibleChanged: beginFocusPrime()
126
+
127
+ // Full-screen layer-shell. The visible card is positioned inside via
128
+ // `cardOrigin`. The `mask` below makes the bar area click-through (so
129
+ // the user can click another bar icon while the panel is open and the
130
+ // activePopout coordinator swaps to that popup); everywhere else, the
131
+ // overlay catches the click and dismisses via the MouseArea below.
132
+ anchors {
133
+ top: true
134
+ bottom: true
135
+ left: true
136
+ right: true
137
+ }
138
+
139
+ // Clickable region is the whole screen. Clicks in the bar strip are
140
+ // forwarded to registered bar buttons so switching between panel icons
141
+ // works in one click even when the overlay surface is above the bar.
142
+ readonly property real _barStripSize: {
143
+ if (!bar) return 0
144
+ var actual = (root.barPos === "top" || root.barPos === "bottom") ? root.barH : root.barW
145
+ return Math.max(bar.barSize, actual) + root.gap
146
+ }
147
+ mask: Region {
148
+ width: root.screenW
149
+ height: root.screenH
150
+ }
151
+
152
+ // Track every layout change between the bar's contentItem and the
153
+ // anchor item. `transform` updates whenever any item in that chain
154
+ // moves/resizes, which is what makes the position binding below
155
+ // actually reactive — mapToItem on its own is a one-shot.
156
+ TransformWatcher {
157
+ id: anchorWatcher
158
+ a: anchorWindow ? anchorWindow.contentItem : null
159
+ b: anchorItem
160
+ }
161
+
162
+ // Anchor item's position within the bar's content surface. For a
163
+ // full-width top bar, the content x maps directly to screen x; the y
164
+ // returned here has the bar's internal padding baked in (e.g. ~13px
165
+ // from vertical centering of the widget row), which is why `cardOrigin`
166
+ // below uses `barH` for the perpendicular axis instead of this y.
167
+ readonly property point anchorScreenPos: {
168
+ anchorWatcher.transform // reactive dependency
169
+ if (!anchorItem || !anchorWindow) return Qt.point(0, 0)
170
+ return anchorItem.mapToItem(anchorWindow.contentItem, 0, 0)
171
+ }
172
+ readonly property real anchorW: anchorItem ? anchorItem.width : 0
173
+ readonly property real anchorH: anchorItem ? anchorItem.height : 0
174
+ readonly property real screenW: screen ? screen.width : 0
175
+ readonly property real screenH: screen ? screen.height : 0
176
+ readonly property real availableCardWidth: screenW > 0
177
+ ? Math.max(120, screenW - ((barPos === "left" || barPos === "right") ? barW + gap + margin : margin * 2))
178
+ : 0
179
+ readonly property real availableCardHeight: screenH > 0
180
+ ? Math.max(120, screenH - ((barPos === "top" || barPos === "bottom") ? barH + gap + margin : margin * 2))
181
+ : 0
182
+ readonly property real verticalContentInset: padding * 2 + Border.top(borderSpec) + Border.bottom(borderSpec)
183
+
184
+ function fittedContentWidth(width, cap) {
185
+ var desired = Math.max(1, Number(width) || 1)
186
+ var maxWidth = root.availableCardWidth > 0 ? root.availableCardWidth : desired
187
+ if (cap !== undefined && Number(cap) > 0) maxWidth = Math.min(maxWidth, Number(cap))
188
+ return Math.round(Math.min(desired, maxWidth))
189
+ }
190
+
191
+ function fittedContentHeight(implicitHeight, cap) {
192
+ var desired = Math.max(root.verticalContentInset, (Number(implicitHeight) || 0) + root.verticalContentInset)
193
+ var maxHeight = root.availableCardHeight > 0 ? root.availableCardHeight : desired
194
+ if (cap !== undefined && Number(cap) > 0) maxHeight = Math.min(maxHeight, Number(cap))
195
+ return Math.round(Math.min(desired, maxHeight))
196
+ }
197
+
198
+ function cappedContentHeight(height) {
199
+ var desired = Math.max(root.padding * 2, Number(height) || root.padding * 2)
200
+ var maxHeight = root.availableCardHeight > 0 ? root.availableCardHeight : desired
201
+ return Math.round(Math.min(desired, maxHeight))
202
+ }
203
+
204
+ // Desired top-left of the card in screen coordinates. For the
205
+ // perpendicular axis (away-from-bar) we anchor to the bar window's edge
206
+ // directly — not the anchor item's y/x — because mapToItem(barContent)
207
+ // returns coordinates in the bar's content space, which can be offset
208
+ // from the bar surface's screen-anchored corner by internal layout
209
+ // (centering wrappers, padding). The bar's surface IS aligned to its
210
+ // anchored screen edge, so using `barW`/`barH` gives the right edge
211
+ // regardless of how the bar's internal widgets are positioned. For the
212
+ // parallel axis (along the bar) the anchor item's reported position is
213
+ // still consistent with the bar content origin, so it's accurate for
214
+ // centering the card under the icon.
215
+ readonly property real barW: anchorWindow ? anchorWindow.width : screenW
216
+ readonly property real barH: anchorWindow ? anchorWindow.height : 0
217
+ readonly property point cardOrigin: {
218
+ if (!anchorItem || !bar) return Qt.point(margin, margin)
219
+ var x = 0, y = 0
220
+ if (centerOnBar && (barPos === "top" || barPos === "bottom")) {
221
+ x = screenW / 2 - contentWidth / 2
222
+ y = barPos === "bottom" ? screenH - barH - contentHeight - gap : barH + gap
223
+ } else if (centerOnBar) {
224
+ x = barPos === "left" ? barW + gap : screenW - barW - contentWidth - gap
225
+ y = screenH / 2 - contentHeight / 2
226
+ } else if (barPos === "bottom") {
227
+ x = anchorScreenPos.x + anchorW / 2 - contentWidth / 2
228
+ y = screenH - barH - contentHeight - gap
229
+ } else if (barPos === "left") {
230
+ x = barW + gap
231
+ y = anchorScreenPos.y + anchorH / 2 - contentHeight / 2
232
+ } else if (barPos === "right") {
233
+ x = screenW - barW - contentWidth - gap
234
+ y = anchorScreenPos.y + anchorH / 2 - contentHeight / 2
235
+ } else { // "top" (default)
236
+ x = anchorScreenPos.x + anchorW / 2 - contentWidth / 2
237
+ y = barH + gap
238
+ }
239
+ x = Math.max(margin, Math.min(x, screenW - contentWidth - margin))
240
+ y = Math.max(margin, Math.min(y, screenH - contentHeight - margin))
241
+ return Qt.point(Math.round(x), Math.round(y))
242
+ }
243
+
244
+
245
+ // --- popout coordination (same-bar single-popout model) -----------------
246
+
247
+ // Coordinate on `open`, not `visible`. `visible` lags into the fade-out
248
+ // animation, which made ownership transfer to a sibling popup race.
249
+ onOpenChanged: {
250
+ if (open) {
251
+ if (content) contentRequested = true
252
+ focusPrimed = false
253
+ beginFocusPrime()
254
+ if (focusTarget) Qt.callLater(function() {
255
+ if (root.open && root.focusTarget) root.focusTarget.forceActiveFocus()
256
+ })
257
+ } else {
258
+ focusPrimeTimer.stop()
259
+ focusPrimed = false
260
+ }
261
+ if (!bar) return
262
+ if (open) {
263
+ popoutSwitchClosing = false
264
+ popoutSwitching = bar.activePopout && bar.activePopout !== coordinatorKey
265
+ bar.requestPopout(coordinatorKey)
266
+ if (popoutSwitching) popoutSwitchTimer.restart()
267
+ } else {
268
+ popoutSwitchClosing = !!(owner && owner.popoutSwitchClosing)
269
+ popoutSwitching = false
270
+ if (bar.activePopout === coordinatorKey) bar.releasePopout(coordinatorKey)
271
+ if (popoutSwitchClosing) closeSwitchTimer.restart()
272
+ }
273
+ }
274
+
275
+ Timer {
276
+ id: focusPrimeTimer
277
+ // Leave enough time for multiple Qt/Wayland commit cycles after the
278
+ // backing window becomes visible while keeping the compositor-wide
279
+ // Exclusive phase imperceptibly short. This interval is covered by the
280
+ // immediate hide/re-summon acceptance case.
281
+ interval: 75
282
+ onTriggered: if (root.open) root.focusPrimed = true
283
+ }
284
+
285
+ Timer {
286
+ id: popoutSwitchTimer
287
+ interval: 150
288
+ onTriggered: root.popoutSwitching = false
289
+ }
290
+
291
+ Timer {
292
+ id: closeSwitchTimer
293
+ interval: 1
294
+ onTriggered: root.popoutSwitchClosing = false
295
+ }
296
+
297
+ // --- outside-click dismissal --------------------------------------------
298
+
299
+ // Catches clicks anywhere in the clickable region (i.e. everywhere on
300
+ // screen except the bar strip, which is masked out). The card has its
301
+ // own MouseArea below so clicks on it don't bubble up here. Disabled
302
+ // during the fade-out so the dying overlay doesn't swallow clicks that
303
+ // were meant for the apps behind it.
304
+ MouseArea {
305
+ id: dismissArea
306
+ anchors.fill: parent
307
+ enabled: root.open
308
+ acceptedButtons: Qt.AllButtons
309
+ hoverEnabled: true
310
+ property bool hoveringBar: false
311
+ cursorShape: hoveringBar ? Qt.PointingHandCursor : Qt.ArrowCursor
312
+
313
+ function inBarRegion(px, py) {
314
+ if (root.barPos === "bottom") return py >= root.screenH - root._barStripSize
315
+ if (root.barPos === "left") return px <= root._barStripSize
316
+ if (root.barPos === "right") return px >= root.screenW - root._barStripSize
317
+ return py <= root._barStripSize
318
+ }
319
+
320
+ function barPoint(px, py) {
321
+ if (root.barPos === "bottom") return Qt.point(px, py - (root.screenH - root.barH))
322
+ if (root.barPos === "right") return Qt.point(px - (root.screenW - root.barW), py)
323
+ return Qt.point(px, py)
324
+ }
325
+
326
+ function pressTargetAt(px, py) {
327
+ if (!root.anchorWindow || !root.anchorWindow.contentItem || !root.bar || !root.bar.clickTargets) return null
328
+ var p = barPoint(px, py)
329
+ var targets = root.bar.clickTargets
330
+ for (var i = targets.length - 1; i >= 0; i--) {
331
+ var target = targets[i]
332
+ if (!target || !target.triggerPress || target.visible === false || target.opacity === 0 || !target.mapToItem) continue
333
+ if (root.bar.targetBelongsToWindow && !root.bar.targetBelongsToWindow(target, root.anchorWindow)) continue
334
+ if (Util.itemContainsPoint(target, root.anchorWindow.contentItem, p.x, p.y)) return target
335
+ }
336
+ return null
337
+ }
338
+
339
+ function forwardBarClick(px, py, button) {
340
+ if (button !== Qt.LeftButton && button !== Qt.RightButton && button !== Qt.MiddleButton) return false
341
+ var target = pressTargetAt(px, py)
342
+ if (!target) return false
343
+ target.triggerPress(button)
344
+ return true
345
+ }
346
+
347
+ onPositionChanged: function(mouse) { hoveringBar = inBarRegion(mouse.x, mouse.y) }
348
+ onExited: hoveringBar = false
349
+ onClicked: function(mouse) {
350
+ // While Exclusive is priming, Hyprland may route a click from another
351
+ // output here with translated coordinates. Never interpret that as a
352
+ // click on this output's bar.
353
+ if (root.focusPrimed && inBarRegion(mouse.x, mouse.y) && forwardBarClick(mouse.x, mouse.y, mouse.button)) return
354
+ root.close()
355
+ }
356
+ }
357
+
358
+ // The panel surface only spans the anchor's screen, and the compositor
359
+ // hit-tests pointer input per output, so `dismissArea` above can never see
360
+ // a click on another monitor. Give every other output a transparent twin
361
+ // whose only job is to catch that click. They exist only while the panel is
362
+ // logically open (not during the fade-out, matching `dismissArea.enabled`).
363
+ //
364
+ // Keyboard focus is None: these must catch the pointer without taking focus
365
+ // from the panel when the cursor merely crosses onto their output.
366
+ Variants {
367
+ model: root.open ? Quickshell.screens : []
368
+
369
+ delegate: Component {
370
+ PanelWindow {
371
+ required property var modelData
372
+
373
+ screen: modelData
374
+ // Compare by output name: the anchor screen must be known before any
375
+ // twin maps, or a twin would cover the panel's own output.
376
+ visible: root.open && !!root.screen && modelData.name !== root.screen.name
377
+ color: "transparent"
378
+ exclusionMode: ExclusionMode.Ignore
379
+
380
+ WlrLayershell.namespace: "omarchy-keyboard-panel-dismiss"
381
+ WlrLayershell.layer: WlrLayer.Overlay
382
+ WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
383
+
384
+ anchors {
385
+ top: true
386
+ bottom: true
387
+ left: true
388
+ right: true
389
+ }
390
+
391
+ MouseArea {
392
+ anchors.fill: parent
393
+ acceptedButtons: Qt.AllButtons
394
+ onPressed: root.close()
395
+ }
396
+ }
397
+ }
398
+ }
399
+
400
+ // --- card ----------------------------------------------------------------
401
+
402
+ BorderSurface {
403
+ id: card
404
+ x: root.cardOrigin.x
405
+ y: root.cardOrigin.y
406
+ width: root.contentWidth
407
+ height: root.contentHeight
408
+ color: Commons.Color.popups.background
409
+ borderSpec: root.borderSpec
410
+ padding: root.padding
411
+ radius: Style.cornerRadius
412
+ opacity: root.open || root.popoutSwitching ? 1.0 : 0
413
+
414
+ Behavior on opacity {
415
+ enabled: !root.popoutSwitching && !root.popoutSwitchClosing
416
+ NumberAnimation { duration: Style.duration(140); easing.type: Easing.OutCubic }
417
+ }
418
+
419
+ // Swallow clicks on the card so they don't bubble to the dismissal
420
+ // MouseArea behind us.
421
+ MouseArea {
422
+ anchors.fill: parent
423
+ acceptedButtons: Qt.AllButtons
424
+ }
425
+
426
+ Item {
427
+ id: contentHolder
428
+ anchors.fill: parent
429
+ // Right-to-left languages read the card mirrored; the card itself
430
+ // stays where the bar puts it.
431
+ LayoutMirroring.enabled: Commons.I18n.rightToLeft
432
+ LayoutMirroring.childrenInherit: true
433
+ anchors.topMargin: card.contentTopInset
434
+ anchors.rightMargin: card.contentRightInset
435
+ anchors.bottomMargin: card.contentBottomInset
436
+ anchors.leftMargin: card.contentLeftInset
437
+ opacity: root.popoutSwitching ? (root.open ? 1.0 : 0) : 1.0
438
+
439
+ Loader {
440
+ id: contentLoader
441
+ anchors.fill: parent
442
+ focus: true
443
+ active: !!root.content && (root.open || root.contentRequested)
444
+ sourceComponent: root.content
445
+ }
446
+
447
+ Behavior on opacity {
448
+ enabled: root.popoutSwitching
449
+ NumberAnimation { duration: Style.duration(140); easing.type: Easing.OutCubic }
450
+ }
451
+ }
452
+ }
453
+ }