@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,221 @@
|
|
|
1
|
+
// <gtk-window-handle> — the titlebar strip: a widget that lets the window manager move the
|
|
2
|
+
// window when it is dragged, and turns the right-click, double-click and middle-click a
|
|
3
|
+
// titlebar is expected to turn into.
|
|
4
|
+
//
|
|
5
|
+
// WHAT IS LEFT OF IT IN GTK 4.24. The widget has ONE property (`child`), a `GtkBinLayout`, a
|
|
6
|
+
// `windowhandle` CSS node and the generic a11y role (gtkwindowhandle.c:529-556); everything
|
|
7
|
+
// else it once was is gone. The titlebar behaviour is three cases in
|
|
8
|
+
// `perform_titlebar_action` (gtkwindowhandle.c:335-367):
|
|
9
|
+
//
|
|
10
|
+
// · a PRIMARY double-click, a MIDDLE click or a SECONDARY click asks the COMPOSITOR first
|
|
11
|
+
// (`gdk_toplevel_titlebar_gesture`), and where there is no answer the settings
|
|
12
|
+
// `gtk-titlebar-double-click`, `-middle-click` and `-right-click` decide — their
|
|
13
|
+
// documented values are `toggle-maximize`, `lower`, `minimize`, `menu` and `none`
|
|
14
|
+
// (`perform_titlebar_action_fallback`, gtkwindowhandle.c:282-333);
|
|
15
|
+
// · a drag past the threshold begins a window MOVE (`gdk_toplevel_begin_move`,
|
|
16
|
+
// gtkwindowhandle.c:423-467);
|
|
17
|
+
// · `menu` opens the window menu, falling back to GTK's OWN Restore / Minimize / Maximize /
|
|
18
|
+
// Close popover (`do_popup_fallback`, gtkwindowhandle.c:160-262).
|
|
19
|
+
//
|
|
20
|
+
// WHAT A PAGE CANNOT DO, AND WHAT IT DOES INSTEAD. `gdk_toplevel_begin_move` and
|
|
21
|
+
// `gdk_toplevel_show_window_menu` are OPERATIONS ON THE COMPOSITOR'S SURFACE: a document is
|
|
22
|
+
// not allowed to move or unmaximize the window it is rendered in, and no web API asks it to.
|
|
23
|
+
// So the port emits the SAME action names GTK's fallback activates — `window.toggle-maximized`
|
|
24
|
+
// and `window.minimize` are the strings `gtk_widget_activate_action` is handed
|
|
25
|
+
// (gtkwindowhandle.c:313-321), and `window.lower` / `window.menu` are the compositor calls it
|
|
26
|
+
// makes instead (gtkwindowhandle.c:84-91, 264-280) — as a `titlebar-action` CustomEvent
|
|
27
|
+
// (bubbles, detail `{ action, gesture, windowAction, x, y }`), and a second event NAMED for the
|
|
28
|
+
// action, which is what the C's `gdk_surface_...` call amounts to from a consumer's side. The
|
|
29
|
+
// settings that choose the action are attributes of the same three names minus the `gtk-`
|
|
30
|
+
// prefix, so a consumer writes `double-click-action="toggle-maximize"` and gets GTK's
|
|
31
|
+
// precedence without a settings object it cannot have.
|
|
32
|
+
//
|
|
33
|
+
// `child` is a SLOT, as everywhere in this package: an attribute cannot carry a widget, and a
|
|
34
|
+
// handle needs no routing of its own because it contributes no box — `display: contents` IS
|
|
35
|
+
// `GtkBinLayout`'s "the child takes the whole allocation", so the strip can go anywhere a
|
|
36
|
+
// header bar goes without moving the layout around it.
|
|
37
|
+
//
|
|
38
|
+
// A11y: `role="generic"`, which GTK 4.12 gave the widget in place of the `group` it used to
|
|
39
|
+
// report (gtkwindowhandle.c:55-59, 555). The gestures are POINTER ones on the child's own
|
|
40
|
+
// box, so everything inside the titlebar — its buttons, its title — stays operable by
|
|
41
|
+
// keyboard.
|
|
42
|
+
//
|
|
43
|
+
// Reference: refs/gtk/gtk/gtkwindowhandle.c (class_init, click_gesture_pressed_cb,
|
|
44
|
+
// perform_titlebar_action, perform_titlebar_action_fallback, drag_gesture_update_cb,
|
|
45
|
+
// do_popup_fallback)
|
|
46
|
+
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
47
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
48
|
+
|
|
49
|
+
/** `GtkTitlebarGesture`'s three gestures, as `perform_titlebar_action` decides them. */
|
|
50
|
+
export type GtkTitlebarGesture = 'double-click' | 'middle-click' | 'right-click';
|
|
51
|
+
|
|
52
|
+
/** The settings' own vocabulary, `none` included: "the compositor declined" is one. */
|
|
53
|
+
export type GtkTitlebarAction = 'toggle-maximize' | 'lower' | 'minimize' | 'menu' | 'none';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Each gesture, the ATTRIBUTE its setting is authored under, and the value read when the
|
|
57
|
+
* attribute is absent.
|
|
58
|
+
*
|
|
59
|
+
* The three defaults are the pspecs' own and they are NOT all the same
|
|
60
|
+
* (gtksettings.c:868-896): `gtk-titlebar-double-click` is `toggle-maximize`,
|
|
61
|
+
* `gtk-titlebar-middle-click` is `none` — a middle click on a titlebar does nothing unless
|
|
62
|
+
* something asked for it — and `gtk-titlebar-right-click` is `menu`. Reading all three as
|
|
63
|
+
* `menu` would open a window menu on a middle click nobody asked for.
|
|
64
|
+
*/
|
|
65
|
+
const GESTURES = {
|
|
66
|
+
'double-click': { attribute: 'double-click-action', fallback: 'toggle-maximize' },
|
|
67
|
+
'middle-click': { attribute: 'middle-click-action', fallback: 'none' },
|
|
68
|
+
'right-click': { attribute: 'right-click-action', fallback: 'menu' },
|
|
69
|
+
} as const satisfies Record<GtkTitlebarGesture, { attribute: string; fallback: GtkTitlebarAction }>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The GObject action names `gtk_widget_activate_action` is handed (gtkwindowhandle.c:313-321).
|
|
73
|
+
*
|
|
74
|
+
* TWO of the four are real `GtkWindow` actions — `window.toggle-maximized` and
|
|
75
|
+
* `window.minimize` are installed in `gtk_window_class_init` (gtkwindow.c:1319-1328), which is
|
|
76
|
+
* what makes them the right names to raise. The other two are compositor OPERATIONS in GTK:
|
|
77
|
+
* `lower` calls `gdk_toplevel_lower` and `menu` calls `gdk_toplevel_show_window_menu`
|
|
78
|
+
* (gtkwindowhandle.c:84-91, 264-280), and `window.lower` / `window.menu` are the names a
|
|
79
|
+
* window host binds those two to.
|
|
80
|
+
*/
|
|
81
|
+
const WINDOW_ACTIONS: Readonly<Record<Exclude<GtkTitlebarAction, 'none'>, string>> = {
|
|
82
|
+
'toggle-maximize': 'window.toggle-maximized',
|
|
83
|
+
lower: 'window.lower',
|
|
84
|
+
minimize: 'window.minimize',
|
|
85
|
+
menu: 'window.menu',
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/** Every action the settings document, which is also the set a typo has to be refused against. */
|
|
89
|
+
const ACTIONS = new Set<string>(['none', 'toggle-maximize', 'lower', 'minimize', 'menu']);
|
|
90
|
+
|
|
91
|
+
/** `gestureOf`'s switch — which button and press count is which gesture. */
|
|
92
|
+
function gestureOf(button: number, presses: number): GtkTitlebarGesture | null {
|
|
93
|
+
switch (button) {
|
|
94
|
+
case 0:
|
|
95
|
+
return presses > 1 ? 'double-click' : null;
|
|
96
|
+
case 1:
|
|
97
|
+
return 'middle-click';
|
|
98
|
+
case 2:
|
|
99
|
+
return 'right-click';
|
|
100
|
+
default:
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The distance a pointer travels before a drag counts.
|
|
107
|
+
*
|
|
108
|
+
* `drag_gesture_update_cb` asks `gtk_drag_check_threshold_double (self, 0, 0, dx, dy)`,
|
|
109
|
+
* which is the theme's drag threshold or `gdk_drag_get_threshold ()` where the toolkit has
|
|
110
|
+
* none (gtkwindowhandle.c:429). A titlebar has to tell a tap from a drag on a touchscreen as
|
|
111
|
+
* much as on a mouse, so it is one device pixel.
|
|
112
|
+
*/
|
|
113
|
+
const DRAG_THRESHOLD = 1;
|
|
114
|
+
|
|
115
|
+
export class GtkWindowHandle extends HTMLElement {
|
|
116
|
+
/** The gesture in progress, as `priv->drag_start_x` / `_y` are in the C. */
|
|
117
|
+
private _drag: { pointerId: number; x: number; y: number } | null = null;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The three gesture SETTINGS, spelled out.
|
|
121
|
+
*
|
|
122
|
+
* `GESTURES` above names the same three, and the list is written rather than computed
|
|
123
|
+
* from it because `scripts/adwaita-elements.mjs` reads `observedAttributes` as an array
|
|
124
|
+
* LITERAL: a `.map()` over a table reads as an unreadable element there, which is
|
|
125
|
+
* reported as "this reader cannot tell" rather than as the three attributes it is.
|
|
126
|
+
*/
|
|
127
|
+
static get observedAttributes() {
|
|
128
|
+
return ['double-click-action', 'middle-click-action', 'right-click-action'];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** The action one gesture is set to, as the settings are read in C. */
|
|
132
|
+
actionFor(gesture: GtkTitlebarGesture): GtkTitlebarAction {
|
|
133
|
+
const { attribute, fallback } = GESTURES[gesture];
|
|
134
|
+
const written = this.getAttribute(attribute);
|
|
135
|
+
// An absent attribute is the setting's own value, and each of the three is its own
|
|
136
|
+
// (gtksettings.c:868-896) — a middle click does nothing by default.
|
|
137
|
+
if (written === null) return fallback;
|
|
138
|
+
// `perform_titlebar_action_fallback` matches `toggle-maximize` by PREFIX, "treat all
|
|
139
|
+
// maximization variants the same" (gtkwindowhandle.c:311-315), so a variant a window
|
|
140
|
+
// manager invents maximizes rather than being refused.
|
|
141
|
+
if (written.startsWith('toggle-maximize')) return 'toggle-maximize';
|
|
142
|
+
// Anything else it does not know takes the C's own refusal branch: `g_warning
|
|
143
|
+
// ("Unsupported titlebar action %s")` and `retval = FALSE` (gtkwindowhandle.c:324-328),
|
|
144
|
+
// which is what `none` means here — a typo must not minimize a window.
|
|
145
|
+
return ACTIONS.has(written) ? (written as GtkTitlebarAction) : 'none';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
connectedCallback() {
|
|
149
|
+
this.setAttribute('role', 'generic');
|
|
150
|
+
this.addEventListener('click', this._onClick);
|
|
151
|
+
this.addEventListener('pointerdown', this._onPointerDown);
|
|
152
|
+
this.addEventListener('pointermove', this._onPointerMove);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
disconnectedCallback() {
|
|
156
|
+
this.removeEventListener('click', this._onClick);
|
|
157
|
+
this.removeEventListener('pointerdown', this._onPointerDown);
|
|
158
|
+
this.removeEventListener('pointermove', this._onPointerMove);
|
|
159
|
+
this._drag = null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* `perform_titlebar_action_fallback`: raise the action GTK would have activated, and
|
|
164
|
+
* then the event NAMED for it.
|
|
165
|
+
*
|
|
166
|
+
* Both fire for every gesture, `none` included: the first is what a consumer reads to
|
|
167
|
+
* know a titlebar was clicked at all — the C's `retval = FALSE`, where the compositor
|
|
168
|
+
* declined, is a fact worth reporting — and the second is what a window host binds to.
|
|
169
|
+
*/
|
|
170
|
+
private _perform(gesture: GtkTitlebarGesture, x: number, y: number): void {
|
|
171
|
+
const action = this.actionFor(gesture);
|
|
172
|
+
const windowAction = action === 'none' ? null : WINDOW_ACTIONS[action];
|
|
173
|
+
const detail = { action, gesture, windowAction, x, y };
|
|
174
|
+
this.dispatchEvent(new CustomEvent('titlebar-action', { bubbles: true, detail }));
|
|
175
|
+
if (windowAction === null) return;
|
|
176
|
+
this.dispatchEvent(new CustomEvent(windowAction, { bubbles: true, detail }));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private _onClick = (event: MouseEvent): void => {
|
|
180
|
+
// The click gesture CLAIMED the sequence, which is what `gtk_event_controller_reset`
|
|
181
|
+
// on both gestures does upstream for every click it acts on — including the second
|
|
182
|
+
// press of a double click, whose drag was denied at press time
|
|
183
|
+
// (gtkwindowhandle.c:408-409, 464-465). A press count the browser knows and a
|
|
184
|
+
// pointerdown does not is why the reset happens HERE.
|
|
185
|
+
this._drag = null;
|
|
186
|
+
const gesture = gestureOf(event.button, event.detail);
|
|
187
|
+
if (gesture === null) return;
|
|
188
|
+
// `do_popup_fallback` places the menu with `gtk_popover_set_pointing_to` at the event's
|
|
189
|
+
// own position, which is the click's.
|
|
190
|
+
this._perform(gesture, event.clientX, event.clientY);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
private _onPointerDown = (event: PointerEvent): void => {
|
|
194
|
+
// A second press of a multi-click sequence DENIES the drag, which is what
|
|
195
|
+
// `click_gesture_pressed_cb` does with `n_press > 1` (gtkwindowhandle.c:382-383):
|
|
196
|
+
// a double-click is a click, and a drag that began on its second press is not one.
|
|
197
|
+
if (event.detail > 1) return;
|
|
198
|
+
this._drag = { pointerId: event.pointerId, x: event.clientX, y: event.clientY };
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* `drag_gesture_update_cb`: past the threshold the WINDOW moves, and the sequence is
|
|
203
|
+
* reset so the gesture does not repeat. The move is a compositor operation, so what is
|
|
204
|
+
* emitted is the INTENT, with the pointer's position where GTK hands `begin_move` its
|
|
205
|
+
* own surface coordinates.
|
|
206
|
+
*/
|
|
207
|
+
private _onPointerMove = (event: PointerEvent): void => {
|
|
208
|
+
const drag = this._drag;
|
|
209
|
+
if (drag === null || drag.pointerId !== event.pointerId) return;
|
|
210
|
+
const travelled = Math.abs(event.clientX - drag.x) + Math.abs(event.clientY - drag.y);
|
|
211
|
+
// STRICTLY past the threshold, which is what `gtk_drag_check_threshold_double` asks:
|
|
212
|
+
// movement up to it is not a drag.
|
|
213
|
+
if (travelled <= DRAG_THRESHOLD) return;
|
|
214
|
+
this._drag = null;
|
|
215
|
+
this.dispatchEvent(
|
|
216
|
+
new CustomEvent('window-move', { bubbles: true, detail: { x: event.clientX, y: event.clientY } }),
|
|
217
|
+
);
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
customElements.define('gtk-window-handle', GtkWindowHandle);
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
// <gtk-window> — a window, IN PAGE. This is a FRAME, not a toplevel: a rounded, shadowed box
|
|
2
|
+
// with a titlebar strip at the top, the window's content below it, and the same window
|
|
3
|
+
// properties `<gtk-window-controls>` reads to decide which frame buttons to draw.
|
|
4
|
+
//
|
|
5
|
+
// SAYING THAT PLAINLY, because the element's name promises something the page cannot be. A
|
|
6
|
+
// browser document has no `GtkWindow`, no `GdkToplevel`, no window manager and no place to
|
|
7
|
+
// map one; what a page can draw is the DECORATION of a window and honour the properties that
|
|
8
|
+
// decide what that decoration shows. So: no `move()`, no `resize()`, no real `is-active`, and
|
|
9
|
+
// a close button that hides or detaches a box rather than a surface the compositor owns.
|
|
10
|
+
// Everything else below is ported from `gtkwindow.c`.
|
|
11
|
+
//
|
|
12
|
+
// THE TREE. `Gtk.Window` is a `GtkBin` with a `child` and, since 4.6, a `titlebar`
|
|
13
|
+
// (gtkwindow.c:1128, :1138), and libadwaita paints `window { &.csd { … } }` around it
|
|
14
|
+
// (refs/libadwaita/src/stylesheet/widgets/_window.scss:1-31). This element therefore builds
|
|
15
|
+
//
|
|
16
|
+
// <gtk-window>
|
|
17
|
+
// ├── div.adw-gtk-window-titlebar — the `titlebar`, or the server-side decoration
|
|
18
|
+
// │ a `Gtk.Window` without one would get from the WM
|
|
19
|
+
// └── div.adw-gtk-window-content — everything else, in document order
|
|
20
|
+
//
|
|
21
|
+
// and `decorated="false"` drops the first, which is what `gtk_window_set_decorated` means
|
|
22
|
+
// (:1014). A `titlebar` SLOT is how the property is written in markup; with none, the strip
|
|
23
|
+
// holds the two `<gtk-window-controls>` and the window's own title — GTK's SSD shape, which
|
|
24
|
+
// is exactly the thing a page has to draw for itself.
|
|
25
|
+
//
|
|
26
|
+
// WHAT THE FRAME PROPERTIES DO, EACH AT ITS OWN SOURCE LINE:
|
|
27
|
+
// `title` — read by a header bar's `update_title` (gtkheaderbar.c:250-271) and
|
|
28
|
+
// written into the strip's title when there is no titlebar (:873).
|
|
29
|
+
// `deletable` — no close button when false (:1024); `gtk_window_close` (:1274).
|
|
30
|
+
// `resizable` — no maximize button when false (:893).
|
|
31
|
+
// `maximized` — the restore glyph instead of the maximize one, and the square-cornered
|
|
32
|
+
// `&.maximized` frame libadwaita draws (_window.scss:66-72, :1044).
|
|
33
|
+
// `fullscreened` — the same square corners from the other side (_window.scss:67, :1060).
|
|
34
|
+
// `modal` / `transient-for` — the sovereignty test: neither means the window owns an icon
|
|
35
|
+
// and a minimize button (gtkwindowcontrols.c:272-273, :299, :318).
|
|
36
|
+
// `icon-name` — the icon at the head of the start controls (:982).
|
|
37
|
+
// `hide-on-close` — the two branches of the close button's default handler (:945,
|
|
38
|
+
// `gtk_window_close` :1274-1287): hide, or destroy. `close-request` is
|
|
39
|
+
// emitted first and is CANCELLED by a handler that takes over (:1200-1224).
|
|
40
|
+
// `default-width` / `default-height` — the size a window opens at (:913-930).
|
|
41
|
+
//
|
|
42
|
+
// THE CLOSE BUTTON. GTK's window controls activate the `window.close` action, which
|
|
43
|
+
// `Gtk.Window` answers with `gtk_window_close` (:1274-1287): emit `close-request`, and if
|
|
44
|
+
// nothing handled it, HIDE the window when `hide-on-close` is set and DESTROY it otherwise.
|
|
45
|
+
// That is the whole of the default, and it is what this element does — except that "destroy"
|
|
46
|
+
// detaches the frame from the page rather than unref'ing a toplevel, which is the one
|
|
47
|
+
// difference a reader of the DOM can see.
|
|
48
|
+
//
|
|
49
|
+
// NOT PORTED, and why — these are the KNOWN_GAPS of this element:
|
|
50
|
+
// `application`, `child`, `default-widget`, `display`, `focus-widget` — WIDGET- or
|
|
51
|
+
// DISPLAY-typed, so a slot or an id here rather than an attribute; `child` and
|
|
52
|
+
// `titlebar` ARE slots and `transient-for` only has to be PRESENT.
|
|
53
|
+
// `destroy-with-parent` — a DOM node has no destroy, and a page has no parent to destroy.
|
|
54
|
+
// `focus-visible`, `mnemonics-visible` — GTK maintains both from user input and the GIR
|
|
55
|
+
// says an application must not set them (:969, :956).
|
|
56
|
+
// `gravity` — which point stays fixed while the window is resized PROGRAMMATICALLY (:1163);
|
|
57
|
+
// a browser box is laid out, never resized that way.
|
|
58
|
+
// `handle-menubar-accel` — F10 activating a menubar, which is `<gtk-application-window>`'s
|
|
59
|
+
// business and needs the `Gio.MenuModel` it is built from (:1150).
|
|
60
|
+
// `startup-id` — write-only, and written by the launcher that started the application (:883).
|
|
61
|
+
//
|
|
62
|
+
// Events: `notify::<prop>` (CustomEvent, bubbles, detail `{ <prop>: value }`) on every real
|
|
63
|
+
// change, and `close-request` (CustomEvent, bubbles, CANCELLED, no detail), which is
|
|
64
|
+
// `Gtk.Window::close-request`.
|
|
65
|
+
//
|
|
66
|
+
// Reference: refs/gtk/gtk/gtkwindow.c
|
|
67
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_window.scss (GtkWindow)
|
|
68
|
+
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
69
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
70
|
+
|
|
71
|
+
import { bindSlottedChildren, type AdwSlot } from '../slotted-children.js';
|
|
72
|
+
|
|
73
|
+
// Registers <gtk-window-controls>: a frame with no titlebar of its own draws the two of them
|
|
74
|
+
// a server-side decoration would have, so importing the window alone must define them.
|
|
75
|
+
import './gtk-window-controls.js';
|
|
76
|
+
import type { WindowAction } from './gtk-window-controls.js';
|
|
77
|
+
|
|
78
|
+
export class GtkWindow extends HTMLElement {
|
|
79
|
+
private _initialized = false;
|
|
80
|
+
/** The `titlebar` strip — `protected` so a subclass can place its own strips around it. */
|
|
81
|
+
protected _titlebar!: HTMLDivElement;
|
|
82
|
+
/** Every child the window has no slot name for. */
|
|
83
|
+
protected _content!: HTMLDivElement;
|
|
84
|
+
/** The SSD controls the strip draws when the window has no titlebar of its own. */
|
|
85
|
+
private _startControls: HTMLElement | null = null;
|
|
86
|
+
private _endControls: HTMLElement | null = null;
|
|
87
|
+
/** The window's own title in the strip, or `null` when a titlebar holds it. */
|
|
88
|
+
private _titleLabel: HTMLElement | null = null;
|
|
89
|
+
/** Watches the strip for an author's titlebar arriving after the build. */
|
|
90
|
+
private _titlebarObserver: MutationObserver | null = null;
|
|
91
|
+
|
|
92
|
+
static get observedAttributes() {
|
|
93
|
+
return [
|
|
94
|
+
'decorated',
|
|
95
|
+
'default-width',
|
|
96
|
+
'default-height',
|
|
97
|
+
'deletable',
|
|
98
|
+
'fullscreened',
|
|
99
|
+
'hide-on-close',
|
|
100
|
+
'icon-name',
|
|
101
|
+
'maximized',
|
|
102
|
+
'modal',
|
|
103
|
+
'resizable',
|
|
104
|
+
'title',
|
|
105
|
+
'transient-for',
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** `Gtk.Window:title` — the window's title. */
|
|
110
|
+
get title(): string | null {
|
|
111
|
+
return this.getAttribute('title');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
set title(value: string | null) {
|
|
115
|
+
this._write('title', value);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** `Gtk.Window:decorated` — whether the frame and its titlebar strip are drawn at all. */
|
|
119
|
+
get decorated(): boolean {
|
|
120
|
+
return this._onByDefault('decorated');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
set decorated(value: boolean) {
|
|
124
|
+
this._write('decorated', String(value));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** `Gtk.Window:maximized` — square corners and the restore glyph. */
|
|
128
|
+
get maximized(): boolean {
|
|
129
|
+
return this._offByDefault('maximized');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
set maximized(value: boolean) {
|
|
133
|
+
this._write('maximized', String(value));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** `Gtk.Window:resizable` — whether the maximize button may appear. */
|
|
137
|
+
get resizable(): boolean {
|
|
138
|
+
return this._onByDefault('resizable');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
set resizable(value: boolean) {
|
|
142
|
+
this._write('resizable', String(value));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** `Gtk.Window:deletable` — whether the close button may appear. */
|
|
146
|
+
get deletable(): boolean {
|
|
147
|
+
return this._onByDefault('deletable');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
set deletable(value: boolean) {
|
|
151
|
+
this._write('deletable', String(value));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* `setAttribute` for a write that changes nothing. Every GObject setter here returns
|
|
156
|
+
* early when the value is already right (gtkwindow.c:1015-1017, :1045-1046, :894-895),
|
|
157
|
+
* and a boolean property whose value did not move must not notify.
|
|
158
|
+
*/
|
|
159
|
+
protected _write(name: string, value: string | null): void {
|
|
160
|
+
if (value === null) this.removeAttribute(name);
|
|
161
|
+
else if (this.getAttribute(name) !== value) this.setAttribute(name, value);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* The two default polarities, because one of them is wrong for half of this widget.
|
|
166
|
+
*
|
|
167
|
+
* `decorated`, `resizable` and `deletable` default TRUE (gtkwindow.c:1014, :893, :1024)
|
|
168
|
+
* and `maximized`, `fullscreened`, `modal` and `hide-on-close` default FALSE (:1044,
|
|
169
|
+
* :1060, :903, :945). Reading them all through one helper is how a bare `<gtk-window>`
|
|
170
|
+
* ended up wearing `.maximized` and `.fullscreen` — square corners and no shadow, on a
|
|
171
|
+
* window that had never been maximized.
|
|
172
|
+
*/
|
|
173
|
+
private _onByDefault(name: string): boolean {
|
|
174
|
+
return this.getAttribute(name) !== 'false';
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private _offByDefault(name: string): boolean {
|
|
178
|
+
return this.hasAttribute(name);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
connectedCallback() {
|
|
182
|
+
if (this._initialized) {
|
|
183
|
+
this._watchTitlebar();
|
|
184
|
+
this._render();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
this._initialized = true;
|
|
188
|
+
|
|
189
|
+
this._titlebar = document.createElement('div');
|
|
190
|
+
this._titlebar.className = 'adw-gtk-window-titlebar';
|
|
191
|
+
this._content = document.createElement('div');
|
|
192
|
+
this._content.className = 'adw-gtk-window-content';
|
|
193
|
+
|
|
194
|
+
bindSlottedChildren(this, [
|
|
195
|
+
{ name: 'titlebar', into: this._titlebar },
|
|
196
|
+
...this.extraSlots(),
|
|
197
|
+
{ into: this._content },
|
|
198
|
+
]).install(...this.strips());
|
|
199
|
+
|
|
200
|
+
// The `window.close` action the frame controls activate, answered by the window
|
|
201
|
+
// itself — `gtk_window_close` (gtkwindow.c:1274-1287). Left armed for the life of the
|
|
202
|
+
// element: it is a listener ON this, not a binding reaching outside it, so a move
|
|
203
|
+
// between parents costs nothing and nothing has to be re-armed.
|
|
204
|
+
this.addEventListener('window-action', (event) => this._onWindowAction(event));
|
|
205
|
+
|
|
206
|
+
this._watchTitlebar();
|
|
207
|
+
this._render();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
disconnectedCallback() {
|
|
211
|
+
this._titlebarObserver?.disconnect();
|
|
212
|
+
this._titlebarObserver = null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* A `slot="titlebar"` child adopted AFTER the build has to take the strip over from the
|
|
217
|
+
* server-side decoration, and `_render` is the one that notices — nothing else here runs
|
|
218
|
+
* when a child lands. Observed on `_titlebar`, which is where the adopted child goes,
|
|
219
|
+
* because `bindSlottedChildren` already watches the host for it.
|
|
220
|
+
*
|
|
221
|
+
* Re-established on every connect, so a window moved between parents keeps it.
|
|
222
|
+
*/
|
|
223
|
+
private _watchTitlebar(): void {
|
|
224
|
+
this._titlebarObserver?.disconnect();
|
|
225
|
+
this._titlebarObserver = new MutationObserver(() => this._render());
|
|
226
|
+
this._titlebarObserver.observe(this._titlebar, { childList: true });
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* The strips the frame is built from, in order. A subclass with a strip of its own —
|
|
231
|
+
* `<gtk-application-window>`'s menubar — adds it here, which is the only reason this pair
|
|
232
|
+
* exists: `install()` takes the structure and the slots at once, and the ORDER is that
|
|
233
|
+
* call's invariant (see `slotted-children.ts`).
|
|
234
|
+
*/
|
|
235
|
+
protected strips(): Node[] {
|
|
236
|
+
return [this._titlebar, this._content];
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** The slots a subclass adds beside `titlebar`; none by default. */
|
|
240
|
+
protected extraSlots(): AdwSlot[] {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
attributeChangedCallback(name: string) {
|
|
245
|
+
if (!this._initialized) return;
|
|
246
|
+
this._render();
|
|
247
|
+
this.dispatchEvent(
|
|
248
|
+
new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: this._property(name) } }),
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private _property(name: string): boolean | number | string | null {
|
|
253
|
+
if (name === 'default-width' || name === 'default-height') {
|
|
254
|
+
const raw = Number.parseFloat(this.getAttribute(name) ?? '');
|
|
255
|
+
return Number.isFinite(raw) ? raw : null;
|
|
256
|
+
}
|
|
257
|
+
if (name === 'title' || name === 'icon-name' || name === 'transient-for') return this.getAttribute(name);
|
|
258
|
+
if (name === 'decorated' || name === 'resizable' || name === 'deletable') return this._onByDefault(name);
|
|
259
|
+
return this._offByDefault(name);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private _render(): void {
|
|
263
|
+
// `gtk_window_set_decorated` (gtkwindow.c:1014): no frame, no titlebar strip, and so
|
|
264
|
+
// nothing for the frame controls to hang in — a bar alone would still draw them.
|
|
265
|
+
this._titlebar.hidden = !this.decorated;
|
|
266
|
+
// `_window.scss:66-72` — maximized and fullscreen are the two states that square the
|
|
267
|
+
// frame off and drop its shadow.
|
|
268
|
+
this.classList.toggle('maximized', this.decorated && this.maximized);
|
|
269
|
+
this.classList.toggle('fullscreen', this.decorated && this._offByDefault('fullscreened'));
|
|
270
|
+
|
|
271
|
+
const width = Number.parseFloat(this.getAttribute('default-width') ?? '');
|
|
272
|
+
const height = Number.parseFloat(this.getAttribute('default-height') ?? '');
|
|
273
|
+
for (const [axis, value] of [
|
|
274
|
+
['width', width],
|
|
275
|
+
['height', height],
|
|
276
|
+
] as const) {
|
|
277
|
+
if (Number.isFinite(value) && value > 0) this.style.setProperty(axis, `${value}px`);
|
|
278
|
+
else this.style.removeProperty(axis);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const title = this.getAttribute('title');
|
|
282
|
+
if (title === null) this.removeAttribute('aria-label');
|
|
283
|
+
else this.setAttribute('aria-label', title);
|
|
284
|
+
this._renderTitlebar();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* The strip, in the two shapes a window can be in. With a `titlebar` child the strip
|
|
289
|
+
* holds exactly that — GTK hands the whole titlebar to the bar, decorations and all. With
|
|
290
|
+
* none it holds the two `<gtk-window-controls>` and the window's title, which is the
|
|
291
|
+
* server-side decoration GTK would otherwise have asked the window manager to draw and
|
|
292
|
+
* which a page has to draw for itself.
|
|
293
|
+
*/
|
|
294
|
+
private _renderTitlebar(): void {
|
|
295
|
+
// The strip's OWN nodes do not count as an authored titlebar. `connectedCallback`
|
|
296
|
+
// re-runs `_render()` on every connect, and a check on `childElementCount` alone
|
|
297
|
+
// read the three SSD children this method had just built as somebody else's titlebar
|
|
298
|
+
// and removed them — so a window that had been moved between parents came back with an
|
|
299
|
+
// empty titlebar while a freshly built one kept its frame buttons.
|
|
300
|
+
const authored = [...this._titlebar.children].some(
|
|
301
|
+
(child) => child !== this._startControls && child !== this._endControls && child !== this._titleLabel,
|
|
302
|
+
);
|
|
303
|
+
if (authored) {
|
|
304
|
+
for (const own of [this._startControls, this._endControls, this._titleLabel]) own?.remove();
|
|
305
|
+
this._startControls = null;
|
|
306
|
+
this._endControls = null;
|
|
307
|
+
this._titleLabel = null;
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (!this.decorated) return;
|
|
311
|
+
|
|
312
|
+
if (this._startControls === null) {
|
|
313
|
+
this._startControls = document.createElement('gtk-window-controls');
|
|
314
|
+
this._startControls.setAttribute('side', 'start');
|
|
315
|
+
this._endControls = document.createElement('gtk-window-controls');
|
|
316
|
+
this._endControls.setAttribute('side', 'end');
|
|
317
|
+
this._titleLabel = document.createElement('span');
|
|
318
|
+
this._titleLabel.className = 'adw-gtk-window-title';
|
|
319
|
+
this._titlebar.append(this._startControls, this._titleLabel, this._endControls);
|
|
320
|
+
}
|
|
321
|
+
const title = this.getAttribute('title');
|
|
322
|
+
if (title === null) this._titleLabel?.removeAttribute('title');
|
|
323
|
+
else this._titleLabel?.setAttribute('title', title ?? '');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/** The frame controls' `GtkActionable` names, answered here — gtkwindow.c:1274-1287. */
|
|
327
|
+
private _onWindowAction(event: Event): void {
|
|
328
|
+
const action = (event as CustomEvent<{ action: WindowAction }>).detail?.action;
|
|
329
|
+
if (action === 'toggle-maximized') {
|
|
330
|
+
this._write('maximized', String(!this._offByDefault('maximized')));
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (action === 'close') this.close();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* `gtk_window_close` (gtkwindow.c:1274-1287): emit `close-request` and, if nothing handled
|
|
338
|
+
* it, hide the window when `hide-on-close` is set and DESTROY it otherwise. "Destroy" is
|
|
339
|
+
* the one word this port cannot mean — a page has no unref — so the default detaches the
|
|
340
|
+
* frame, which is the same observable outcome for everything above it.
|
|
341
|
+
*/
|
|
342
|
+
close(): boolean {
|
|
343
|
+
const request = new CustomEvent('close-request', { bubbles: true, cancelable: true });
|
|
344
|
+
this.dispatchEvent(request);
|
|
345
|
+
if (request.defaultPrevented) return false;
|
|
346
|
+
if (this._offByDefault('hide-on-close')) this.hidden = true;
|
|
347
|
+
else this.remove();
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* `gtk_window_maximize`. ASYNCHRONOUS in GTK — the GIR says so at gtkwindow.c:1044 — so
|
|
353
|
+
* the property is the thing a caller watches, and this writes it directly rather than
|
|
354
|
+
* pretending to round-trip a compositor.
|
|
355
|
+
*/
|
|
356
|
+
maximize(): void {
|
|
357
|
+
this._write('maximized', 'true');
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/** `gtk_window_unmaximize`, with the same caveat as {@link maximize}. */
|
|
361
|
+
unmaximize(): void {
|
|
362
|
+
this._write('maximized', 'false');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
customElements.define('gtk-window', GtkWindow);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Pango's justification switch, as a CSS `text-align` — the one place this package spells
|
|
2
|
+
// it, because TWO widgets show justified text: `<gtk-label>` (through `Gtk.Label:justify`)
|
|
3
|
+
// and `<gtk-text-view>` (through `Gtk.TextView:justification`). The enum is Pango's, not
|
|
4
|
+
// either widget's: `gtk_text_view_set_justification` writes the same
|
|
5
|
+
// `layout->default_style->justification` (gtktextview.c:3560-3573) that `gtk_label_set_justify`
|
|
6
|
+
// writes, so the two properties take the same four nicks through the same layout field.
|
|
7
|
+
//
|
|
8
|
+
// LEFT and RIGHT are START and END of the TEXT DIRECTION, which is what the C means: a
|
|
9
|
+
// justified label reads `Gtk.Justification.LEFT` in either direction and lands on the leading
|
|
10
|
+
// edge. FILL is start-aligned lines with the spaces between words stretched, which is CSS
|
|
11
|
+
// `justify`.
|
|
12
|
+
//
|
|
13
|
+
// `normalizeLabelJustify` (`@gjsify/adwaita-core`) is the reader of the nick, and it reads it
|
|
14
|
+
// the same way for both widgets — which is what makes a shared table the right shape here
|
|
15
|
+
// rather than a second switch.
|
|
16
|
+
|
|
17
|
+
import type { LabelJustification } from '@gjsify/adwaita-core';
|
|
18
|
+
|
|
19
|
+
export const JUSTIFY_TEXT_ALIGN: Record<LabelJustification, string> = {
|
|
20
|
+
left: 'start',
|
|
21
|
+
right: 'end',
|
|
22
|
+
center: 'center',
|
|
23
|
+
fill: 'justify',
|
|
24
|
+
};
|
|
@@ -123,6 +123,30 @@ export class PopoverMenuView {
|
|
|
123
123
|
return this._rows;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
/**
|
|
127
|
+
* The path of the page showing; `[]` is the root.
|
|
128
|
+
*
|
|
129
|
+
* Public because `GtkPopoverMenu:visible-submenu` IS this: GTK's value is the
|
|
130
|
+
* `GtkStack` child's name (gtkpopovermenu.c:755-757), and the stack child's identity
|
|
131
|
+
* here is the path that leads to it. Reading it is how the element answers the
|
|
132
|
+
* property without keeping a second copy of the open page beside this one.
|
|
133
|
+
*/
|
|
134
|
+
get page(): AdwMenuPath {
|
|
135
|
+
return this._page;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Point the view at `path` without rendering — {@link render} does that, and doing it
|
|
140
|
+
* here as well would rebuild the rows twice per change.
|
|
141
|
+
*
|
|
142
|
+
* Distinct from {@link reset} because it NAMES the destination: a popover menu can be
|
|
143
|
+
* opened straight into a submenu, and a caller that had to open the parent first and
|
|
144
|
+
* then click into it would be reporting the reader's journey as the widget's state.
|
|
145
|
+
*/
|
|
146
|
+
showPage(path: AdwMenuPath): void {
|
|
147
|
+
this._page = [...path];
|
|
148
|
+
}
|
|
149
|
+
|
|
126
150
|
/**
|
|
127
151
|
* The rows a key can actually REACH, which is the only list worth focusing into.
|
|
128
152
|
*
|