gnome-shell/subprojects/extensions-app/data/ui/extensions-window.ui
Florian Müllner 7907b9754b extensions-app: Use ListModel to track extensions
Manually adding and removing rows to dynamic lists is rather
old-fashioned, GTK 4 strongly encourages the use of models.

Modernize the code by exposing extensions as ListModel, and
bind it to the two lists with appropriate filters.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3067>
2023-12-21 15:24:23 +00:00

250 lines
12 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="primary-menu">
<section>
<item>
<attribute name="label" translatable="yes">Keyboard Shortcuts</attribute>
<attribute name="action">win.show-help-overlay</attribute>
</item>
<item>
<attribute name="label" translatable="yes">About Extensions</attribute>
<attribute name="action">win.show-about</attribute>
</item>
</section>
</menu>
<object class="GtkSortListModel" id="sortModel">
<property name="sorter">
<object class="GtkStringSorter">
<property name="expression">
<lookup name="name" type="Extension"/>
</property>
</object>
</property>
</object>
<object class="GtkStringFilter" id="searchFilter">
<property name="ignore-case">true</property>
<property name="match-mode">substring</property>
<property name="expression">
<lookup name="name" type="Extension"/>
</property>
</object>
<object class="GtkFilterListModel" id="userListModel">
<property name="model">sortModel</property>
<property name="filter">
<object class="GtkBoolFilter">
<property name="expression">
<lookup name="is-user" type="Extension"/>
</property>
</object>
</property>
</object>
<object class="GtkFilterListModel" id="systemListModel">
<property name="model">sortModel</property>
<property name="filter">
<object class="GtkBoolFilter">
<property name="invert">true</property>
<property name="expression">
<lookup name="is-user" type="Extension"/>
</property>
</object>
</property>
</object>
<template class="ExtensionsWindow" parent="AdwApplicationWindow">
<property name="default-width">800</property>
<property name="default-height">500</property>
<property name="title" translatable="yes">Extensions</property>
<child>
<object class="AdwToolbarView">
<child type="top">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkMenuButton" id="menuButton">
<property name="tooltip-text" translatable="yes">Main Menu</property>
<property name="receives-default">True</property>
<property name="menu-model">primary-menu</property>
<property name="icon-name">open-menu-symbolic</property>
<property name="primary">True</property>
</object>
</child>
<child type="start">
<object class="GtkToggleButton" id="searchButton">
<property name="tooltip-text" translatable="yes">Search</property>
<property name="receives-default">True</property>
<property name="icon-name">edit-find-symbolic</property>
<child>
<object class="GtkShortcutController">
<property name='scope'>global</property>
<child>
<object class='GtkShortcut'>
<property name='trigger'>&lt;Control&gt;f</property>
<property name='action'>activate</property>
</object>
</child>
<child>
<object class='GtkShortcut'>
<property name='trigger'>&lt;Control&gt;s</property>
<property name='action'>activate</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="top">
<object class="GtkSearchBar" id="searchBar">
<property name="key-capture-widget">ExtensionsWindow</property>
<property name="search-mode-enabled"
bind-source="searchButton"
bind-property="active"
bind-flags="bidirectional"/>
<child>
<object class="GtkSearchEntry" id="searchEntry">
<property name="placeholder-text" translatable="yes">Search extensions</property>
<property name="max-width-chars">35</property>
</object>
</child>
</object>
</child>
<property name="content">
<object class="GtkStack" id="mainStack">
<property name="transition-type">crossfade</property>
<property name="vexpand">True</property>
<child>
<object class="GtkStackPage">
<property name="name">main</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwBanner" id="updatesBanner">
<property name="button-label" translatable="yes">Log Out…</property>
<property name="action-name">win.logout</property>
</object>
</child>
<child>
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">_Extensions</property>
<property name="activatable-widget">enabledSwitch</property>
<property name="use-underline">true</property>
<child type="suffix">
<object class="GtkMenuButton">
<property name="valign">center</property>
<property name="has-frame">false</property>
<property name="icon-name">info-symbolic</property>
<accessibility>
<property name="label" translatable="yes">More Information</property>
</accessibility>
<property name="popover">
<object class="GtkPopover" id="infoPopover">
<property name="child">
<object class="AdwClamp">
<property name="maximum-size">350</property>
<property name="tightening-threshold">350</property>
<property name="child">
<object class="GtkLabel">
<property name="label" translatable="yes">Extensions can cause performance and stability issues. It is recommended to disable all extensions if you experience problems with your system.</property>
<property name="wrap">true</property>
<!-- Hack to make the screen reader read the label -->
<property name="selectable"
bind-source="infoPopover"
bind-property="visible"
bind-flags="invert-boolean|sync-create"/>
</object>
</property>
</object>
</property>
</object>
</property>
</object>
</child>
<child type="suffix">
<object class="GtkSwitch" id="enabledSwitch">
<property name="action-name">win.user-extensions-enabled</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="userGroup">
<property name="title" translatable="yes">User Extensions</property>
<property name="visible"
bind-source="userListModel"
bind-property="n-items"
bind-flags="sync-create"/>
<child>
<object class="GtkListBox" id="userList">
<property name="selection-mode">none</property>
<accessibility>
<relation name="labelled-by">userGroup</relation>
</accessibility>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="systemGroup">
<property name="title" translatable="yes">System Extensions</property>
<property name="visible"
bind-source="systemListModel"
bind-property="n-items"
bind-flags="sync-create"/>
<child>
<object class="GtkListBox" id="systemList">
<property name="selection-mode">none</property>
<accessibility>
<relation name="labelled-by">systemGroup</relation>
</accessibility>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">placeholder</property>
<property name="child">
<object class="AdwStatusPage">
<property name="icon-name">org.gnome.Extensions-symbolic</property>
<property name="title" translatable="yes">No Installed Extensions</property>
<property name="description" translatable="yes">To find and add extensions, visit &lt;a href="https://extensions.gnome.org"&gt;extensions.gnome.org&lt;/a&gt;.</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">noshell</property>
<property name="child">
<object class="AdwStatusPage">
<property name="title" translatable="yes">Somethings gone wrong</property>
<property name="description" translatable="yes">Were very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again.</property>
</object>
</property>
</object>
</child>
</object>
</property>
</object>
</child>
</template>
</interface>