@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.
- package/dist/adwaita-web.css +8070 -3037
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/adw-application-window.spec.d.ts +1 -0
- package/lib/types/adw-bin.spec.d.ts +1 -0
- package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
- package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
- package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
- package/lib/types/adw-preferences-row.spec.d.ts +1 -0
- package/lib/types/adw-shortcuts.spec.d.ts +1 -0
- package/lib/types/adw-tab-bar.spec.d.ts +1 -0
- package/lib/types/adw-tab-button.spec.d.ts +1 -0
- package/lib/types/adw-tab-overview.spec.d.ts +1 -0
- package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
- package/lib/types/adw-window.spec.d.ts +1 -0
- package/lib/types/breakpoints.d.ts +14 -3
- package/lib/types/construct-vectors.spec.d.ts +1 -0
- package/lib/types/elements/adw-application-window.d.ts +27 -0
- package/lib/types/elements/adw-bin.d.ts +17 -0
- package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
- package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
- package/lib/types/elements/adw-dialog.d.ts +10 -0
- package/lib/types/elements/adw-layout-slot.d.ts +19 -0
- package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
- package/lib/types/elements/adw-preferences-row.d.ts +31 -0
- package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
- package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
- package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
- package/lib/types/elements/adw-sidebar.d.ts +5 -0
- package/lib/types/elements/adw-switch-row.d.ts +3 -0
- package/lib/types/elements/adw-tab-bar.d.ts +108 -0
- package/lib/types/elements/adw-tab-button.d.ts +32 -0
- package/lib/types/elements/adw-tab-overview.d.ts +199 -0
- package/lib/types/elements/adw-tab-view.d.ts +19 -23
- package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
- package/lib/types/elements/adw-window.d.ts +40 -0
- package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
- package/lib/types/elements/gtk-application-window.d.ts +34 -0
- package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
- package/lib/types/elements/gtk-button.d.ts +9 -0
- package/lib/types/elements/gtk-calendar.d.ts +159 -0
- package/lib/types/elements/gtk-center-box.d.ts +39 -0
- package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
- package/lib/types/elements/gtk-column-view.d.ts +50 -0
- package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
- package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
- package/lib/types/elements/gtk-editable-label.d.ts +33 -0
- package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
- package/lib/types/elements/gtk-entry.d.ts +20 -1
- package/lib/types/elements/gtk-expander.d.ts +49 -0
- package/lib/types/elements/gtk-fixed.d.ts +13 -0
- package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
- package/lib/types/elements/gtk-flow-box.d.ts +87 -0
- package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
- package/lib/types/elements/gtk-frame.d.ts +24 -0
- package/lib/types/elements/gtk-gl-area.d.ts +136 -0
- package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
- package/lib/types/elements/gtk-grid-view.d.ts +39 -0
- package/lib/types/elements/gtk-grid.d.ts +27 -0
- package/lib/types/elements/gtk-header-bar.d.ts +60 -0
- package/lib/types/elements/gtk-inscription.d.ts +64 -0
- package/lib/types/elements/gtk-label.d.ts +3 -0
- package/lib/types/elements/gtk-level-bar.d.ts +59 -0
- package/lib/types/elements/gtk-link-button.d.ts +29 -0
- package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
- package/lib/types/elements/gtk-list-box.d.ts +100 -0
- package/lib/types/elements/gtk-list-view.d.ts +73 -0
- package/lib/types/elements/gtk-media-controls.d.ts +142 -0
- package/lib/types/elements/gtk-notebook.d.ts +148 -0
- package/lib/types/elements/gtk-overlay.d.ts +22 -0
- package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
- package/lib/types/elements/gtk-paned.d.ts +121 -0
- package/lib/types/elements/gtk-password-entry.d.ts +27 -0
- package/lib/types/elements/gtk-picture.d.ts +66 -0
- package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
- package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
- package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
- package/lib/types/elements/gtk-popover.d.ts +28 -3
- package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
- package/lib/types/elements/gtk-revealer.d.ts +55 -0
- package/lib/types/elements/gtk-scale-button.d.ts +59 -0
- package/lib/types/elements/gtk-scale.d.ts +98 -0
- package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
- package/lib/types/elements/gtk-scrolled-window.d.ts +121 -0
- package/lib/types/elements/gtk-search-bar.d.ts +39 -0
- package/lib/types/elements/gtk-search-entry.d.ts +27 -0
- package/lib/types/elements/gtk-separator.d.ts +10 -0
- package/lib/types/elements/gtk-spin-button.d.ts +94 -0
- package/lib/types/elements/gtk-spinner.d.ts +14 -0
- package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
- package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
- package/lib/types/elements/gtk-stack.d.ts +154 -0
- package/lib/types/elements/gtk-switch.d.ts +4 -1
- package/lib/types/elements/gtk-text-view.d.ts +62 -0
- package/lib/types/elements/gtk-text.d.ts +45 -0
- package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
- package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
- package/lib/types/elements/gtk-video.d.ts +97 -0
- package/lib/types/elements/gtk-viewport.d.ts +84 -0
- package/lib/types/elements/gtk-window-controls.d.ts +80 -0
- package/lib/types/elements/gtk-window-handle.d.ts +39 -0
- package/lib/types/elements/gtk-window.d.ts +97 -0
- package/lib/types/elements/justification.d.ts +2 -0
- package/lib/types/elements/popover-menu.d.ts +18 -0
- package/lib/types/elements/roving-focus.d.ts +29 -1
- package/lib/types/emoji-data.d.ts +38 -0
- package/lib/types/font-description.d.ts +96 -0
- package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
- package/lib/types/gtk-action-bar.spec.d.ts +1 -0
- package/lib/types/gtk-application-window.spec.d.ts +1 -0
- package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
- package/lib/types/gtk-calendar.spec.d.ts +1 -0
- package/lib/types/gtk-center-box.spec.d.ts +1 -0
- package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
- package/lib/types/gtk-column-view.spec.d.ts +1 -0
- package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
- package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
- package/lib/types/gtk-editable-label.spec.d.ts +1 -0
- package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
- package/lib/types/gtk-expander.spec.d.ts +1 -0
- package/lib/types/gtk-fixed.spec.d.ts +1 -0
- package/lib/types/gtk-flow-box.spec.d.ts +1 -0
- package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
- package/lib/types/gtk-frame.spec.d.ts +1 -0
- package/lib/types/gtk-gl-area.spec.d.ts +1 -0
- package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
- package/lib/types/gtk-grid-view.spec.d.ts +1 -0
- package/lib/types/gtk-grid.spec.d.ts +1 -0
- package/lib/types/gtk-header-bar.spec.d.ts +1 -0
- package/lib/types/gtk-inscription.spec.d.ts +1 -0
- package/lib/types/gtk-level-bar.spec.d.ts +1 -0
- package/lib/types/gtk-link-button.spec.d.ts +1 -0
- package/lib/types/gtk-list-box.spec.d.ts +1 -0
- package/lib/types/gtk-list-view.spec.d.ts +1 -0
- package/lib/types/gtk-media-controls.spec.d.ts +1 -0
- package/lib/types/gtk-notebook.spec.d.ts +1 -0
- package/lib/types/gtk-overlay.spec.d.ts +1 -0
- package/lib/types/gtk-paned.spec.d.ts +1 -0
- package/lib/types/gtk-password-entry.spec.d.ts +1 -0
- package/lib/types/gtk-picture.spec.d.ts +1 -0
- package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
- package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
- package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
- package/lib/types/gtk-popover-role.spec.d.ts +1 -0
- package/lib/types/gtk-popover.spec.d.ts +1 -0
- package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
- package/lib/types/gtk-revealer.spec.d.ts +1 -0
- package/lib/types/gtk-scale-button.spec.d.ts +1 -0
- package/lib/types/gtk-scale.spec.d.ts +1 -0
- package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
- package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
- package/lib/types/gtk-search-bar.spec.d.ts +1 -0
- package/lib/types/gtk-search-entry.spec.d.ts +1 -0
- package/lib/types/gtk-separator.spec.d.ts +1 -0
- package/lib/types/gtk-spin-button.spec.d.ts +1 -0
- package/lib/types/gtk-spinner.spec.d.ts +1 -0
- package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
- package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
- package/lib/types/gtk-stack.spec.d.ts +1 -0
- package/lib/types/gtk-text-view.spec.d.ts +1 -0
- package/lib/types/gtk-text.spec.d.ts +1 -0
- package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
- package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
- package/lib/types/gtk-video.spec.d.ts +1 -0
- package/lib/types/gtk-viewport.spec.d.ts +1 -0
- package/lib/types/gtk-window-controls.spec.d.ts +1 -0
- package/lib/types/gtk-window-handle.spec.d.ts +1 -0
- package/lib/types/gtk-window.spec.d.ts +1 -0
- package/lib/types/index.d.ts +4 -1
- package/lib/types/list-view-dom.d.ts +44 -0
- package/lib/types/namespace/adw.d.ts +12 -0
- package/lib/types/namespace/gtk.d.ts +61 -0
- package/lib/types/page-setup.d.ts +100 -0
- package/lib/types/scroll-shading.d.ts +15 -1
- package/lib/types/shared-tree-builder.d.ts +30 -2
- package/lib/types/signals.d.ts +4 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/tab-chip.d.ts +73 -0
- package/lib/types/template-classes.d.ts +11 -0
- package/package.json +12 -8
- package/scss/_action_row.scss +2 -2
- package/scss/_application_window.scss +26 -0
- package/scss/_aspect_frame.scss +25 -0
- package/scss/_bin.scss +26 -0
- package/scss/_button.scss +45 -0
- package/scss/_calendar.scss +176 -0
- package/scss/_center_box.scss +25 -0
- package/scss/_checks.scss +6 -1
- package/scss/_clamp_scrollable.scss +28 -0
- package/scss/_color_button.scss +67 -0
- package/scss/_column_view.scss +126 -0
- package/scss/_drag_icon.scss +55 -0
- package/scss/_drawing.scss +85 -0
- package/scss/_emoji_chooser.scss +213 -0
- package/scss/_entry.scss +13 -5
- package/scss/_entry_row.scss +1 -1
- package/scss/_expander.scss +113 -0
- package/scss/_fixed.scss +29 -0
- package/scss/_flow_box.scss +94 -0
- package/scss/_font_button.scss +63 -0
- package/scss/_frame.scss +41 -0
- package/scss/_grid.scss +19 -0
- package/scss/_grid_view.scss +46 -0
- package/scss/_gtk_about_dialog.scss +186 -0
- package/scss/_headerbar.scss +132 -0
- package/scss/_icons.generated.scss +186 -0
- package/scss/_inscription.scss +125 -0
- package/scss/_level_bar.scss +190 -0
- package/scss/_link.scss +82 -0
- package/scss/_list_box.scss +88 -0
- package/scss/_list_view.scss +96 -0
- package/scss/_media_controls.scss +139 -0
- package/scss/_overlay.scss +68 -0
- package/scss/_paned.scss +130 -0
- package/scss/_password_entry.scss +83 -0
- package/scss/_picture.scss +80 -0
- package/scss/_popover_bin.scss +53 -0
- package/scss/_popover_menu_bar.scss +104 -0
- package/scss/_preferences_row.scss +51 -0
- package/scss/_print_dialogs.scss +328 -0
- package/scss/_reset.scss +21 -19
- package/scss/_revealer.scss +37 -0
- package/scss/_row.scss +20 -5
- package/scss/_scale.scss +298 -0
- package/scss/_scale_button.scss +167 -0
- package/scss/_scrollbar.scss +230 -0
- package/scss/_scrolled_window.scss +131 -0
- package/scss/_search_bar.scss +118 -0
- package/scss/_search_entry.scss +86 -0
- package/scss/_separator.scss +44 -0
- package/scss/_shortcuts_dialog.scss +100 -0
- package/scss/_spin_button.scss +172 -0
- package/scss/_spin_row.scss +56 -8
- package/scss/_spinner.scss +85 -4
- package/scss/_stack.scss +729 -0
- package/scss/_switch.scss +13 -5
- package/scss/_switch_row.scss +10 -0
- package/scss/_tab_bar.scss +317 -0
- package/scss/_tab_button.scss +98 -0
- package/scss/_tab_overview.scss +483 -0
- package/scss/_text.scss +182 -0
- package/scss/_theme.scss +1 -1
- package/scss/_tree_expander.scss +62 -0
- package/scss/_variables.scss +43 -21
- package/scss/_video.scss +146 -0
- package/scss/_view_switcher_sidebar.scss +112 -0
- package/scss/_viewport.scss +50 -0
- package/scss/_window.scss +118 -1
- package/scss/_window_handle.scss +20 -0
- package/scss/adwaita-skin.scss +109 -0
- package/src/adw-action-rows.spec.ts +76 -0
- package/src/adw-application-window.spec.ts +118 -0
- package/src/adw-bin.spec.ts +75 -0
- package/src/adw-breakpoint-bin.spec.ts +324 -0
- package/src/adw-clamp-scrollable.spec.ts +189 -0
- package/src/adw-multi-layout-view.spec.ts +243 -0
- package/src/adw-preferences-row.spec.ts +164 -0
- package/src/adw-row-state.spec.ts +142 -0
- package/src/adw-shortcuts.spec.ts +155 -0
- package/src/adw-tab-bar.spec.ts +287 -0
- package/src/adw-tab-button.spec.ts +101 -0
- package/src/adw-tab-overview.spec.ts +443 -0
- package/src/adw-view-switcher-sidebar.spec.ts +281 -0
- package/src/adw-window.spec.ts +129 -0
- package/src/breakpoints.ts +25 -8
- package/src/capabilities.d.mts +3 -0
- package/src/capabilities.mjs +18 -0
- package/src/connect-lifecycle.spec.ts +12 -0
- package/src/construct-vectors.spec.ts +175 -0
- package/src/elements/adw-application-window.ts +154 -0
- package/src/elements/adw-bin.ts +101 -0
- package/src/elements/adw-breakpoint-bin.ts +287 -0
- package/src/elements/adw-clamp-scrollable.ts +207 -0
- package/src/elements/adw-dialog.ts +19 -0
- package/src/elements/adw-layout-slot.ts +95 -0
- package/src/elements/adw-multi-layout-view.ts +326 -0
- package/src/elements/adw-preferences-row.ts +150 -0
- package/src/elements/adw-shortcuts-dialog.ts +52 -0
- package/src/elements/adw-shortcuts-item.ts +171 -0
- package/src/elements/adw-shortcuts-section.ts +86 -0
- package/src/elements/adw-sidebar.ts +42 -3
- package/src/elements/adw-switch-row.ts +28 -1
- package/src/elements/adw-tab-bar.ts +529 -0
- package/src/elements/adw-tab-button.ts +194 -0
- package/src/elements/adw-tab-overview.ts +1011 -0
- package/src/elements/adw-tab-view.ts +66 -145
- package/src/elements/adw-toggle-group.ts +20 -5
- package/src/elements/adw-view-stack.ts +18 -0
- package/src/elements/adw-view-switcher-sidebar.ts +332 -0
- package/src/elements/adw-window.ts +185 -11
- package/src/elements/checks.ts +35 -8
- package/src/elements/gtk-about-dialog.ts +811 -0
- package/src/elements/gtk-application-window.ts +108 -0
- package/src/elements/gtk-aspect-frame.ts +160 -0
- package/src/elements/gtk-button.ts +12 -0
- package/src/elements/gtk-calendar.ts +757 -0
- package/src/elements/gtk-center-box.ts +184 -0
- package/src/elements/gtk-color-dialog-button.ts +278 -0
- package/src/elements/gtk-column-view.ts +320 -0
- package/src/elements/gtk-drag-icon.ts +257 -0
- package/src/elements/gtk-drawing-area.ts +303 -0
- package/src/elements/gtk-editable-label.ts +204 -0
- package/src/elements/gtk-emoji-chooser.ts +542 -0
- package/src/elements/gtk-entry.ts +39 -5
- package/src/elements/gtk-expander.ts +301 -0
- package/src/elements/gtk-fixed.ts +99 -0
- package/src/elements/gtk-flow-box-child.ts +68 -0
- package/src/elements/gtk-flow-box.ts +480 -0
- package/src/elements/gtk-font-dialog-button.ts +432 -0
- package/src/elements/gtk-frame.ts +174 -0
- package/src/elements/gtk-gl-area.ts +476 -0
- package/src/elements/gtk-graphics-offload.ts +130 -0
- package/src/elements/gtk-grid-view.ts +168 -0
- package/src/elements/gtk-grid.ts +127 -0
- package/src/elements/gtk-header-bar.ts +273 -0
- package/src/elements/gtk-inscription.ts +387 -0
- package/src/elements/gtk-label.ts +19 -11
- package/src/elements/gtk-level-bar.ts +323 -0
- package/src/elements/gtk-link-button.ts +138 -0
- package/src/elements/gtk-list-box-row.ts +195 -0
- package/src/elements/gtk-list-box.ts +413 -0
- package/src/elements/gtk-list-view.ts +370 -0
- package/src/elements/gtk-media-controls.ts +509 -0
- package/src/elements/gtk-notebook.ts +664 -0
- package/src/elements/gtk-overlay.ts +149 -0
- package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
- package/src/elements/gtk-paned.ts +597 -0
- package/src/elements/gtk-password-entry.ts +170 -0
- package/src/elements/gtk-picture.ts +254 -0
- package/src/elements/gtk-popover-bin.ts +332 -0
- package/src/elements/gtk-popover-menu-bar.ts +355 -0
- package/src/elements/gtk-popover-menu.ts +339 -0
- package/src/elements/gtk-popover.ts +92 -10
- package/src/elements/gtk-print-unix-dialog.ts +989 -0
- package/src/elements/gtk-progress-bar.ts +24 -11
- package/src/elements/gtk-revealer.ts +406 -0
- package/src/elements/gtk-scale-button.ts +358 -0
- package/src/elements/gtk-scale.ts +492 -0
- package/src/elements/gtk-scrollbar.ts +528 -0
- package/src/elements/gtk-scrolled-window.ts +642 -0
- package/src/elements/gtk-search-bar.ts +200 -0
- package/src/elements/gtk-search-entry.ts +172 -0
- package/src/elements/gtk-separator.ts +52 -0
- package/src/elements/gtk-spin-button.ts +475 -0
- package/src/elements/gtk-spinner.ts +126 -0
- package/src/elements/gtk-stack-sidebar.ts +212 -0
- package/src/elements/gtk-stack-switcher.ts +279 -0
- package/src/elements/gtk-stack.ts +748 -0
- package/src/elements/gtk-switch.ts +52 -19
- package/src/elements/gtk-text-view.ts +290 -0
- package/src/elements/gtk-text.ts +219 -0
- package/src/elements/gtk-toggle-button.ts +239 -0
- package/src/elements/gtk-tree-expander.ts +243 -0
- package/src/elements/gtk-video.ts +423 -0
- package/src/elements/gtk-viewport.ts +277 -0
- package/src/elements/gtk-window-controls.ts +341 -0
- package/src/elements/gtk-window-handle.ts +221 -0
- package/src/elements/gtk-window.ts +366 -0
- package/src/elements/justification.ts +24 -0
- package/src/elements/popover-menu.ts +24 -0
- package/src/elements/roving-focus.ts +53 -21
- package/src/emoji-data.ts +577 -0
- package/src/entry-rows.spec.ts +31 -0
- package/src/font-description.ts +238 -0
- package/src/gtk-about-dialog.spec.ts +250 -0
- package/src/gtk-action-bar.spec.ts +89 -0
- package/src/gtk-application-window.spec.ts +107 -0
- package/src/gtk-aspect-frame.spec.ts +114 -0
- package/src/gtk-calendar.spec.ts +589 -0
- package/src/gtk-center-box.spec.ts +125 -0
- package/src/gtk-color-dialog-button.spec.ts +141 -0
- package/src/gtk-column-view.spec.ts +154 -0
- package/src/gtk-drag-icon.spec.ts +190 -0
- package/src/gtk-drawing-area.spec.ts +211 -0
- package/src/gtk-editable-label.spec.ts +190 -0
- package/src/gtk-emoji-chooser.spec.ts +173 -0
- package/src/gtk-entry.spec.ts +23 -0
- package/src/gtk-expander.spec.ts +170 -0
- package/src/gtk-fixed.spec.ts +97 -0
- package/src/gtk-flow-box.spec.ts +289 -0
- package/src/gtk-font-dialog-button.spec.ts +166 -0
- package/src/gtk-frame.spec.ts +119 -0
- package/src/gtk-gl-area.spec.ts +361 -0
- package/src/gtk-graphics-offload.spec.ts +119 -0
- package/src/gtk-grid-view.spec.ts +106 -0
- package/src/gtk-grid.spec.ts +122 -0
- package/src/gtk-header-bar.spec.ts +202 -0
- package/src/gtk-inscription.spec.ts +235 -0
- package/src/gtk-level-bar.spec.ts +199 -0
- package/src/gtk-link-button.spec.ts +117 -0
- package/src/gtk-list-box.spec.ts +422 -0
- package/src/gtk-list-view.spec.ts +203 -0
- package/src/gtk-media-controls.spec.ts +295 -0
- package/src/gtk-notebook.spec.ts +546 -0
- package/src/gtk-overlay.spec.ts +141 -0
- package/src/gtk-paned.spec.ts +267 -0
- package/src/gtk-password-entry.spec.ts +150 -0
- package/src/gtk-picture.spec.ts +172 -0
- package/src/gtk-popover-bin.spec.ts +229 -0
- package/src/gtk-popover-menu-bar.spec.ts +296 -0
- package/src/gtk-popover-menu.spec.ts +261 -0
- package/src/gtk-popover-role.spec.ts +138 -0
- package/src/gtk-popover.spec.ts +264 -0
- package/src/gtk-print-dialogs.spec.ts +251 -0
- package/src/gtk-revealer.spec.ts +164 -0
- package/src/gtk-scale-button.spec.ts +218 -0
- package/src/gtk-scale.spec.ts +213 -0
- package/src/gtk-scrollbar.spec.ts +244 -0
- package/src/gtk-scrolled-window.spec.ts +262 -0
- package/src/gtk-search-bar.spec.ts +179 -0
- package/src/gtk-search-entry.spec.ts +142 -0
- package/src/gtk-separator.spec.ts +74 -0
- package/src/gtk-spin-button.spec.ts +186 -0
- package/src/gtk-spinner.spec.ts +130 -0
- package/src/gtk-stack-sidebar.spec.ts +217 -0
- package/src/gtk-stack-switcher.spec.ts +249 -0
- package/src/gtk-stack.spec.ts +432 -0
- package/src/gtk-text-view.spec.ts +189 -0
- package/src/gtk-text.spec.ts +163 -0
- package/src/gtk-toggle-button.spec.ts +186 -0
- package/src/gtk-tree-expander.spec.ts +201 -0
- package/src/gtk-video.spec.ts +240 -0
- package/src/gtk-viewport.spec.ts +140 -0
- package/src/gtk-window-controls.spec.ts +232 -0
- package/src/gtk-window-handle.spec.ts +158 -0
- package/src/gtk-window.spec.ts +190 -0
- package/src/index.ts +9 -1
- package/src/keyboard-operable.spec.ts +33 -1
- package/src/list-view-dom.ts +121 -0
- package/src/namespace/adw.ts +12 -0
- package/src/namespace/gtk.ts +61 -0
- package/src/page-setup.ts +222 -0
- package/src/scroll-shading.ts +18 -1
- package/src/shared-tree-builder.ts +263 -21
- package/src/signals.ts +15 -0
- package/src/source-view/theme.ts +11 -5
- package/src/style-classes.spec.ts +9 -8
- package/src/styles.generated.ts +1 -1
- package/src/tab-chip.ts +200 -0
- package/src/template-classes.ts +45 -0
- 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);
|