@gjsify/adwaita-web 0.53.0 → 0.55.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 (440) hide show
  1. package/dist/adwaita-web.css +8070 -3037
  2. package/dist/adwaita-web.css.map +1 -1
  3. package/lib/types/adw-application-window.spec.d.ts +1 -0
  4. package/lib/types/adw-bin.spec.d.ts +1 -0
  5. package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
  6. package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
  7. package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
  8. package/lib/types/adw-preferences-row.spec.d.ts +1 -0
  9. package/lib/types/adw-shortcuts.spec.d.ts +1 -0
  10. package/lib/types/adw-tab-bar.spec.d.ts +1 -0
  11. package/lib/types/adw-tab-button.spec.d.ts +1 -0
  12. package/lib/types/adw-tab-overview.spec.d.ts +1 -0
  13. package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
  14. package/lib/types/adw-window.spec.d.ts +1 -0
  15. package/lib/types/breakpoints.d.ts +14 -3
  16. package/lib/types/construct-vectors.spec.d.ts +1 -0
  17. package/lib/types/elements/adw-application-window.d.ts +27 -0
  18. package/lib/types/elements/adw-bin.d.ts +17 -0
  19. package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
  20. package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
  21. package/lib/types/elements/adw-dialog.d.ts +10 -0
  22. package/lib/types/elements/adw-layout-slot.d.ts +19 -0
  23. package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
  24. package/lib/types/elements/adw-preferences-row.d.ts +31 -0
  25. package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
  26. package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
  27. package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
  28. package/lib/types/elements/adw-sidebar.d.ts +5 -0
  29. package/lib/types/elements/adw-switch-row.d.ts +3 -0
  30. package/lib/types/elements/adw-tab-bar.d.ts +108 -0
  31. package/lib/types/elements/adw-tab-button.d.ts +32 -0
  32. package/lib/types/elements/adw-tab-overview.d.ts +199 -0
  33. package/lib/types/elements/adw-tab-view.d.ts +19 -23
  34. package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
  35. package/lib/types/elements/adw-window.d.ts +40 -0
  36. package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
  37. package/lib/types/elements/gtk-application-window.d.ts +34 -0
  38. package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
  39. package/lib/types/elements/gtk-button.d.ts +9 -0
  40. package/lib/types/elements/gtk-calendar.d.ts +159 -0
  41. package/lib/types/elements/gtk-center-box.d.ts +39 -0
  42. package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
  43. package/lib/types/elements/gtk-column-view.d.ts +50 -0
  44. package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
  45. package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
  46. package/lib/types/elements/gtk-editable-label.d.ts +33 -0
  47. package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
  48. package/lib/types/elements/gtk-entry.d.ts +20 -1
  49. package/lib/types/elements/gtk-expander.d.ts +49 -0
  50. package/lib/types/elements/gtk-fixed.d.ts +13 -0
  51. package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
  52. package/lib/types/elements/gtk-flow-box.d.ts +87 -0
  53. package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
  54. package/lib/types/elements/gtk-frame.d.ts +24 -0
  55. package/lib/types/elements/gtk-gl-area.d.ts +136 -0
  56. package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
  57. package/lib/types/elements/gtk-grid-view.d.ts +39 -0
  58. package/lib/types/elements/gtk-grid.d.ts +27 -0
  59. package/lib/types/elements/gtk-header-bar.d.ts +60 -0
  60. package/lib/types/elements/gtk-inscription.d.ts +64 -0
  61. package/lib/types/elements/gtk-label.d.ts +3 -0
  62. package/lib/types/elements/gtk-level-bar.d.ts +59 -0
  63. package/lib/types/elements/gtk-link-button.d.ts +29 -0
  64. package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
  65. package/lib/types/elements/gtk-list-box.d.ts +100 -0
  66. package/lib/types/elements/gtk-list-view.d.ts +73 -0
  67. package/lib/types/elements/gtk-media-controls.d.ts +142 -0
  68. package/lib/types/elements/gtk-notebook.d.ts +148 -0
  69. package/lib/types/elements/gtk-overlay.d.ts +22 -0
  70. package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
  71. package/lib/types/elements/gtk-paned.d.ts +121 -0
  72. package/lib/types/elements/gtk-password-entry.d.ts +27 -0
  73. package/lib/types/elements/gtk-picture.d.ts +66 -0
  74. package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
  75. package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
  76. package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
  77. package/lib/types/elements/gtk-popover.d.ts +28 -3
  78. package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
  79. package/lib/types/elements/gtk-revealer.d.ts +55 -0
  80. package/lib/types/elements/gtk-scale-button.d.ts +59 -0
  81. package/lib/types/elements/gtk-scale.d.ts +98 -0
  82. package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
  83. package/lib/types/elements/gtk-scrolled-window.d.ts +121 -0
  84. package/lib/types/elements/gtk-search-bar.d.ts +39 -0
  85. package/lib/types/elements/gtk-search-entry.d.ts +27 -0
  86. package/lib/types/elements/gtk-separator.d.ts +10 -0
  87. package/lib/types/elements/gtk-spin-button.d.ts +94 -0
  88. package/lib/types/elements/gtk-spinner.d.ts +14 -0
  89. package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
  90. package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
  91. package/lib/types/elements/gtk-stack.d.ts +154 -0
  92. package/lib/types/elements/gtk-switch.d.ts +4 -1
  93. package/lib/types/elements/gtk-text-view.d.ts +62 -0
  94. package/lib/types/elements/gtk-text.d.ts +45 -0
  95. package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
  96. package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
  97. package/lib/types/elements/gtk-video.d.ts +97 -0
  98. package/lib/types/elements/gtk-viewport.d.ts +84 -0
  99. package/lib/types/elements/gtk-window-controls.d.ts +80 -0
  100. package/lib/types/elements/gtk-window-handle.d.ts +39 -0
  101. package/lib/types/elements/gtk-window.d.ts +97 -0
  102. package/lib/types/elements/justification.d.ts +2 -0
  103. package/lib/types/elements/popover-menu.d.ts +18 -0
  104. package/lib/types/elements/roving-focus.d.ts +29 -1
  105. package/lib/types/emoji-data.d.ts +38 -0
  106. package/lib/types/font-description.d.ts +96 -0
  107. package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
  108. package/lib/types/gtk-action-bar.spec.d.ts +1 -0
  109. package/lib/types/gtk-application-window.spec.d.ts +1 -0
  110. package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
  111. package/lib/types/gtk-calendar.spec.d.ts +1 -0
  112. package/lib/types/gtk-center-box.spec.d.ts +1 -0
  113. package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
  114. package/lib/types/gtk-column-view.spec.d.ts +1 -0
  115. package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
  116. package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
  117. package/lib/types/gtk-editable-label.spec.d.ts +1 -0
  118. package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
  119. package/lib/types/gtk-expander.spec.d.ts +1 -0
  120. package/lib/types/gtk-fixed.spec.d.ts +1 -0
  121. package/lib/types/gtk-flow-box.spec.d.ts +1 -0
  122. package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
  123. package/lib/types/gtk-frame.spec.d.ts +1 -0
  124. package/lib/types/gtk-gl-area.spec.d.ts +1 -0
  125. package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
  126. package/lib/types/gtk-grid-view.spec.d.ts +1 -0
  127. package/lib/types/gtk-grid.spec.d.ts +1 -0
  128. package/lib/types/gtk-header-bar.spec.d.ts +1 -0
  129. package/lib/types/gtk-inscription.spec.d.ts +1 -0
  130. package/lib/types/gtk-level-bar.spec.d.ts +1 -0
  131. package/lib/types/gtk-link-button.spec.d.ts +1 -0
  132. package/lib/types/gtk-list-box.spec.d.ts +1 -0
  133. package/lib/types/gtk-list-view.spec.d.ts +1 -0
  134. package/lib/types/gtk-media-controls.spec.d.ts +1 -0
  135. package/lib/types/gtk-notebook.spec.d.ts +1 -0
  136. package/lib/types/gtk-overlay.spec.d.ts +1 -0
  137. package/lib/types/gtk-paned.spec.d.ts +1 -0
  138. package/lib/types/gtk-password-entry.spec.d.ts +1 -0
  139. package/lib/types/gtk-picture.spec.d.ts +1 -0
  140. package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
  141. package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
  142. package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
  143. package/lib/types/gtk-popover-role.spec.d.ts +1 -0
  144. package/lib/types/gtk-popover.spec.d.ts +1 -0
  145. package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
  146. package/lib/types/gtk-revealer.spec.d.ts +1 -0
  147. package/lib/types/gtk-scale-button.spec.d.ts +1 -0
  148. package/lib/types/gtk-scale.spec.d.ts +1 -0
  149. package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
  150. package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
  151. package/lib/types/gtk-search-bar.spec.d.ts +1 -0
  152. package/lib/types/gtk-search-entry.spec.d.ts +1 -0
  153. package/lib/types/gtk-separator.spec.d.ts +1 -0
  154. package/lib/types/gtk-spin-button.spec.d.ts +1 -0
  155. package/lib/types/gtk-spinner.spec.d.ts +1 -0
  156. package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
  157. package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
  158. package/lib/types/gtk-stack.spec.d.ts +1 -0
  159. package/lib/types/gtk-text-view.spec.d.ts +1 -0
  160. package/lib/types/gtk-text.spec.d.ts +1 -0
  161. package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
  162. package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
  163. package/lib/types/gtk-video.spec.d.ts +1 -0
  164. package/lib/types/gtk-viewport.spec.d.ts +1 -0
  165. package/lib/types/gtk-window-controls.spec.d.ts +1 -0
  166. package/lib/types/gtk-window-handle.spec.d.ts +1 -0
  167. package/lib/types/gtk-window.spec.d.ts +1 -0
  168. package/lib/types/index.d.ts +4 -1
  169. package/lib/types/list-view-dom.d.ts +44 -0
  170. package/lib/types/namespace/adw.d.ts +12 -0
  171. package/lib/types/namespace/gtk.d.ts +61 -0
  172. package/lib/types/page-setup.d.ts +100 -0
  173. package/lib/types/scroll-shading.d.ts +15 -1
  174. package/lib/types/shared-tree-builder.d.ts +30 -2
  175. package/lib/types/signals.d.ts +4 -0
  176. package/lib/types/styles.generated.d.ts +1 -1
  177. package/lib/types/tab-chip.d.ts +73 -0
  178. package/lib/types/template-classes.d.ts +11 -0
  179. package/package.json +12 -8
  180. package/scss/_action_row.scss +2 -2
  181. package/scss/_application_window.scss +26 -0
  182. package/scss/_aspect_frame.scss +25 -0
  183. package/scss/_bin.scss +26 -0
  184. package/scss/_button.scss +45 -0
  185. package/scss/_calendar.scss +176 -0
  186. package/scss/_center_box.scss +25 -0
  187. package/scss/_checks.scss +6 -1
  188. package/scss/_clamp_scrollable.scss +28 -0
  189. package/scss/_color_button.scss +67 -0
  190. package/scss/_column_view.scss +126 -0
  191. package/scss/_drag_icon.scss +55 -0
  192. package/scss/_drawing.scss +85 -0
  193. package/scss/_emoji_chooser.scss +213 -0
  194. package/scss/_entry.scss +13 -5
  195. package/scss/_entry_row.scss +1 -1
  196. package/scss/_expander.scss +113 -0
  197. package/scss/_fixed.scss +29 -0
  198. package/scss/_flow_box.scss +94 -0
  199. package/scss/_font_button.scss +63 -0
  200. package/scss/_frame.scss +41 -0
  201. package/scss/_grid.scss +19 -0
  202. package/scss/_grid_view.scss +46 -0
  203. package/scss/_gtk_about_dialog.scss +186 -0
  204. package/scss/_headerbar.scss +132 -0
  205. package/scss/_icons.generated.scss +186 -0
  206. package/scss/_inscription.scss +125 -0
  207. package/scss/_level_bar.scss +190 -0
  208. package/scss/_link.scss +82 -0
  209. package/scss/_list_box.scss +88 -0
  210. package/scss/_list_view.scss +96 -0
  211. package/scss/_media_controls.scss +139 -0
  212. package/scss/_overlay.scss +68 -0
  213. package/scss/_paned.scss +130 -0
  214. package/scss/_password_entry.scss +83 -0
  215. package/scss/_picture.scss +80 -0
  216. package/scss/_popover_bin.scss +53 -0
  217. package/scss/_popover_menu_bar.scss +104 -0
  218. package/scss/_preferences_row.scss +51 -0
  219. package/scss/_print_dialogs.scss +328 -0
  220. package/scss/_reset.scss +21 -19
  221. package/scss/_revealer.scss +37 -0
  222. package/scss/_row.scss +20 -5
  223. package/scss/_scale.scss +298 -0
  224. package/scss/_scale_button.scss +167 -0
  225. package/scss/_scrollbar.scss +230 -0
  226. package/scss/_scrolled_window.scss +131 -0
  227. package/scss/_search_bar.scss +118 -0
  228. package/scss/_search_entry.scss +86 -0
  229. package/scss/_separator.scss +44 -0
  230. package/scss/_shortcuts_dialog.scss +100 -0
  231. package/scss/_spin_button.scss +172 -0
  232. package/scss/_spin_row.scss +56 -8
  233. package/scss/_spinner.scss +85 -4
  234. package/scss/_stack.scss +729 -0
  235. package/scss/_switch.scss +13 -5
  236. package/scss/_switch_row.scss +10 -0
  237. package/scss/_tab_bar.scss +317 -0
  238. package/scss/_tab_button.scss +98 -0
  239. package/scss/_tab_overview.scss +483 -0
  240. package/scss/_text.scss +182 -0
  241. package/scss/_theme.scss +1 -1
  242. package/scss/_tree_expander.scss +62 -0
  243. package/scss/_variables.scss +43 -21
  244. package/scss/_video.scss +146 -0
  245. package/scss/_view_switcher_sidebar.scss +112 -0
  246. package/scss/_viewport.scss +50 -0
  247. package/scss/_window.scss +118 -1
  248. package/scss/_window_handle.scss +20 -0
  249. package/scss/adwaita-skin.scss +109 -0
  250. package/src/adw-action-rows.spec.ts +76 -0
  251. package/src/adw-application-window.spec.ts +118 -0
  252. package/src/adw-bin.spec.ts +75 -0
  253. package/src/adw-breakpoint-bin.spec.ts +324 -0
  254. package/src/adw-clamp-scrollable.spec.ts +189 -0
  255. package/src/adw-multi-layout-view.spec.ts +243 -0
  256. package/src/adw-preferences-row.spec.ts +164 -0
  257. package/src/adw-row-state.spec.ts +142 -0
  258. package/src/adw-shortcuts.spec.ts +155 -0
  259. package/src/adw-tab-bar.spec.ts +287 -0
  260. package/src/adw-tab-button.spec.ts +101 -0
  261. package/src/adw-tab-overview.spec.ts +443 -0
  262. package/src/adw-view-switcher-sidebar.spec.ts +281 -0
  263. package/src/adw-window.spec.ts +129 -0
  264. package/src/breakpoints.ts +25 -8
  265. package/src/capabilities.d.mts +3 -0
  266. package/src/capabilities.mjs +18 -0
  267. package/src/connect-lifecycle.spec.ts +12 -0
  268. package/src/construct-vectors.spec.ts +175 -0
  269. package/src/elements/adw-application-window.ts +154 -0
  270. package/src/elements/adw-bin.ts +101 -0
  271. package/src/elements/adw-breakpoint-bin.ts +287 -0
  272. package/src/elements/adw-clamp-scrollable.ts +207 -0
  273. package/src/elements/adw-dialog.ts +19 -0
  274. package/src/elements/adw-layout-slot.ts +95 -0
  275. package/src/elements/adw-multi-layout-view.ts +326 -0
  276. package/src/elements/adw-preferences-row.ts +150 -0
  277. package/src/elements/adw-shortcuts-dialog.ts +52 -0
  278. package/src/elements/adw-shortcuts-item.ts +171 -0
  279. package/src/elements/adw-shortcuts-section.ts +86 -0
  280. package/src/elements/adw-sidebar.ts +42 -3
  281. package/src/elements/adw-switch-row.ts +28 -1
  282. package/src/elements/adw-tab-bar.ts +529 -0
  283. package/src/elements/adw-tab-button.ts +194 -0
  284. package/src/elements/adw-tab-overview.ts +1011 -0
  285. package/src/elements/adw-tab-view.ts +66 -145
  286. package/src/elements/adw-toggle-group.ts +20 -5
  287. package/src/elements/adw-view-stack.ts +18 -0
  288. package/src/elements/adw-view-switcher-sidebar.ts +332 -0
  289. package/src/elements/adw-window.ts +185 -11
  290. package/src/elements/checks.ts +35 -8
  291. package/src/elements/gtk-about-dialog.ts +811 -0
  292. package/src/elements/gtk-application-window.ts +108 -0
  293. package/src/elements/gtk-aspect-frame.ts +160 -0
  294. package/src/elements/gtk-button.ts +12 -0
  295. package/src/elements/gtk-calendar.ts +757 -0
  296. package/src/elements/gtk-center-box.ts +184 -0
  297. package/src/elements/gtk-color-dialog-button.ts +278 -0
  298. package/src/elements/gtk-column-view.ts +320 -0
  299. package/src/elements/gtk-drag-icon.ts +257 -0
  300. package/src/elements/gtk-drawing-area.ts +303 -0
  301. package/src/elements/gtk-editable-label.ts +204 -0
  302. package/src/elements/gtk-emoji-chooser.ts +542 -0
  303. package/src/elements/gtk-entry.ts +39 -5
  304. package/src/elements/gtk-expander.ts +301 -0
  305. package/src/elements/gtk-fixed.ts +99 -0
  306. package/src/elements/gtk-flow-box-child.ts +68 -0
  307. package/src/elements/gtk-flow-box.ts +480 -0
  308. package/src/elements/gtk-font-dialog-button.ts +432 -0
  309. package/src/elements/gtk-frame.ts +174 -0
  310. package/src/elements/gtk-gl-area.ts +476 -0
  311. package/src/elements/gtk-graphics-offload.ts +130 -0
  312. package/src/elements/gtk-grid-view.ts +168 -0
  313. package/src/elements/gtk-grid.ts +127 -0
  314. package/src/elements/gtk-header-bar.ts +273 -0
  315. package/src/elements/gtk-inscription.ts +387 -0
  316. package/src/elements/gtk-label.ts +19 -11
  317. package/src/elements/gtk-level-bar.ts +323 -0
  318. package/src/elements/gtk-link-button.ts +138 -0
  319. package/src/elements/gtk-list-box-row.ts +195 -0
  320. package/src/elements/gtk-list-box.ts +413 -0
  321. package/src/elements/gtk-list-view.ts +370 -0
  322. package/src/elements/gtk-media-controls.ts +509 -0
  323. package/src/elements/gtk-notebook.ts +664 -0
  324. package/src/elements/gtk-overlay.ts +149 -0
  325. package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
  326. package/src/elements/gtk-paned.ts +597 -0
  327. package/src/elements/gtk-password-entry.ts +170 -0
  328. package/src/elements/gtk-picture.ts +254 -0
  329. package/src/elements/gtk-popover-bin.ts +332 -0
  330. package/src/elements/gtk-popover-menu-bar.ts +355 -0
  331. package/src/elements/gtk-popover-menu.ts +339 -0
  332. package/src/elements/gtk-popover.ts +92 -10
  333. package/src/elements/gtk-print-unix-dialog.ts +989 -0
  334. package/src/elements/gtk-progress-bar.ts +24 -11
  335. package/src/elements/gtk-revealer.ts +406 -0
  336. package/src/elements/gtk-scale-button.ts +358 -0
  337. package/src/elements/gtk-scale.ts +492 -0
  338. package/src/elements/gtk-scrollbar.ts +528 -0
  339. package/src/elements/gtk-scrolled-window.ts +642 -0
  340. package/src/elements/gtk-search-bar.ts +200 -0
  341. package/src/elements/gtk-search-entry.ts +172 -0
  342. package/src/elements/gtk-separator.ts +52 -0
  343. package/src/elements/gtk-spin-button.ts +475 -0
  344. package/src/elements/gtk-spinner.ts +126 -0
  345. package/src/elements/gtk-stack-sidebar.ts +212 -0
  346. package/src/elements/gtk-stack-switcher.ts +279 -0
  347. package/src/elements/gtk-stack.ts +748 -0
  348. package/src/elements/gtk-switch.ts +52 -19
  349. package/src/elements/gtk-text-view.ts +290 -0
  350. package/src/elements/gtk-text.ts +219 -0
  351. package/src/elements/gtk-toggle-button.ts +239 -0
  352. package/src/elements/gtk-tree-expander.ts +243 -0
  353. package/src/elements/gtk-video.ts +423 -0
  354. package/src/elements/gtk-viewport.ts +277 -0
  355. package/src/elements/gtk-window-controls.ts +341 -0
  356. package/src/elements/gtk-window-handle.ts +221 -0
  357. package/src/elements/gtk-window.ts +366 -0
  358. package/src/elements/justification.ts +24 -0
  359. package/src/elements/popover-menu.ts +24 -0
  360. package/src/elements/roving-focus.ts +53 -21
  361. package/src/emoji-data.ts +577 -0
  362. package/src/entry-rows.spec.ts +31 -0
  363. package/src/font-description.ts +238 -0
  364. package/src/gtk-about-dialog.spec.ts +250 -0
  365. package/src/gtk-action-bar.spec.ts +89 -0
  366. package/src/gtk-application-window.spec.ts +107 -0
  367. package/src/gtk-aspect-frame.spec.ts +114 -0
  368. package/src/gtk-calendar.spec.ts +589 -0
  369. package/src/gtk-center-box.spec.ts +125 -0
  370. package/src/gtk-color-dialog-button.spec.ts +141 -0
  371. package/src/gtk-column-view.spec.ts +154 -0
  372. package/src/gtk-drag-icon.spec.ts +190 -0
  373. package/src/gtk-drawing-area.spec.ts +211 -0
  374. package/src/gtk-editable-label.spec.ts +190 -0
  375. package/src/gtk-emoji-chooser.spec.ts +173 -0
  376. package/src/gtk-entry.spec.ts +23 -0
  377. package/src/gtk-expander.spec.ts +170 -0
  378. package/src/gtk-fixed.spec.ts +97 -0
  379. package/src/gtk-flow-box.spec.ts +289 -0
  380. package/src/gtk-font-dialog-button.spec.ts +166 -0
  381. package/src/gtk-frame.spec.ts +119 -0
  382. package/src/gtk-gl-area.spec.ts +361 -0
  383. package/src/gtk-graphics-offload.spec.ts +119 -0
  384. package/src/gtk-grid-view.spec.ts +106 -0
  385. package/src/gtk-grid.spec.ts +122 -0
  386. package/src/gtk-header-bar.spec.ts +202 -0
  387. package/src/gtk-inscription.spec.ts +235 -0
  388. package/src/gtk-level-bar.spec.ts +199 -0
  389. package/src/gtk-link-button.spec.ts +117 -0
  390. package/src/gtk-list-box.spec.ts +422 -0
  391. package/src/gtk-list-view.spec.ts +203 -0
  392. package/src/gtk-media-controls.spec.ts +295 -0
  393. package/src/gtk-notebook.spec.ts +546 -0
  394. package/src/gtk-overlay.spec.ts +141 -0
  395. package/src/gtk-paned.spec.ts +267 -0
  396. package/src/gtk-password-entry.spec.ts +150 -0
  397. package/src/gtk-picture.spec.ts +172 -0
  398. package/src/gtk-popover-bin.spec.ts +229 -0
  399. package/src/gtk-popover-menu-bar.spec.ts +296 -0
  400. package/src/gtk-popover-menu.spec.ts +261 -0
  401. package/src/gtk-popover-role.spec.ts +138 -0
  402. package/src/gtk-popover.spec.ts +264 -0
  403. package/src/gtk-print-dialogs.spec.ts +251 -0
  404. package/src/gtk-revealer.spec.ts +164 -0
  405. package/src/gtk-scale-button.spec.ts +218 -0
  406. package/src/gtk-scale.spec.ts +213 -0
  407. package/src/gtk-scrollbar.spec.ts +244 -0
  408. package/src/gtk-scrolled-window.spec.ts +262 -0
  409. package/src/gtk-search-bar.spec.ts +179 -0
  410. package/src/gtk-search-entry.spec.ts +142 -0
  411. package/src/gtk-separator.spec.ts +74 -0
  412. package/src/gtk-spin-button.spec.ts +186 -0
  413. package/src/gtk-spinner.spec.ts +130 -0
  414. package/src/gtk-stack-sidebar.spec.ts +217 -0
  415. package/src/gtk-stack-switcher.spec.ts +249 -0
  416. package/src/gtk-stack.spec.ts +432 -0
  417. package/src/gtk-text-view.spec.ts +189 -0
  418. package/src/gtk-text.spec.ts +163 -0
  419. package/src/gtk-toggle-button.spec.ts +186 -0
  420. package/src/gtk-tree-expander.spec.ts +201 -0
  421. package/src/gtk-video.spec.ts +240 -0
  422. package/src/gtk-viewport.spec.ts +140 -0
  423. package/src/gtk-window-controls.spec.ts +232 -0
  424. package/src/gtk-window-handle.spec.ts +158 -0
  425. package/src/gtk-window.spec.ts +190 -0
  426. package/src/index.ts +9 -1
  427. package/src/keyboard-operable.spec.ts +33 -1
  428. package/src/list-view-dom.ts +121 -0
  429. package/src/namespace/adw.ts +12 -0
  430. package/src/namespace/gtk.ts +61 -0
  431. package/src/page-setup.ts +222 -0
  432. package/src/scroll-shading.ts +18 -1
  433. package/src/shared-tree-builder.ts +263 -21
  434. package/src/signals.ts +15 -0
  435. package/src/source-view/theme.ts +11 -5
  436. package/src/style-classes.spec.ts +9 -8
  437. package/src/styles.generated.ts +1 -1
  438. package/src/tab-chip.ts +200 -0
  439. package/src/template-classes.ts +45 -0
  440. package/src/test.browser.mts +152 -0
@@ -0,0 +1,476 @@
1
+ // <gtk-gl-area> — a widget whose contents are drawn on a GPU.
2
+ //
3
+ // WHAT THE C DOES, IN ORDER, because the ORDER is the contract a GL application
4
+ // depends on (gtkglarea.c:757-812, the snapshot):
5
+ //
6
+ // · it works in DEVICE pixels: `w = width * scale`, `h = height * scale` (:761-763);
7
+ // · an empty allocation draws NOTHING at all — `:767-768`;
8
+ // · an error set draws the error MESSAGE over the widget and stops (:769-775,
9
+ // `gtk_gl_area_draw_error_screen` at :701-723) — not an empty box, and not a
10
+ // context attempt;
11
+ // · no context draws nothing (:776-777);
12
+ // · otherwise: make the context current, attach the buffers, enable or disable the
13
+ // depth test, and — only if `needs_render || auto_render` — emit `::resize` FIRST
14
+ // if the allocation changed, then emit `::render` (:779-811). `needs_render` is
15
+ // cleared after the emit, so a `queue_render()` from a handler queues its frame and
16
+ // loses its flag — which is why a GL animation asks per tick, not from `::render`.
17
+ //
18
+ // `needs_render` starts TRUE and `needs_resize` is set by `size_allocate` whenever the
19
+ // widget is allocated a new size while realized (:686-697, :1104) — so the first draw
20
+ // emits `resize` before `render`, which is the order every GL program needs.
21
+ //
22
+ // WHAT A BROWSER CHANGES, ALL OF IT WRITTEN HERE RATHER THAN LEFT TO THE READER:
23
+ //
24
+ // · THE CONTEXT IS THE BROWSER'S. `GdkGLContext` comes from a GdkSurface; a
25
+ // `<canvas>`'s `getContext` hands out WebGL, which is ES-flavoured on every engine.
26
+ // `allowed-apis` therefore chooses between ES VERSIONS here and `api` reports
27
+ // `gles` whichever it got: GTK's GL/GLES split has no counterpart in a web page,
28
+ // and saying so is more useful than a flag that pretends otherwise. An
29
+ // `allowed-apis` naming NEITHER creates no context, and the snapshot's no-context
30
+ // branch (:776-777) is what a reader then sees.
31
+ // · THE BUFFER PERSISTS. WebGL clears the drawing buffer after compositing unless the
32
+ // context is created with `preserveDrawingBuffer`, and GTK's texture does not
33
+ // disappear between frames — so the element asks for it, which is the one creation
34
+ // option here with a direct counterpart in the C (a texture GTK keeps).
35
+ // · THERE IS NO FRAME CLOCK. GTK's snapshot runs when GTK DRAWS the widget, and an
36
+ // application animating a GLArea queues a redraw per tick
37
+ // (`gtk_widget_queue_draw`). The element therefore draws on the first allocation, on
38
+ // `queueRender()`, and on the property writes that end in `queue_draw` — and an
39
+ // application that wants sixty frames a second asks for them, exactly as it would
40
+ // in GTK. `auto-render` is still the same flag over the same condition; what it
41
+ // gates is whether a draw the element was asked for ends in `::render`.
42
+ // · `make_current` is the browser's standing arrangement: a WebGL context is current
43
+ // for its own canvas and nowhere else (:1563-1572), so the method hands the context
44
+ // back rather than switching anything.
45
+ //
46
+ // A11Y: no role, and none invented. GtkGLArea sets no accessible role of its own, and a
47
+ // GL surface is as opaque to a screen reader as it is to the compositor; an application
48
+ // that draws text owes the reader a label, which an ordinary `aria-label` provides.
49
+ //
50
+ // Events: `render` (CustomEvent, bubbles, detail `{ context }`), `resize` (CustomEvent,
51
+ // bubbles, detail `{ width, height }` — the C's DEVICE-pixel viewport, :1055-1062) and
52
+ // `create-context` (CustomEvent, bubbles, detail `{ context }`, which a handler may fill
53
+ // instead of letting the element ask the browser), plus `notify::<prop>`.
54
+ //
55
+ // KNOWN GAPS: `use-es`, deprecated in GTK 4.12 and replaced by `allowed-apis`; it is
56
+ // listed in KNOWN_GAPS in scripts/check-adwaita-element-properties.mjs.
57
+ //
58
+ // Reference: refs/gtk/gtk/gtkglarea.c
59
+ // Copyright (c) The GTK Team. LGPLv2.1+.
60
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
61
+
62
+ /** `GdkGLAPI`'s nicks, as `GdkGLAPINickSet` spells them. */
63
+ const APIS = ['gl', 'gles'] as const;
64
+ type GlApi = (typeof APIS)[number];
65
+
66
+ /** A WebGL context, whichever version the browser handed out. */
67
+ type GlContext = WebGLRenderingContext | WebGL2RenderingContext;
68
+
69
+ /**
70
+ * `allowed-apis`, parsed: GdkGLAPIFlags is a FLAGS property, so it is a SET, and a
71
+ * browser attribute carries a set as a space-separated list of nicks (`gl gles`). An
72
+ * unparseable or absent value is the GIR default, `GDK_GL_API_GL | GDK_GL_API_GLES`
73
+ * (gtkglarea.c:1098-1101).
74
+ */
75
+ function parseApis(element: HTMLElement): GlApi[] {
76
+ const raw = element.getAttribute('allowed-apis');
77
+ if (raw === null) return [...APIS];
78
+ const names = raw.split(/[\s,|]+/).filter((token) => (APIS as readonly string[]).includes(token));
79
+ return APIS.filter((api) => names.includes(api));
80
+ }
81
+
82
+ function booleanAttribute(element: HTMLElement, name: string, fallback: boolean): boolean {
83
+ const raw = element.getAttribute(name);
84
+ if (raw === null) return fallback;
85
+ return raw !== 'false' && raw !== '0';
86
+ }
87
+
88
+ export class GtkGLArea extends HTMLElement {
89
+ private _canvas!: HTMLCanvasElement;
90
+ private _messageEl: HTMLDivElement | null = null;
91
+ private _initialized = false;
92
+ private _context: GlContext | null = null;
93
+ private _error: string | null = null;
94
+ /** `gtk_gl_area_resize` is called from here, so `needs_resize` is a C field too. */
95
+ private _needsResize = false;
96
+ /** `priv->needs_render`, TRUE from `gtk_gl_area_init` (:1104). */
97
+ /** `priv->allowed_apis`, default `GDK_GL_API_GL | GDK_GL_API_GLES` (:1100). */
98
+ private _allowedApis: GlApi[] = [...APIS];
99
+ private _needsRender = true;
100
+ /** `priv->have_buffers` (:392), dropped by the two buffer setters. */
101
+ private _haveBuffers = false;
102
+ private _width = 0;
103
+ private _height = 0;
104
+ private _scale = 1;
105
+ private _resize: ResizeObserver | null = null;
106
+ private _frame: number | null = null;
107
+
108
+ static get observedAttributes() {
109
+ return ['auto-render', 'has-depth-buffer', 'has-stencil-buffer', 'allowed-apis'];
110
+ }
111
+
112
+ /**
113
+ * `GtkGLArea:auto-render` — whether `::render` is emitted every time the widget draws.
114
+ * Defaults to TRUE (:1102, and `g_param_spec_boolean` at :924).
115
+ */
116
+ get autoRender(): boolean {
117
+ return booleanAttribute(this, 'auto-render', true);
118
+ }
119
+
120
+ set autoRender(v: boolean) {
121
+ if (this.autoRender === !!v) return;
122
+ this._write('auto-render', String(!!v));
123
+ }
124
+
125
+ /**
126
+ * `GtkGLArea:has-depth-buffer` — whether a depth buffer is allocated and the depth
127
+ * test enabled (:782-785, :408-417). Defaults to FALSE (:941).
128
+ */
129
+ get hasDepthBuffer(): boolean {
130
+ return booleanAttribute(this, 'has-depth-buffer', false);
131
+ }
132
+
133
+ set hasDepthBuffer(v: boolean) {
134
+ if (this.hasDepthBuffer === !!v) return;
135
+ this._write('has-depth-buffer', String(!!v));
136
+ }
137
+
138
+ /** `GtkGLArea:has-stencil-buffer` — the stencil half of the same renderbuffer (:954). */
139
+ get hasStencilBuffer(): boolean {
140
+ return booleanAttribute(this, 'has-stencil-buffer', false);
141
+ }
142
+
143
+ set hasStencilBuffer(v: boolean) {
144
+ if (this.hasStencilBuffer === !!v) return;
145
+ this._write('has-stencil-buffer', String(!!v));
146
+ }
147
+
148
+ /**
149
+ * `GtkGLArea:allowed-apis` — the APIs a created context may use (:983, :1100).
150
+ *
151
+ * The value lives in a field, not in the attribute, because the setter REFUSES a
152
+ * realized area and a refused write in a custom element has already moved the
153
+ * attribute — the C keeps the property and drops the call, this keeps the property and
154
+ * puts the attribute back.
155
+ */
156
+ get allowedApis(): GlApi[] {
157
+ return [...this._allowedApis];
158
+ }
159
+
160
+ set allowedApis(v: GlApi[]) {
161
+ if (this._context !== null) {
162
+ // `g_return_if_fail (!gtk_widget_get_realized (…))` (:1242) — see the header.
163
+ // `_write` rather than `setAttribute`: the write-back fires this callback
164
+ // again, and the guard stops it when the value is already the one in force.
165
+ this._write('allowed-apis', this._allowedApis.join(' '));
166
+ return;
167
+ }
168
+ this._allowedApis = APIS.filter((api) => v.includes(api));
169
+ this._write('allowed-apis', this._allowedApis.join(' '));
170
+ }
171
+
172
+ /**
173
+ * The guard that makes "notify only on a real change" true: `setAttribute` runs the
174
+ * custom-element reaction for a write that changes nothing, while GTK's setters
175
+ * return early (:1522, :1197).
176
+ */
177
+ private _write(name: string, value: string): void {
178
+ if (this.getAttribute(name) !== value) this.setAttribute(name, value);
179
+ }
180
+
181
+ /**
182
+ * `GtkGLArea:api` — the API in use, read-only in the GIR and defaulting to 0, which
183
+ * is `GDK_GL_API_GL`. A context in a browser is WebGL or WebGL2, both ES, so a
184
+ * realized area reports `gles` and an unrealized one the pspec's `0` — see the header.
185
+ */
186
+ get api(): GlApi {
187
+ return this._context === null ? 'gl' : 'gles';
188
+ }
189
+
190
+ /** `gtk_gl_area_get_context` (:1495-1508) — the context, or `null` when there is none. */
191
+ get context(): GlContext | null {
192
+ return this._context;
193
+ }
194
+
195
+ /** `gtk_gl_area_get_error` (:1533-1543) — the error set on the area, if any. */
196
+ get error(): string | null {
197
+ return this._error;
198
+ }
199
+
200
+ /** `gtk_gl_area_set_error` (:1545-1558). `null` clears it, which restores drawing. */
201
+ setError(error: Error | string | null): void {
202
+ const message = error === null ? null : typeof error === 'string' ? error : error.message;
203
+ if (this._error === message) return;
204
+ this._error = message;
205
+ this._renderMessage();
206
+ // An error stops the draw; `set_error` queues a redraw so the message shows
207
+ // (:1552-1556) and drawing resumes when it is cleared.
208
+ this._queueDraw();
209
+ }
210
+
211
+ /**
212
+ * `gtk_gl_area_make_current` (:1563-1572). A WebGL context is current for its own
213
+ * canvas and nowhere else, so there is nothing to switch — the method exists
214
+ * because the C's callers expect it to.
215
+ */
216
+ makeCurrent(): GlContext | null {
217
+ return this._context;
218
+ }
219
+
220
+ /**
221
+ * `gtk_gl_area_queue_render` (:1465-1474) — the render flag plus `queue_draw`.
222
+ *
223
+ * AND WHY THE DRAW IS NOT SYNCHRONOUS. `gtk_widget_queue_draw` marks the window dirty
224
+ * and the frame clock draws it LATER, so an application that queues per tick animates
225
+ * instead of recursing; a 2D-style synchronous draw would make the same application a
226
+ * stack overflow. An animation frame is the browser's frame clock, and coalescing
227
+ * through one keeps "ask for a frame" a scheduler.
228
+ *
229
+ * NOTE WHAT THE FLAG DOES NOT SURVIVE: `needs_render` is cleared AFTER the `::render`
230
+ * emit (:811), so a `queue_render()` from inside the handler has its flag overwritten
231
+ * and only the queued frame remains. That is the C's own behaviour, and it is why an
232
+ * animation asks from a tick callback rather than from the handler.
233
+ */
234
+ queueRender(): void {
235
+ this._needsRender = true;
236
+ this._queueDraw();
237
+ }
238
+
239
+ connectedCallback() {
240
+ if (this._initialized) {
241
+ // The teardown below released the observer on the way out, so a re-parent has
242
+ // to arm it again — see `scripts/check-adwaita-connect-rebind.mjs`.
243
+ this._observe();
244
+ return;
245
+ }
246
+ this._initialized = true;
247
+
248
+ // An attribute written before the element upgraded fires `attributeChangedCallback`
249
+ // with `_initialized` still false, so the authored set is read here — the C reads
250
+ // it at realize, which is the same moment as far as this property is concerned.
251
+ if (this.hasAttribute('allowed-apis')) this._allowedApis = parseApis(this);
252
+
253
+ this._canvas = document.createElement('canvas');
254
+ this._canvas.className = 'adw-gl-area-canvas';
255
+ this.replaceChildren(this._canvas);
256
+ this._observe();
257
+ }
258
+
259
+ disconnectedCallback() {
260
+ this._resize?.disconnect();
261
+ this._resize = null;
262
+ if (this._frame !== null) cancelAnimationFrame(this._frame);
263
+ this._frame = null;
264
+ }
265
+
266
+ /** `gtk_widget_queue_draw`: one frame, however many requests arrived before it. */
267
+ private _queueDraw(): void {
268
+ if (!this._initialized || this._frame !== null) return;
269
+ this._frame = requestAnimationFrame(() => {
270
+ this._frame = null;
271
+ this._draw();
272
+ });
273
+ }
274
+
275
+ attributeChangedCallback(name: string) {
276
+ if (!this._initialized) return;
277
+ switch (name) {
278
+ case 'auto-render':
279
+ // `set_auto_render` queues a redraw, and only when it is turned ON
280
+ // (:1528-1529).
281
+ if (this.autoRender) this._queueDraw();
282
+ break;
283
+ case 'has-depth-buffer':
284
+ case 'has-stencil-buffer':
285
+ // Neither setter queues: they notify and drop `have_buffers` (:1391-1396,
286
+ // :1440-1447), which the next draw re-attaches.
287
+ this._haveBuffers = false;
288
+ break;
289
+ case 'allowed-apis':
290
+ // `gtk_gl_area_set_allowed_apis` REFUSES a realized area
291
+ // (`g_return_if_fail (!gtk_widget_get_realized (…))`, :1242) — the context
292
+ // is built from the set once, and a browser canvas has one context for its
293
+ // lifetime. A custom element cannot refuse an attribute write the way the C
294
+ // refuses a call, so the write is undone: the attribute goes back to the set
295
+ // in force, which is the state the property keeps, and nothing notifies. The
296
+ // page can see the refusal; the C only warns. `_write` rather than
297
+ // `setAttribute`: this write fires the callback again, and the guard is what
298
+ // stops the second pass from writing a third.
299
+ if (this._context !== null) {
300
+ this._write('allowed-apis', this._allowedApis.join(' '));
301
+ return;
302
+ }
303
+ this._allowedApis = parseApis(this);
304
+ break;
305
+ default:
306
+ break;
307
+ }
308
+ this._notify(name);
309
+ }
310
+
311
+ /** The `notify::` detail for `name`: the PROPERTY, parsed, not the raw attribute. */
312
+ private _notify(name: string): void {
313
+ const value: string | boolean =
314
+ name === 'allowed-apis'
315
+ ? this.allowedApis.join(' ')
316
+ : name === 'auto-render'
317
+ ? this.autoRender
318
+ : name === 'has-depth-buffer'
319
+ ? this.hasDepthBuffer
320
+ : this.hasStencilBuffer;
321
+ this.dispatchEvent(new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: value } }));
322
+ }
323
+
324
+ private _observe(): void {
325
+ if (this._resize) return;
326
+ // The first observation is the realize: `size_allocate` sets `needs_resize` for
327
+ // every allocation while realized (:693-696), and the draw that answers it emits
328
+ // `::resize` before `::render`.
329
+ this._resize = new ResizeObserver((entries) => {
330
+ for (const entry of entries) {
331
+ const box = entry.borderBoxSize?.[0];
332
+ const width = box ? box.inlineSize : entry.contentRect.width;
333
+ const height = box ? box.blockSize : entry.contentRect.height;
334
+ if (width === this._width && height === this._height) continue;
335
+ this._width = width;
336
+ this._height = height;
337
+ this._needsResize = true;
338
+ this._queueDraw();
339
+ }
340
+ });
341
+ this._resize.observe(this);
342
+ }
343
+
344
+ /**
345
+ * The snapshot, in the C's order (gtkglarea.c:757-812). One pass, four early exits,
346
+ * and the two flags cleared only after the signals — see the header.
347
+ */
348
+ private _draw(): void {
349
+ if (!this._canvas) return;
350
+ const scale = typeof window === 'undefined' ? 1 : window.devicePixelRatio || 1;
351
+ this._scale = scale;
352
+ // The viewport is in DEVICE pixels (:761-763), which is also what a canvas's
353
+ // backing store is.
354
+ const width = Math.round(this._width * scale);
355
+ const height = Math.round(this._height * scale);
356
+ if (width === 0 || height === 0) return;
357
+
358
+ if (this._error !== null) {
359
+ this._renderMessage();
360
+ return;
361
+ }
362
+ const context = this._context ?? this._createContext();
363
+ if (context === null) return;
364
+
365
+ this.makeCurrent();
366
+ this.attachBuffers(context);
367
+ // `glEnable`/`glDisable (GL_DEPTH_TEST)` per `has-depth-buffer` (:782-785).
368
+ // As in `attachBuffers`: a handler-supplied context may not be a WebGL one at all,
369
+ // and a missing call is skipped rather than thrown (:782-785).
370
+ if (this.hasDepthBuffer) context.enable?.(context.DEPTH_TEST);
371
+ else context.disable?.(context.DEPTH_TEST);
372
+
373
+ if (this._needsRender || this.autoRender) {
374
+ if (this._needsResize) {
375
+ this._needsResize = false;
376
+ this.dispatchEvent(new CustomEvent('resize', { bubbles: true, detail: { width, height } }));
377
+ }
378
+ this.dispatchEvent(new CustomEvent('render', { bubbles: true, detail: { context } }));
379
+ }
380
+ this._needsRender = false;
381
+ }
382
+
383
+ /**
384
+ * `gtk_gl_area_attach_buffers` (:583-618): the depth/stencil renderbuffer is created
385
+ * when either buffer is asked for and deleted when neither is — and `have_buffers`
386
+ * says which, so a redraw after one of the two setters is the frame that allocates
387
+ * it (:408-417). WebGL's equivalent is the depth and stencil TESTS plus the
388
+ * `depth`/`stencil` context attributes the element created the context with: a context
389
+ * cannot gain a buffer afterwards, which is why `_createContext` reads both properties
390
+ * before asking, and why the flag is what decides the tests are re-applied.
391
+ */
392
+ attachBuffers(context: GlContext | null = this._context): void {
393
+ if (context === null) return;
394
+ // The C calls `glEnable`/`glDisable` straight (:583-618), because a `GdkGLContext`
395
+ // always has them. A `create-context` handler in a browser can hand the element
396
+ // anything at all — the spec's own case is a 2D context — so the calls are made
397
+ // where they exist and skipped where they do not, rather than throwing out of a
398
+ // frame the C would have drawn.
399
+ if (this.hasStencilBuffer) context.enable?.(context.STENCIL_TEST);
400
+ else context.disable?.(context.STENCIL_TEST);
401
+ // The C's `have_buffers` guard: with the buffers already attached and nothing
402
+ // resized, `attach_buffers` has nothing to do (:396-397).
403
+ this._haveBuffers = true;
404
+ }
405
+
406
+ /**
407
+ * `::create-context` (:1086-1109) lets a handler supply the context, and GTK's handler
408
+ * RETURNS one. A browser event has no return channel, so the detail object is the
409
+ * channel: a handler that sets `detail.context` wins, and the element asks the
410
+ * browser only when nobody did.
411
+ */
412
+ private _createContext(): GlContext | null {
413
+ const allowed = this.allowedApis;
414
+ if (allowed.length === 0) return null;
415
+ const detail: { context: GlContext | null } = { context: null };
416
+ this.dispatchEvent(new CustomEvent('create-context', { bubbles: true, detail }));
417
+ if (detail.context !== null) {
418
+ this._context = detail.context;
419
+ return this._context;
420
+ }
421
+ // `preserveDrawingBuffer` keeps the picture on screen between frames, which is
422
+ // what GTK's own texture does; the depth/stencil attributes are the buffers the C
423
+ // allocates in `attach_buffers`.
424
+ const attributes: WebGLContextAttributes = {
425
+ preserveDrawingBuffer: true,
426
+ depth: this.hasDepthBuffer,
427
+ stencil: this.hasStencilBuffer,
428
+ };
429
+ // WebGL2 (ES 3.0) is the newer of the two the browser has; `allowed-apis` naming
430
+ // only `gl` asks for the older one, because no browser offers desktop GL.
431
+ const names = allowed.includes('gles') ? ['webgl2', 'webgl'] : ['webgl'];
432
+ for (const name of names) {
433
+ const context = this._canvas.getContext(name, attributes) as GlContext | null;
434
+ if (context !== null) {
435
+ this._context = context;
436
+ return context;
437
+ }
438
+ }
439
+ return null;
440
+ }
441
+
442
+ /**
443
+ * `gtk_gl_area_draw_error_screen` (:701-723): the message over the whole widget, at
444
+ * its own font, vertically centred. The canvas stays where it is — GTK's error screen
445
+ * replaces what a frame would have drawn, not the widget's own node — and the message
446
+ * node is removed again when the error clears, which is the redraw the C's setter
447
+ * queues (:1552-1556).
448
+ */
449
+ private _renderMessage(): void {
450
+ if (this._error === null) {
451
+ this._messageEl?.remove();
452
+ this._messageEl = null;
453
+ return;
454
+ }
455
+ if (!this._messageEl) {
456
+ this._messageEl = document.createElement('div');
457
+ this._messageEl.className = 'adw-gl-area-error';
458
+ this.append(this._messageEl);
459
+ }
460
+ this._messageEl.textContent = this._error;
461
+ }
462
+
463
+ /** The device-pixel viewport, for a spec that checks `::resize`. */
464
+ get viewport(): { width: number; height: number } {
465
+ return {
466
+ width: Math.round(this._width * this._scale),
467
+ height: Math.round(this._height * this._scale),
468
+ };
469
+ }
470
+
471
+ /** The scale factor the viewport is multiplied by (gtkglarea.c:761-763). */
472
+ get pixelScale(): number {
473
+ return this._scale;
474
+ }
475
+ }
476
+ customElements.define('gtk-gl-area', GtkGLArea);
@@ -0,0 +1,130 @@
1
+ // <gtk-graphics-offload> — a wrapper that asks the compositor to take its ONE child
2
+ // as it is, skipping a texture round-trip that a frequently changing child would pay on
3
+ // every frame.
4
+ //
5
+ // WHAT THIS IS NOT, STATED FIRST BECAUSE IT IS THE FIRST THING A READER GETS WRONG. A web
6
+ // page cannot hand a surface to a compositor the way `gdk_surface_create_subsurface` does
7
+ // (`sync_subsurface`, gtkgraphicsoffload.c:176-191). There is no API on the platform for
8
+ // it and no CSS property that means it. So the element ports everything AROUND the
9
+ // passthrough, which is all of the widget's own behaviour:
10
+ //
11
+ // · the ENUM, with its default. `enabled` is `GTK_GRAPHICS_OFFLOAD_ENABLED` from the
12
+ // start (`:107-109`, `:267-273`) and takes one of two values; `set_enabled` returns
13
+ // early when it is already right, then `sync_subsurface`, `queue_draw` and a notify
14
+ // (`:366-380`). When offload is enabled the element sets `will-change: transform` on
15
+ // its own box, which is the browser's own statement that a layer may be composited
16
+ // without being drawn into a texture first — the closest thing on this platform to
17
+ // what the C asks GDK for, and the whole of what it can do.
18
+ // · the BLACK RECTANGLE. `black_background` paints `GDK_RGBA_BLACK` over the widget's
19
+ // whole allocation and THEN the child (`:213-233`), which is what letterboxing a video
20
+ // whose aspect ratio does not match the screen needs, and the reason the property
21
+ // exists at all rather than being a CSS class the application could add itself.
22
+ // · THE BIN LAYOUT. `GtkGraphicsOffload` installs `GTK_TYPE_BIN_LAYOUT` (`:290`), so the
23
+ // child is given the whole allocation rather than sized by anything of the wrapper's.
24
+ // · THE ORDER of the notify, which is the property order and never anything else.
25
+ //
26
+ // What GTK does NOT do is worth reading too, because it is the list of things an
27
+ // application must not put on top of an offloaded child (`:64-75`): rounded corners that
28
+ // clip the content, a transform more complex than a translation and a scale, a filter such
29
+ // as opacity or grayscale, and translucent content. None of them are enforced here — a
30
+ // browser decides what it composites — and the block says so rather than implying the
31
+ // passthrough is available.
32
+ //
33
+ // A11Y: no role. The widget is a bin (`:286-291`): it contributes no name, no role and no
34
+ // value of its own, and the child's own accessibility is what a screen reader should get.
35
+ //
36
+ // Events: `notify::<prop>` (CustomEvent, bubbles, detail `{ <prop>: value }`) on a real
37
+ // change. There is no `notify::child` from a slotted write — the child arrives as markup,
38
+ // which is the same answer `GtkOverlay` gives.
39
+ //
40
+ // Reference: refs/gtk/gtk/gtkgraphicsoffload.c
41
+ // Copyright (c) The GTK Team. LGPLv2.1+.
42
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
43
+
44
+ import { bindSlottedChildren } from '../slotted-children.js';
45
+
46
+ /** `GtkGraphicsOffloadEnabled`, spelled as the GIR's enum nicks. */
47
+ type OffloadEnabled = 'enabled' | 'disabled';
48
+
49
+ function booleanAttribute(element: HTMLElement, name: string, fallback: boolean): boolean {
50
+ const raw = element.getAttribute(name);
51
+ if (raw === null) return fallback;
52
+ return raw !== 'false' && raw !== '0';
53
+ }
54
+
55
+ export class GtkGraphicsOffload extends HTMLElement {
56
+ private _childEl!: HTMLDivElement;
57
+ private _initialized = false;
58
+
59
+ static get observedAttributes() {
60
+ return ['enabled', 'black-background'];
61
+ }
62
+
63
+ /** `Gtk.GraphicsOffload:child` — the child widget, as the light-DOM node adopted. */
64
+ get child(): Element | null {
65
+ return this._childEl?.firstElementChild ?? null;
66
+ }
67
+
68
+ /**
69
+ * `Gtk.GraphicsOffload:enabled` — whether the widget ATTEMPTS to offload its child's
70
+ * contents. Defaults to `GTK_GRAPHICS_OFFLOAD_ENABLED` (`:267-273`).
71
+ */
72
+ get enabled(): OffloadEnabled {
73
+ return this.getAttribute('enabled') === 'disabled' ? 'disabled' : 'enabled';
74
+ }
75
+
76
+ set enabled(v: OffloadEnabled) {
77
+ // `if (priv->enabled == enabled) return;` (:369) — the guard that makes the notify
78
+ // a change rather than an echo.
79
+ if (this.enabled === v) return;
80
+ this.setAttribute('enabled', v);
81
+ }
82
+
83
+ /** `Gtk.GraphicsOffload:black-background` — the black rect painted before the child. */
84
+ get blackBackground(): boolean {
85
+ return booleanAttribute(this, 'black-background', false);
86
+ }
87
+
88
+ set blackBackground(v: boolean) {
89
+ if (this.blackBackground === !!v) return;
90
+ this.setAttribute('black-background', String(!!v));
91
+ }
92
+
93
+ connectedCallback() {
94
+ if (this._initialized) return;
95
+ this._initialized = true;
96
+
97
+ this._childEl = document.createElement('div');
98
+ this._childEl.className = 'adw-graphics-offload-child';
99
+ // `GTK_TYPE_BIN_LAYOUT` gives the child the whole allocation, and `child` is the one
100
+ // GtkBuildable slot the widget has, so it is the default one here.
101
+ bindSlottedChildren(this, [{ into: this._childEl }]).install(this._childEl);
102
+ this.replaceChildren(this._childEl);
103
+ this._render();
104
+ }
105
+
106
+ attributeChangedCallback(name: string) {
107
+ if (!this._initialized) return;
108
+ if (name === 'enabled' || name === 'black-background') this._render();
109
+ this._notify(name);
110
+ }
111
+
112
+ /** `sync_subsurface` (:176-191): the subsurface exists while the widget is realized and offload is not disabled. */
113
+ private _render(): void {
114
+ const offloading = this.enabled !== 'disabled';
115
+ // The browser's own hint that this layer may be composited without a texture
116
+ // round-trip. It is not the passthrough — nothing on this platform is — and the
117
+ // block says so where a reader would otherwise assume parity.
118
+ this.style.willChange = offloading ? 'transform' : '';
119
+ // `gtk_snapshot_append_color (… GDK_RGBA_BLACK …)` over the whole allocation, before
120
+ // the child (:222-229): a background, which is what makes the letterbox bars black.
121
+ this.style.backgroundColor = this.blackBackground ? '#000000' : '';
122
+ }
123
+
124
+ private _notify(name: string): void {
125
+ const value: string | boolean = name === 'enabled' ? this.enabled : this.blackBackground;
126
+ this.dispatchEvent(new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: value } }));
127
+ }
128
+ }
129
+
130
+ customElements.define('gtk-graphics-offload', GtkGraphicsOffload);