diff --git a/StartMenu@sonichy/README.md b/HTYMenu@sonichy/README.md similarity index 100% rename from StartMenu@sonichy/README.md rename to HTYMenu@sonichy/README.md diff --git a/StartMenu@sonichy/extension.js b/HTYMenu@sonichy/extension.js similarity index 60% rename from StartMenu@sonichy/extension.js rename to HTYMenu@sonichy/extension.js index 633f6af..bceee07 100755 --- a/StartMenu@sonichy/extension.js +++ b/HTYMenu@sonichy/extension.js @@ -8,18 +8,31 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; import * as SystemActions from 'resource:///org/gnome/shell/misc/systemActions.js'; +import * as AppFavorites from 'resource:///org/gnome/shell/ui/appFavorites.js'; export default class DatetimeExtension extends Extension { enable() { - let indicator = new PanelMenu.Button(0.0, this.metadata.name, false); + this.indicator = new PanelMenu.Button(0.0, this.metadata.name, false); - let gicon = Gio.icon_new_for_string(this.dir.get_path() + '/gnome.svg'); - const icon = new St.Icon({ + this.settings = this.getSettings(); + this.settings.connectObject('changed', () => this.reload(), this); + + let icon_name = this.settings.get_string('icon-name'); + if (icon_name == '') + icon_name = this.dir.get_path() + '/gnome.svg'; + let gicon = Gio.icon_new_for_string(icon_name); + this.icon = new St.Icon({ gicon: gicon, - style_class: 'system-status-icon' + style_class: 'system-status-icon' }); - indicator.add_child(icon); + this.indicator.add_child(this.icon); + + //favorite + let menuItem = new PopupMenu.PopupSubMenuMenuItem('收藏', true, {}); + menuItem.icon.icon_name = 'favorite'; + this.indicator.menu.addMenuItem(menuItem); + this.loadFavorites(menuItem); // /usr/share/gnome-shell/extensions/arcmenu@arcmenu.com/menulayouts/baseMenuLayout.js let appSys = Shell.AppSystem.get_default(); @@ -38,7 +51,7 @@ export default class DatetimeExtension extends Extension { // /usr/share/gnome-shell/extensions/arcmenu@arcmenu.com/menulayouts/utils.js //console.log(dir.get_icon().to_string()); menuItem.icon.icon_name = dir.get_icon().to_string(); - indicator.menu.addMenuItem(menuItem); + this.indicator.menu.addMenuItem(menuItem); let iter1 = dir.iter(); let nextType1; while (nextType1 = iter1.next()) { @@ -54,30 +67,56 @@ export default class DatetimeExtension extends Extension { } } - let menuItem = new PopupMenu.PopupImageMenuItem('设置', 'settings', {}); + menuItem = new PopupMenu.PopupImageMenuItem('设置', 'settings', {}); menuItem.connect('activate', () => { + /* let id = 'org.gnome.Settings.desktop'; let app = appSys.lookup_app(id); app.open_new_window(-1); + */ + //https://gjs.guide/extensions/development/preferences.html + this.openPreferences(); }); - indicator.menu.addMenuItem(menuItem); + this.indicator.menu.addMenuItem(menuItem); // Shutdown // /usr/share/gnome-shell/extensions/arcmenu@arcmenu.com/menuButton.js let systemActions = SystemActions.getDefault(); menuItem = new PopupMenu.PopupSubMenuMenuItem('关机', true, {}); menuItem.icon.icon_name = 'system-shutdown'; - indicator.menu.addMenuItem(menuItem); + this.indicator.menu.addMenuItem(menuItem); menuItem.menu.addAction('关机', () => systemActions.activatePowerOff(), 'system-shutdown'); menuItem.menu.addAction('重启', () => systemActions.activateRestart(), 'system-reboot'); menuItem.menu.addAction('锁定', () => systemActions.activateLockScreen(), 'changes-prevent'); menuItem.menu.addAction('注销', () => systemActions.activateLogout(), 'system-log-out'); menuItem.menu.addAction('休眠', () => systemActions.activateSuspend(), 'weather-clear-night'); - Main.panel.addToStatusArea(this.uuid, indicator); + //Main.panel.addToStatusArea(this.uuid, this.indicator); + //https://extensions.gnome.org/review/51343 + Main.panel.addToStatusArea(this.uuid, this.indicator, 1, 'left'); } disable() { - } + this.indicator?.destroy(); + this.indicator = null; + } + + // /usr/share/gnome-shell/extensions/arcmenu@arcmenu.com/menulayouts/baseMenuLayout.js + //https://extensions.gnome.org/review/51343 + loadFavorites(menuItem) { + const appList = AppFavorites.getAppFavorites().getFavorites(); + for (let i=0; i app.open_new_window(-1), Gio.icon_new_for_string(app.get_icon().to_string())); + } + } + + reload() { + let icon_name = this.settings.get_string('icon-name'); + if (icon_name == '') + icon_name = this.dir.get_path() + '/gnome.svg'; + let gicon = Gio.icon_new_for_string(icon_name); + this.icon.gicon = gicon; + } } diff --git a/StartMenu@sonichy/gnome.svg b/HTYMenu@sonichy/gnome.svg similarity index 100% rename from StartMenu@sonichy/gnome.svg rename to HTYMenu@sonichy/gnome.svg diff --git a/HTYMenu@sonichy/metadata.json b/HTYMenu@sonichy/metadata.json new file mode 100755 index 0000000..7131ffd --- /dev/null +++ b/HTYMenu@sonichy/metadata.json @@ -0,0 +1,10 @@ +{ + "uuid": "HTYMenu@sonichy", + "name": "HTYMenu", + "description": "Display application list on GNOME taskbar", + "author": "sonichy", + "version": "2.0", + "shell-version": [ "45", "46", "47", "48" ], + "url": "https://github.com/sonichy/GNOME_extension", + "settings-schema": "org.gnome.shell.extensions.HTYMenu" +} diff --git a/HTYMenu@sonichy/prefs.js b/HTYMenu@sonichy/prefs.js new file mode 100644 index 0000000..4ebd965 --- /dev/null +++ b/HTYMenu@sonichy/prefs.js @@ -0,0 +1,226 @@ +import Gio from 'gi://Gio'; +import Adw from 'gi://Adw'; +import Gtk from 'gi://Gtk'; +import GLib from 'gi://GLib'; +import Gdk from 'gi://Gdk'; + +import { ExtensionPreferences, gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; +import * as Config from 'resource:///org/gnome/Shell/Extensions/js/misc/config.js'; + +export default class ExamplePreferences extends ExtensionPreferences { + fillPreferencesWindow(window) { + const settings = this.getSettings(); + + const page = new Adw.PreferencesPage({ + title: _('General'), + icon_name: 'settings', + }); + window.add(page); + + const group = new Adw.PreferencesGroup(); + page.add(group); + + let icon_name = settings.get_string('icon-name'); + if (icon_name == '') + icon_name = this.dir.get_path() + '/gnome.svg'; + const icon = new Gtk.Image({ + gicon: Gio.icon_new_for_string(icon_name), + pixel_size: 64 + }); + group.add(icon); + + const button = new Gtk.Button({ + label: _('Browse'), + valign: Gtk.Align.CENTER + }); + //button.container.add(icon); + button.connect('clicked', () => { + console.log('button clicked!'); + }); + const row_icon = new Adw.ActionRow({ + title: _('Choose a New Icon'), + activatable_widget: button, + subtitle: settings.get_string('icon-name') + }); + row_icon.add_suffix(button); + group.add(row_icon); + + // /usr/share/gnome-shell/extensions/arcmenu@arcmenu.com/settings/MenuButtonPage.js, IconChooserDialog + const searchEntry = new Gtk.SearchEntry({ + placeholder_text: '搜索...', + search_delay: 250 + }); + searchEntry.connect('search-changed', () => { + const query = searchEntry.text; + if (!query) { + filter.set_filter_func(null); + return; + } + filter.set_filter_func(item => { + return item.string.includes(query); + }); + }); + group.add(searchEntry); + + const iconThemeDefault = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()); + const iconTheme = new Gtk.IconTheme({ + resource_path: iconThemeDefault.resource_path, + theme_name: iconThemeDefault.theme_name + }); + const iconNames = iconTheme.get_icon_names(); + iconNames.sort((a, b) => a.localeCompare(b)); + const listStore = new Gtk.StringList({ strings: iconNames }); + + const filter = new Gtk.CustomFilter(); + const filterListModel = new Gtk.FilterListModel({ + model: listStore, + filter, + }); + const factory = new Gtk.SignalListItemFactory(); + factory.connect('setup', (factory_, item) => { + item.connect('notify::selected', () => { + let s = listView.model.get_selected_item().string; + icon.gicon = Gio.icon_new_for_string(s); + row_icon.subtitle = s; + settings.set_string('icon-name', s); + }); + const box = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, + spacing: 12, + margin_top: 3, + margin_bottom: 3, + margin_start: 12, + margin_end: 12, + }); + + const image = new Gtk.Image({ + pixel_size: 32, + hexpand: false, + halign: Gtk.Align.START, + }); + box.image = image; + + const label = new Gtk.Label({ + hexpand: false, + halign: Gtk.Align.START, + wrap: true, + //wrap_mode: Pango.WrapMode.WORD_CHAR, + }); + box.label = label; + + box.append(image); + box.append(label); + item.set_child(box); + }); + factory.connect('bind', (factory_, {child, item}) => { + const iconName = item.string; + child.image.icon_name = iconName; + child.label.label = iconName; + }); + const listView = new Gtk.ListView({ + model: new Gtk.SingleSelection({ model: filterListModel, autoselect: false, selected: -1 }), + factory, + vexpand: true, + valign: Gtk.Align.FILL, + }); + const scrollWindow = new Gtk.ScrolledWindow({ + child: listView, + //hscrollbar_policy: Gtk.PolicyType.NEVER, + //vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, + }); + group.add(scrollWindow); + + + // /usr/share/gnome-shell/extensions/arcmenu@arcmenu.com/settings/AboutPage.js + const page_about = new Adw.PreferencesPage({ + title: _('About'), + icon_name: 'dialog-information', + }); + window.add(page_about); + + const group_head = new Adw.PreferencesGroup(); + page_about.add(group_head); + + const projectImage = new Gtk.Image({ + icon_name: 'gnome_apps', + pixel_size: 100, + }); + group_head.add(projectImage); + + const projectTitleLabel = new Gtk.Label({ + label: _('HTYMenu'), + css_classes: ['title-1'], + //vexpand: true, + valign: Gtk.Align.FILL, + }); + group_head.add(projectTitleLabel); + + const projectDescriptionLabel = new Gtk.Label({ + label: 'GNOME 应用程序菜单扩展', + hexpand: false, + vexpand: false, + }); + group_head.add(projectDescriptionLabel); + + const group_info = new Adw.PreferencesGroup(); + page_about.add(group_info); + + const projectVersionRow = new Adw.ActionRow({ + title: 'HTYMenu Version', + }); + projectVersionRow.add_suffix(new Gtk.Label({ + label: '1.1', + css_classes: ['dim-label'], + })); + group_info.add(projectVersionRow); + + const gnomeVersionRow = new Adw.ActionRow({ + title: _('GNOME Version'), + }); + gnomeVersionRow.add_suffix(new Gtk.Label({ + label: Config.PACKAGE_VERSION.toString(), + css_classes: ['dim-label'], + })); + group_info.add(gnomeVersionRow); + + const osRow = new Adw.ActionRow({ + title: _('OS Name'), + }); + const name = GLib.get_os_info('NAME'); + const prettyName = GLib.get_os_info('PRETTY_NAME'); + osRow.add_suffix(new Gtk.Label({ + label: prettyName ? prettyName : name, + css_classes: ['dim-label'], + })); + group_info.add(osRow); + + const sessionTypeRow = new Adw.ActionRow({ + title: _('Window System'), + }); + sessionTypeRow.add_suffix(new Gtk.Label({ + label: GLib.getenv('XDG_SESSION_TYPE'), + css_classes: ['dim-label'], + })); + group_info.add(sessionTypeRow); + + const uri = 'https://github.com/sonichy/GNOME_extension'; + const linkRow = new Adw.ActionRow({ + title: 'Source', + activatable: true, + //tooltip_text: uri, + subtitle: uri + }); + linkRow.connect('activated', () => { + Gtk.show_uri(page_about.get_root(), uri, Gdk.CURRENT_TIME); + }); + const image = new Gtk.Image({ + icon_name: 'adw-external-link-symbolic', + valign: Gtk.Align.CENTER, + }); + linkRow.add_suffix(image); + group_info.add(linkRow); + + //window._settings = this.getSettings(); + //window._settings.bind('show-indicator', row, 'active', Gio.SettingsBindFlags.DEFAULT); + } +} diff --git a/HTYMenu@sonichy/preview.png b/HTYMenu@sonichy/preview.png new file mode 100644 index 0000000..fddb349 Binary files /dev/null and b/HTYMenu@sonichy/preview.png differ diff --git a/HTYMenu@sonichy/schemas/gschemas.compiled b/HTYMenu@sonichy/schemas/gschemas.compiled new file mode 100644 index 0000000..bf07ceb Binary files /dev/null and b/HTYMenu@sonichy/schemas/gschemas.compiled differ diff --git a/HTYMenu@sonichy/schemas/org.gnome.shell.extensions.HTYMenu.gschema.xml b/HTYMenu@sonichy/schemas/org.gnome.shell.extensions.HTYMenu.gschema.xml new file mode 100644 index 0000000..6c8ad98 --- /dev/null +++ b/HTYMenu@sonichy/schemas/org.gnome.shell.extensions.HTYMenu.gschema.xml @@ -0,0 +1,10 @@ + + + + + "" + Set icon name + Show icon by name in statusbar + + + diff --git a/README.md b/README.md index a285215..2ac3b5f 100755 --- a/README.md +++ b/README.md @@ -8,5 +8,8 @@ ## GSettings schema must be compiled `glib-compile-schemas schemas/` +## PreferencesPage +https://gjs.guide/extensions/development/preferences.html + ## Debug dbus-run-session -- gnome-shell --nested --wayland diff --git a/StartMenu@sonichy/metadata.json b/StartMenu@sonichy/metadata.json deleted file mode 100755 index 8bf0a3d..0000000 --- a/StartMenu@sonichy/metadata.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "uuid": "StartMenu@sonichy", - "name": "StartMenu", - "description": "Display application list on GNOME taskbar", - "author": "sonichy", - "version": "1.0", - "shell-version": [ "45", "46", "47", "48" ], - "url": "https://github.com/sonichy/GNOME_extension" -} diff --git a/StartMenu@sonichy/preview.png b/StartMenu@sonichy/preview.png deleted file mode 100644 index 1060133..0000000 Binary files a/StartMenu@sonichy/preview.png and /dev/null differ