Skip to content
Snippets Groups Projects
Commit e4379f2c authored by Rocky Automation's avatar Rocky Automation :tv:
Browse files

import gnome-shell-extensions-3.32.1-39.el8_10

parent 3928b010
No related branches found
No related merge requests found
b6f22657a98bbccef7e7de48bd3f86c3169295f2707c53673e8eda9b3a49671b
8d4ab50f559137b8709496c216ff29df996a8d2fdfd5ed65876efca95186092f
From b9ba6b8708c18fb14033150fdb02a508457e0a17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 2 Feb 2024 15:39:32 +0100
Subject: [PATCH] classification-banner: Hide from picks
Banners are laid out via a fullscreen actor. While the actor is
not reactive, it can still interfere with picks (for example
during drag-and-drop operations).
Avoid that by explicitly hiding the actor from picks.
---
extensions/classification-banner/extension.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/extensions/classification-banner/extension.js b/extensions/classification-banner/extension.js
index ea788022..2bde741e 100644
--- a/extensions/classification-banner/extension.js
+++ b/extensions/classification-banner/extension.js
@@ -18,7 +18,7 @@
/* exported init */
-const { Clutter, Gio, GLib, GObject, St } = imports.gi;
+const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Layout = imports.ui.layout;
@@ -34,6 +34,8 @@ class ClassificationBanner extends Clutter.Actor {
});
this._monitorConstraint = constraint;
+ Shell.util_set_hidden_from_pick(this, true);
+
this._settings = ExtensionUtils.getSettings();
this.connect('destroy', () => {
if (this._fullscreenChangedId)
--
2.43.0
From 0f13a5e00d9115b4d1518c91aa45c88f3e7e7c27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 2 Nov 2023 20:51:45 +0100
Subject: [PATCH] desktop-icons: Don't try spawn with non-existent workdir
g_spawn_async() will fail if the specified workdir doesn't exist.
That means that opening a terminal from the context menu will fail
when the desktop directory doesn't exist.
The extension doesn't really make sense in that case, but when we
show an "Open in Terminal" menu item even then, users expect it
to work.
---
extensions/desktop-icons/desktopIconsUtil.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/extensions/desktop-icons/desktopIconsUtil.js b/extensions/desktop-icons/desktopIconsUtil.js
index 0aea6542..c1a0dda3 100644
--- a/extensions/desktop-icons/desktopIconsUtil.js
+++ b/extensions/desktop-icons/desktopIconsUtil.js
@@ -49,6 +49,9 @@ function launchTerminal(workdir) {
* https://gitlab.gnome.org/GNOME/gnome-shell/blob/gnome-3-30/js/misc/util.js
*/
+ if (!GLib.file_test(workdir, GLib.FileTest.EXISTS))
+ workdir = null;
+
var success, pid;
try {
[success, pid] = GLib.spawn_async(workdir, argv, null,
--
2.41.0
From f954feefa637e3cd6f92450076c0ef0941fd6763 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 12 Sep 2023 19:29:22 +0200
Subject: [PATCH] panel-favorites: Update to upstream version
---
extensions/panel-favorites/extension.js | 559 ++++++++++++++----
extensions/panel-favorites/meson.build | 6 +
extensions/panel-favorites/prefs.js | 293 +++++++++
...ell.extensions.panel-favorites.gschema.xml | 41 ++
extensions/panel-favorites/stylesheet.css | 8 +-
5 files changed, 797 insertions(+), 110 deletions(-)
create mode 100644 extensions/panel-favorites/prefs.js
create mode 100644 extensions/panel-favorites/schemas/org.gnome.shell.extensions.panel-favorites.gschema.xml
diff --git a/extensions/panel-favorites/extension.js b/extensions/panel-favorites/extension.js
index b817dbb6..5495dc3f 100644
--- a/extensions/panel-favorites/extension.js
+++ b/extensions/panel-favorites/extension.js
@@ -1,32 +1,38 @@
-// Copyright (C) 2011-2013 R M Yorston
+// Copyright (C) 2011-2020 R M Yorston
// Licence: GPLv2+
-const Clutter = imports.gi.Clutter;
-const Gio = imports.gi.Gio;
-const GLib = imports.gi.GLib;
-const Lang = imports.lang;
-const Shell = imports.gi.Shell;
+const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
const Signals = imports.signals;
-const St = imports.gi.St;
-const Mainloop = imports.mainloop;
const AppFavorites = imports.ui.appFavorites;
const Main = imports.ui.main;
const Panel = imports.ui.panel;
+const PanelMenu = imports.ui.panelMenu;
+const PopupMenu = imports.ui.popupMenu;
const Tweener = imports.ui.tweener;
+const ExtensionUtils = imports.misc.extensionUtils;
+
+const _f = imports.gettext.domain('frippery-panel-favorites').gettext;
+
const PANEL_LAUNCHER_LABEL_SHOW_TIME = 0.15;
const PANEL_LAUNCHER_LABEL_HIDE_TIME = 0.1;
const PANEL_LAUNCHER_HOVER_TIMEOUT = 300;
-const PanelLauncher = new Lang.Class({
- Name: 'PanelLauncher',
+const SETTINGS_FAVORITES_ENABLED = 'favorites-enabled';
+const SETTINGS_FAVORITES_POSITION = 'favorites-position';
+const SETTINGS_OTHER_APPS_ENABLED = 'other-apps-enabled';
+const SETTINGS_OTHER_APPS_POSITION = 'other-apps-position';
+const SETTINGS_OTHER_APPS = 'other-apps';
- _init: function(app) {
+const PanelLauncher =
+class PanelLauncher {
+ constructor(app) {
this.actor = new St.Button({ style_class: 'panel-button',
reactive: true });
- this.iconSize = 24;
- let icon = app.create_icon_texture(this.iconSize);
+ let gicon = app.app_info.get_icon();
+ let icon = new St.Icon({ gicon: gicon,
+ style_class: 'panel-launcher-icon'});
this.actor.set_child(icon);
this.actor._delegate = this;
let text = app.get_name();
@@ -41,31 +47,66 @@ const PanelLauncher = new Lang.Class({
this.actor.label_actor = this.label;
this._app = app;
- this.actor.connect('clicked', Lang.bind(this, function() {
+ this._menu = null;
+ this._menuManager = new PopupMenu.PopupMenuManager(this);
+
+ this.actor.connect('clicked', () => {
this._app.open_new_window(-1);
- }));
+ if ( Main.overview.visible ) {
+ Main.overview.hide();
+ }
+ });
this.actor.connect('notify::hover',
- Lang.bind(this, this._onHoverChanged));
+ this._onHoverChanged.bind(this));
+ this.actor.connect('button-press-event',
+ this._onButtonPress.bind(this));
this.actor.opacity = 207;
+ }
- this.actor.connect('notify::allocation', Lang.bind(this, this._alloc));
- },
-
- _onHoverChanged: function(actor) {
+ _onHoverChanged(actor) {
actor.opacity = actor.hover ? 255 : 207;
- },
-
- _alloc: function() {
- let size = this.actor.allocation.y2 - this.actor.allocation.y1 - 3;
- if ( size >= 24 && size != this.iconSize ) {
- this.actor.get_child().destroy();
- this.iconSize = size;
- let icon = this._app.create_icon_texture(this.iconSize);
- this.actor.set_child(icon);
+ }
+
+ _onButtonPress(actor, event) {
+ let button = event.get_button();
+ if (button == 3) {
+ this.popupMenu();
+ return Clutter.EVENT_STOP;
+ }
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ // this code stolen from appDisplay.js
+ popupMenu() {
+ if (!this._menu) {
+ this._menu = new AppIconMenu(this);
+ this._menu.connect('activate-window', (menu, window) => {
+ this.activateWindow(window);
+ });
+ this._menu.connect('open-state-changed', (menu, isPoppedUp) => {
+ if (!isPoppedUp)
+ this.actor.sync_hover();
+ });
+
+ this._menuManager.addMenu(this._menu);
}
- },
- showLabel: function() {
+ this.actor.set_hover(true);
+ this._menu.popup();
+ this._menuManager.ignoreRelease();
+
+ return false;
+ }
+
+ activateWindow(metaWindow) {
+ if (metaWindow) {
+ Main.activateWindow(metaWindow);
+ } else {
+ Main.overview.hide();
+ }
+ }
+
+ showLabel() {
this.label.opacity = 0;
this.label.show();
@@ -101,58 +142,105 @@ const PanelLauncher = new Lang.Class({
time: PANEL_LAUNCHER_LABEL_SHOW_TIME,
transition: 'easeOutQuad',
});
- },
+ }
- hideLabel: function() {
+ hideLabel() {
this.label.opacity = 255;
Tweener.addTween(this.label,
{ opacity: 0,
time: PANEL_LAUNCHER_LABEL_HIDE_TIME,
transition: 'easeOutQuad',
- onComplete: Lang.bind(this, function() {
- this.label.hide();
- })
+ onComplete: () => this.label.hide()
});
- },
+ }
- destroy: function() {
+ destroy() {
this.label.destroy();
this.actor.destroy();
}
-});
+};
+
+const ApplicationMenuItem =
+class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem {
+ constructor(app, params) {
+ super(params);
+
+ let box = new St.BoxLayout({ name: 'applicationMenuBox',
+ style_class: 'applications-menu-item-box'});
+ this.actor.add_child(box);
+
+ let icon = app.create_icon_texture(24);
+ box.add(icon, { x_fill: false, y_fill: false });
+
+ let name = app.get_name();
+
+ let matches = /^(OpenJDK Policy Tool) (.*)/.exec(name);
+ if ( matches && matches.length == 3 ) {
+ name = matches[1] + '\n' + matches[2];
+ }
-const PanelFavorites = new Lang.Class({
- Name: 'PanelFavorites',
+ matches = /^(OpenJDK 8 Policy Tool) (.*)/.exec(name);
+ if ( matches && matches.length == 3 ) {
+ name = matches[1] + '\n' + matches[2];
+ }
+
+ matches = /^(OpenJDK Monitoring & Management Console) (.*)/.exec(name);
+ if ( matches && matches.length == 3 ) {
+ name = 'OpenJDK Console\n' + matches[2];
+ }
+
+ matches = /^(OpenJDK 8 Monitoring & Management Console) (.*)/.exec(name);
+ if ( matches && matches.length == 3 ) {
+ name = 'OpenJDK 8 Console\n' + matches[2];
+ }
+
+ let label = new St.Label({ text: name });
+ box.add(label);
+
+ this.app = app;
- _init: function() {
+ this.connect('activate', () => {
+ let id = this.app.get_id();
+ let app = Shell.AppSystem.get_default().lookup_app(id);
+ app.open_new_window(-1);
+ });
+ }
+};
+
+const PanelAppsButton = GObject.registerClass(
+class PanelAppsButton extends PanelMenu.Button {
+ _init(details) {
+ super._init(0.5, details.description, false);
this._showLabelTimeoutId = 0;
this._resetHoverTimeoutId = 0;
this._labelShowing = false;
- this.actor = new St.BoxLayout({ name: 'panelFavorites',
+ this.name = details.name;
+ this._details = details;
+
+ this._box = new St.BoxLayout({ name: 'panelFavoritesBox',
x_expand: true, y_expand: true,
style_class: 'panel-favorites' });
- this._display();
+ this.add_actor(this._box);
- this.container = new St.Bin({ y_fill: true,
- x_fill: true,
- child: this.actor });
+ this.connect('destroy', this._onDestroy.bind(this));
+ this._installChangedId = Shell.AppSystem.get_default().connect('installed-changed', this._redisplay.bind(this));
+ this._changedId = details.change_object.connect(details.change_event, this._redisplay.bind(this));
- this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
- this._installChangedId = Shell.AppSystem.get_default().connect('installed-changed', Lang.bind(this, this._redisplay));
- this._changedId = AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._redisplay));
- },
+ this._display();
+ }
- _redisplay: function() {
+ _redisplay() {
for ( let i=0; i<this._buttons.length; ++i ) {
this._buttons[i].destroy();
}
+ this.menu.removeAll();
this._display();
- },
+ }
- _display: function() {
- let launchers = global.settings.get_strv(AppFavorites.getAppFavorites().FAVORITE_APPS_KEY);
+ _display() {
+ let launchers = this._details.settings.get_strv(this._details.key);
this._buttons = [];
let j = 0;
@@ -164,104 +252,361 @@ const PanelFavorites = new Lang.Class({
}
let launcher = new PanelLauncher(app);
- this.actor.add(launcher.actor);
+ this._box.add(launcher.actor);
launcher.actor.connect('notify::hover',
- Lang.bind(this, function() {
- this._onHover(launcher);
- }));
+ () => this._onHover(launcher));
this._buttons[j] = launcher;
+
+ let menuItem = new ApplicationMenuItem(app);
+ this.menu.addMenuItem(menuItem, j);
++j;
}
- },
+ }
// this routine stolen from dash.js
- _onHover: function(launcher) {
+ _onHover(launcher) {
if ( launcher.actor.hover ) {
if (this._showLabelTimeoutId == 0) {
let timeout = this._labelShowing ?
0 : PANEL_LAUNCHER_HOVER_TIMEOUT;
- this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
- Lang.bind(this, function() {
+ this._showLabelTimeoutId = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT, timeout,
+ () => {
this._labelShowing = true;
launcher.showLabel();
this._showLabelTimeoutId = 0;
return GLib.SOURCE_REMOVE;
- }));
+ });
if (this._resetHoverTimeoutId > 0) {
- Mainloop.source_remove(this._resetHoverTimeoutId);
+ GLib.source_remove(this._resetHoverTimeoutId);
this._resetHoverTimeoutId = 0;
}
}
} else {
if (this._showLabelTimeoutId > 0) {
- Mainloop.source_remove(this._showLabelTimeoutId);
+ GLib.source_remove(this._showLabelTimeoutId);
this._showLabelTimeoutId = 0;
}
launcher.hideLabel();
if (this._labelShowing) {
- this._resetHoverTimeoutId = Mainloop.timeout_add(
- PANEL_LAUNCHER_HOVER_TIMEOUT,
- Lang.bind(this, function() {
+ this._resetHoverTimeoutId = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT, PANEL_LAUNCHER_HOVER_TIMEOUT,
+ () => {
this._labelShowing = false;
this._resetHoverTimeoutId = 0;
return GLib.SOURCE_REMOVE;
- }));
+ });
}
}
- },
+ }
- _onDestroy: function() {
+ _onDestroy() {
if ( this._installChangedId != 0 ) {
Shell.AppSystem.get_default().disconnect(this._installChangedId);
this._installChangedId = 0;
}
if ( this._changedId != 0 ) {
- AppFavorites.getAppFavorites().disconnect(this._changedId);
+ this._details.change_object.disconnect(this._changedId);
this._changedId = 0;
}
}
});
-Signals.addSignalMethods(PanelFavorites.prototype);
-let myAddToStatusArea;
-let panelFavorites;
+// this code stolen from appDisplay.js
+const AppIconMenu =
+class AppIconMenu extends PopupMenu.PopupMenu {
+ constructor(source) {
+ super(source.actor, 0.5, St.Side.TOP);
-function enable() {
- Panel.Panel.prototype.myAddToStatusArea = myAddToStatusArea;
+ // We want to keep the item hovered while the menu is up
+ this.blockSourceEvents = true;
- // place panel to left of app menu, or failing that at right end of box
- let siblings = Main.panel._leftBox.get_children();
- let appMenu = Main.panel.statusArea['appMenu'];
- let pos = appMenu ? siblings.indexOf(appMenu.container) : siblings.length;
+ this._source = source;
- panelFavorites = new PanelFavorites();
- Main.panel.myAddToStatusArea('panel-favorites', panelFavorites,
- pos, 'left');
-}
+ this.actor.add_style_class_name('panel-menu');
-function disable() {
- delete Panel.Panel.prototype.myAddToStatusArea;
+ // Chain our visibility and lifecycle to that of the source
+ this._sourceMappedId = source.actor.connect('notify::mapped', () => {
+ if (!source.actor.mapped)
+ this.close();
+ });
+ source.actor.connect('destroy', () => {
+ source.actor.disconnect(this._sourceMappedId);
+ this.destroy();
+ });
- panelFavorites.actor.destroy();
- panelFavorites.emit('destroy');
- panelFavorites = null;
-}
+ Main.uiGroup.add_actor(this.actor);
+ }
+
+ _redisplay() {
+ this.removeAll();
+
+ // find windows on current and other workspaces
+ let activeWorkspace = global.workspace_manager.get_active_workspace();
+
+ let w_here = this._source._app.get_windows().filter(function(w) {
+ return !w.skip_taskbar && w.get_workspace() == activeWorkspace;
+ });
+
+ let w_there = this._source._app.get_windows().filter(function(w) {
+ return !w.skip_taskbar && w.get_workspace() != activeWorkspace;
+ });
+
+ // if we have lots of windows use submenus in both cases to
+ // avoid confusion
+ let use_submenu = w_here.length + w_there.length > 10;
+
+ this._appendWindows(use_submenu, _f('This Workspace'), w_here);
+
+ if (w_here.length && !use_submenu) {
+ this._appendSeparator();
+ }
+
+ this._appendWindows(use_submenu, _f('Other Workspaces'), w_there);
+
+ if (!this._source._app.is_window_backed()) {
+ if (w_there.length && !use_submenu) {
+ this._appendSeparator();
+ }
+
+ let appInfo = this._source._app.get_app_info();
+ let actions = appInfo.list_actions();
+ if (this._source._app.can_open_new_window() &&
+ actions.indexOf('new-window') == -1) {
+ let item = this._appendMenuItem(_('New Window'));
+ item.connect('activate', () => {
+ this._source._app.open_new_window(-1);
+ this.emit('activate-window', null);
+ });
+ }
+
+ for (let i = 0; i < actions.length; i++) {
+ let action = actions[i];
+ let item = this._appendMenuItem(appInfo.get_action_name(action));
+ item.connect('activate', (emitter, event) => {
+ this._source._app.launch_action(action, event.get_time(), -1);
+ this.emit('activate-window', null);
+ });
+ }
+
+ let canFavorite = global.settings.is_writable('favorite-apps');
+
+ if (canFavorite) {
+ let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source._app.get_id());
+
+ if (isFavorite) {
+ let item = this._appendMenuItem(_('Remove from Favorites'));
+ item.connect('activate', () => {
+ let favs = AppFavorites.getAppFavorites();
+ favs.removeFavorite(this._source._app.get_id());
+ });
+ } else {
+ let item = this._appendMenuItem(_('Add to Favorites'));
+ item.connect('activate', () => {
+ let favs = AppFavorites.getAppFavorites();
+ favs.addFavorite(this._source.app.get_id());
+ });
+ }
+ }
+
+ if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) {
+ let item = this._appendMenuItem(_('Show Details'));
+ item.connect('activate', () => {
+ let id = this._source._app.get_id();
+ let args = GLib.Variant.new('(ss)', [id, '']);
+ Gio.DBus.get(Gio.BusType.SESSION, null, (o, res) => {
+ let bus = Gio.DBus.get_finish(res);
+ bus.call('org.gnome.Software',
+ '/org/gnome/Software',
+ 'org.gtk.Actions', 'Activate',
+ GLib.Variant.new('(sava{sv})',
+ ['details', [args], null]),
+ null, 0, -1, null, null);
+ Main.overview.hide();
+ });
+ });
+ }
+ }
+ }
+
+ _appendWindows(use_submenu, text, windows) {
+ let parent = this;
+ if (windows.length && use_submenu) {
+ // if we have lots of activatable windows create a submenu
+ let item = new PopupMenu.PopupSubMenuMenuItem(text);
+ this.addMenuItem(item);
+ parent = item.menu;
+ }
+ for (let i = 0; i < windows.length; i++) {
+ let window = windows[i];
+ let item = new PopupMenu.PopupMenuItem(window.title);
+ parent.addMenuItem(item);
+ item.connect('activate', () =>
+ this.emit('activate-window', window));
+ }
+ }
+
+ _appendSeparator() {
+ let separator = new PopupMenu.PopupSeparatorMenuItem();
+ this.addMenuItem(separator);
+ }
+
+ _appendMenuItem(labelText) {
+ let item = new PopupMenu.PopupMenuItem(labelText);
+ this.addMenuItem(item);
+ return item;
+ }
+
+ popup(activatingButton) {
+ // this code stolen from PanelMenuButton
+ // limit height of menu: the menu should have scrollable submenus
+ // for this to make sense
+ let workArea = Main.layoutManager.getWorkAreaForMonitor(
+ Main.layoutManager.primaryIndex);
+ let verticalMargins = this.actor.margin_top + this.actor.margin_bottom;
+ this.actor.style = ('max-height: ' + Math.round(workArea.height -
+ verticalMargins) + 'px;');
+
+ this._source.label.hide();
+ this._redisplay();
+ this.open();
+ }
+};
+Signals.addSignalMethods(AppIconMenu.prototype);
+
+const FAVORITES = 0;
+const OTHER_APPS = 1;
+
+const PanelFavoritesExtension =
+class PanelFavoritesExtension {
+ constructor() {
+ ExtensionUtils.initTranslations();
+ this._panelAppsButton = [ null, null ];
+ this._settings = ExtensionUtils.getSettings();
+ }
+
+ _getPosition(key) {
+ let position, box;
+ // if key is false use left box, if true use right
+ if (!this._settings.get_boolean(key)) {
+ // place panel to left of app menu
+ let siblings = Main.panel._leftBox.get_children();
+ let appMenu = Main.panel.statusArea['appMenu'];
+ position = appMenu ?
+ siblings.indexOf(appMenu.container) : siblings.length;
+ box = 'left';
+ }
+ else {
+ // place panel to left of aggregate menu
+ let siblings = Main.panel._rightBox.get_children();
+ let aggMenu = Main.panel.statusArea['aggregateMenu'];
+ position = aggMenu ?
+ siblings.indexOf(aggMenu.container) : siblings.length-1;
+ box = 'right';
+ }
+ return [position, box];
+ }
+
+ _configureButtons() {
+ let details = [
+ {
+ description: _f('Favorites'),
+ name: 'panelFavorites',
+ settings: global.settings,
+ key: AppFavorites.getAppFavorites().FAVORITE_APPS_KEY,
+ change_object: AppFavorites.getAppFavorites(),
+ change_event: 'changed'
+ },
+ {
+ description: _f('Other Applications'),
+ name: 'panelOtherApps',
+ settings: ExtensionUtils.getSettings(),
+ key: SETTINGS_OTHER_APPS,
+ change_object: ExtensionUtils.getSettings(),
+ change_event: 'changed::' + SETTINGS_OTHER_APPS
+ }
+ ];
+ let role = [ 'panel-favorites', 'panel-other-apps' ];
+ let prefix = [ 'favorites-', 'other-apps-' ];
+
+ for ( let i=0; i<this._panelAppsButton.length; ++i ) {
+ if (this._settings.get_boolean(prefix[i]+'enabled')) {
+ if (!this._panelAppsButton[i]) {
+ // button is enabled but doesn't exist, create it
+ this._panelAppsButton[i] = new PanelAppsButton(details[i]);
+ }
+ }
+ else {
+ if (this._panelAppsButton[i]) {
+ // button is disabled but does exist, destroy it
+ this._panelAppsButton[i].emit('destroy');
+ this._panelAppsButton[i].actor.destroy();
+ this._panelAppsButton[i] = null;
+ }
+ }
+
+ if (this._panelAppsButton[i]) {
+ let indicator = Main.panel.statusArea[role[i]];
+ let key = prefix[i]+'position';
+ let [position, box] = this._getPosition(key);
+
+ if (!indicator) {
+ // indicator with required role doesn't exist, create it
+ Main.panel.addToStatusArea(role[i],
+ this._panelAppsButton[i], position, box);
+ }
+ else {
+ let right_box, wrong_box;
+ if (this._settings.get_boolean(key)) {
+ right_box = Main.panel._rightBox;
+ wrong_box = Main.panel._leftBox;
+ }
+ else {
+ right_box = Main.panel._leftBox;
+ wrong_box = Main.panel._rightBox;
+ }
+
+ let children = wrong_box.get_children();
+ if (children.indexOf(indicator.container) != -1) {
+ // indicator exists but is in wrong box, move it
+ wrong_box.remove_actor(indicator.container);
+ right_box.insert_child_at_index(indicator.container,
+ position);
+ }
+ }
+ }
+ }
+ }
+
+ enable() {
+ this._configureButtons();
+ this._changedId = this._settings.connect('changed',
+ this._configureButtons.bind(this));
+ }
+
+ disable() {
+ let role = [ 'panel-favorites', 'panel-other-apps' ];
+
+ if (this._changedId) {
+ this._settings.disconnect(this._changedId);
+ }
+
+ for ( let i=0; i<this._panelAppsButton.length; ++i ) {
+ if (this._panelAppsButton[i]) {
+ let indicator = Main.panel.statusArea[role[i]];
+ if (indicator) {
+ let parent = indicator.container.get_parent();
+ parent.remove_actor(indicator.container);
+ }
+ this._panelAppsButton[i].emit('destroy');
+ this._panelAppsButton[i].actor.destroy();
+ this._panelAppsButton[i] = null;
+ }
+ }
+ }
+};
function init() {
- myAddToStatusArea = function(role, indicator, position, box) {
- if (this.statusArea[role])
- throw new Error('Extension point conflict: there is already a status indicator for role ' + role);
-
- position = position || 0;
- let boxes = {
- left: this._leftBox,
- center: this._centerBox,
- right: this._rightBox
- };
- let boxContainer = boxes[box] || this._rightBox;
- this.statusArea[role] = indicator;
- this._addToPanelBox(role, indicator, position, boxContainer);
- return indicator;
- };
+ return new PanelFavoritesExtension();
}
diff --git a/extensions/panel-favorites/meson.build b/extensions/panel-favorites/meson.build
index 48504f63..ab6967fa 100644
--- a/extensions/panel-favorites/meson.build
+++ b/extensions/panel-favorites/meson.build
@@ -3,3 +3,9 @@ extension_data += configure_file(
output: metadata_name,
configuration: metadata_conf
)
+
+extension_sources += files(
+ 'prefs.js'
+)
+
+extension_schemas += files('schemas/' + metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/panel-favorites/prefs.js b/extensions/panel-favorites/prefs.js
new file mode 100644
index 00000000..410034f5
--- /dev/null
+++ b/extensions/panel-favorites/prefs.js
@@ -0,0 +1,293 @@
+// Copyright (C) 2015-2019 R M Yorston
+// Licence: GPLv2+
+
+/* stolen from the workspace-indicator extension */
+const { Gio, GObject, Gtk } = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+
+const _f = imports.gettext.domain('frippery-panel-favorites').gettext;
+
+const SETTINGS_FAVORITES_ENABLED = 'favorites-enabled';
+const SETTINGS_FAVORITES_POSITION = 'favorites-position';
+const SETTINGS_OTHER_APPS_ENABLED = 'other-apps-enabled';
+const SETTINGS_OTHER_APPS_POSITION = 'other-apps-position';
+const SETTINGS_OTHER_APPS = 'other-apps';
+
+const AppsModel = GObject.registerClass(
+class AppsModel extends Gtk.ListStore {
+ _init(params) {
+ super._init(params);
+ this.set_column_types([GObject.TYPE_STRING]);
+
+ this.Columns = {
+ LABEL: 0,
+ };
+
+ this._settings = ExtensionUtils.getSettings();
+
+ this._reloadFromSettings();
+
+ // overriding class closure doesn't work, because GtkTreeModel
+ // plays tricks with marshallers and class closures
+ this.connect('row-changed', this._onRowChanged.bind(this));
+ this.connect('row-inserted', this._onRowInserted.bind(this));
+ this.connect('row-deleted', this._onRowDeleted.bind(this));
+ }
+
+ _reloadFromSettings() {
+ if (this._preventChanges)
+ return;
+ this._preventChanges = true;
+
+ let newNames = this._settings.get_strv(SETTINGS_OTHER_APPS);
+
+ let i = 0;
+ let [ok, iter] = this.get_iter_first();
+ while (ok && i < newNames.length) {
+ this.set(iter, [this.Columns.LABEL], [newNames[i]]);
+
+ ok = this.iter_next(iter);
+ i++;
+ }
+
+ while (ok)
+ ok = this.remove(iter);
+
+ for ( ; i < newNames.length; i++) {
+ iter = this.append();
+ this.set(iter, [this.Columns.LABEL], [newNames[i]]);
+ }
+
+ this._preventChanges = false;
+ }
+
+ _onRowChanged(self, path, iter) {
+ if (this._preventChanges)
+ return;
+ this._preventChanges = true;
+
+ let index = path.get_indices()[0];
+ let names = this._settings.get_strv(SETTINGS_OTHER_APPS);
+
+ if (index >= names.length) {
+ // fill with blanks
+ for (let i = names.length; i <= index; i++)
+ names[i] = '';
+ }
+
+ names[index] = this.get_value(iter, this.Columns.LABEL);
+
+ this._settings.set_strv(SETTINGS_OTHER_APPS, names);
+
+ this._preventChanges = false;
+ }
+
+ _onRowInserted(self, path, iter) {
+ if (this._preventChanges)
+ return;
+ this._preventChanges = true;
+
+ let index = path.get_indices()[0];
+ let names = this._settings.get_strv(SETTINGS_OTHER_APPS);
+ let label = this.get_value(iter, this.Columns.LABEL) || '';
+ names.splice(index, 0, label);
+
+ this._settings.set_strv(SETTINGS_OTHER_APPS, names);
+
+ this._preventChanges = false;
+ }
+
+ _onRowDeleted(self, path) {
+ if (this._preventChanges)
+ return;
+ this._preventChanges = true;
+
+ let index = path.get_indices()[0];
+ let names = this._settings.get_strv(SETTINGS_OTHER_APPS);
+
+ if (index >= names.length)
+ return;
+
+ names.splice(index, 1);
+
+ // compact the array
+ for (let i = names.length -1; i >= 0 && !names[i]; i++)
+ names.pop();
+
+ this._settings.set_strv(SETTINGS_OTHER_APPS, names);
+
+ this._preventChanges = false;
+ }
+});
+
+const PanelFavoritesSettingsWidget = GObject.registerClass(
+class PanelFavoritesSettingsWidget extends Gtk.Grid {
+ _init(params) {
+ super._init(params);
+ this.margin = 12;
+ this.orientation = Gtk.Orientation.VERTICAL;
+ this._settings = ExtensionUtils.getSettings();
+
+ this.add(new Gtk.Label({
+ label: '<b>' + _f("Favorites") + '</b>',
+ use_markup: true, margin_bottom: 6,
+ hexpand: true, halign: Gtk.Align.START }));
+
+ let align = new Gtk.Alignment({ left_padding: 12 });
+ this.add(align);
+
+ let grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
+ row_spacing: 6,
+ column_spacing: 6 });
+ align.add(grid);
+
+ let state = this._settings.get_boolean(SETTINGS_FAVORITES_ENABLED);
+ let check = new Gtk.CheckButton({ label: _f("Enable"),
+ active: state,
+ margin_top: 6 });
+ this._settings.bind(SETTINGS_FAVORITES_ENABLED, check, 'active', Gio.SettingsBindFlags.DEFAULT);
+ grid.add(check);
+
+ let box = new Gtk.HBox();
+ grid.add(box);
+
+ box.pack_start(new Gtk.Label({ label: _f("Position"),
+ halign: Gtk.Align.START }),
+ false, true, 6);
+
+ state = this._settings.get_boolean(SETTINGS_FAVORITES_POSITION);
+ let radio = null;
+ radio = new Gtk.RadioButton({ active: !state,
+ label: _f('Left'),
+ group: radio });
+ box.pack_start(radio, false, true, 6);
+
+ radio = new Gtk.RadioButton({ active: state,
+ label: _f('Right'),
+ group: radio });
+ this._settings.bind(SETTINGS_FAVORITES_POSITION, radio, 'active',
+ Gio.SettingsBindFlags.DEFAULT);
+ radio.set_active(state);
+ box.pack_start(radio, false, true, 6);
+
+
+ this.add(new Gtk.Label({
+ label: '<b>' + _f("Other Applications") + '</b>',
+ use_markup: true, margin_bottom: 6, margin_top: 12,
+ hexpand: true, halign: Gtk.Align.START }));
+
+ align = new Gtk.Alignment({ left_padding: 12 });
+ this.add(align);
+
+ grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
+ row_spacing: 6,
+ column_spacing: 6 });
+ align.add(grid);
+
+ state = this._settings.get_boolean(SETTINGS_OTHER_APPS_ENABLED);
+ check = new Gtk.CheckButton({ label: _f("Enable"),
+ active: state,
+ margin_top: 6 });
+ this._settings.bind(SETTINGS_OTHER_APPS_ENABLED, check, 'active',
+ Gio.SettingsBindFlags.DEFAULT);
+ grid.add(check);
+
+ box = new Gtk.HBox();
+ grid.add(box);
+
+ box.pack_start(new Gtk.Label({
+ label: _f("Position"),
+ halign: Gtk.Align.START }),
+ false, true, 6);
+
+ state = this._settings.get_boolean(SETTINGS_OTHER_APPS_POSITION);
+ radio = null;
+ radio = new Gtk.RadioButton({ active: !state,
+ label: _f('Left'),
+ group: radio });
+ box.pack_start(radio, false, true, 6);
+
+ radio = new Gtk.RadioButton({ active: state,
+ label: _f('Right'),
+ group: radio });
+ this._settings.bind(SETTINGS_OTHER_APPS_POSITION, radio, 'active',
+ Gio.SettingsBindFlags.DEFAULT);
+ radio.set_active(state);
+ box.pack_start(radio, false, true, 6);
+
+ let scrolled = new Gtk.ScrolledWindow({ shadow_type: Gtk.ShadowType.IN });
+ scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+ grid.add(scrolled);
+
+ this._store = new AppsModel();
+ this._treeView = new Gtk.TreeView({ model: this._store,
+ headers_visible: false,
+ reorderable: true,
+ hexpand: true,
+ vexpand: true
+ });
+
+ let column = new Gtk.TreeViewColumn({ title: _f("Launcher") });
+ let renderer = new Gtk.CellRendererText({ editable: true });
+ renderer.connect('edited', this._cellEdited.bind(this));
+ column.pack_start(renderer, true);
+ column.add_attribute(renderer, 'text', this._store.Columns.LABEL);
+ this._treeView.append_column(column);
+
+ scrolled.add(this._treeView);
+
+ let toolbar = new Gtk.Toolbar({ icon_size: Gtk.IconSize.SMALL_TOOLBAR });
+ toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
+
+ let newButton = new Gtk.ToolButton({ icon_name: 'list-add-symbolic' });
+ newButton.connect('clicked', this._newClicked.bind(this));
+ toolbar.add(newButton);
+
+ let delButton = new Gtk.ToolButton({ icon_name: 'list-remove-symbolic' });
+ delButton.connect('clicked', this._delClicked.bind(this));
+ toolbar.add(delButton);
+
+ let selection = this._treeView.get_selection();
+ selection.connect('changed',
+ function() {
+ delButton.sensitive = selection.count_selected_rows() > 0;
+ });
+ delButton.sensitive = selection.count_selected_rows() > 0;
+
+ grid.add(toolbar);
+ }
+
+ _cellEdited(renderer, path, new_text) {
+ let [ok, iter] = this._store.get_iter_from_string(path);
+
+ if (ok)
+ this._store.set(iter, [this._store.Columns.LABEL], [new_text]);
+ }
+
+ _newClicked() {
+ let iter = this._store.append();
+ let index = this._store.get_path(iter).get_indices()[0];
+
+ let label = "dummy.desktop";
+ this._store.set(iter, [this._store.Columns.LABEL], [label]);
+ }
+
+ _delClicked() {
+ let [any, model, iter] = this._treeView.get_selection().get_selected();
+
+ if (any)
+ this._store.remove(iter);
+ }
+});
+
+function init() {
+ ExtensionUtils.initTranslations();
+}
+
+function buildPrefsWidget() {
+ let widget = new PanelFavoritesSettingsWidget();
+ widget.show_all();
+
+ return widget;
+}
diff --git a/extensions/panel-favorites/schemas/org.gnome.shell.extensions.panel-favorites.gschema.xml b/extensions/panel-favorites/schemas/org.gnome.shell.extensions.panel-favorites.gschema.xml
new file mode 100644
index 00000000..ca1228c1
--- /dev/null
+++ b/extensions/panel-favorites/schemas/org.gnome.shell.extensions.panel-favorites.gschema.xml
@@ -0,0 +1,41 @@
+<schemalist gettext-domain="gnome-shell-extensions">
+ <schema id="org.gnome.shell.extensions.panel-favorites" path="/org/gnome/shell/extensions/panel-favorites/">
+ <key name="favorites-enabled" type="b">
+ <default>true</default>
+ <summary>Display Favorites</summary>
+ <description>
+ Whether to show the launchers for Favorite applications.
+ </description>
+ </key>
+ <key name="favorites-position" type="b">
+ <default>false</default>
+ <summary>Where to display Favorites</summary>
+ <description>
+ Whether to show the launchers for Favorite applications on the
+ left or right of the panel.
+ </description>
+ </key>
+ <key name="other-apps-enabled" type="b">
+ <default>false</default>
+ <summary>Display Other Apps</summary>
+ <description>
+ Whether to show the launchers for other applications.
+ </description>
+ </key>
+ <key name="other-apps-position" type="b">
+ <default>true</default>
+ <summary>Where to display Other Apps</summary>
+ <description>
+ Whether to show the launchers for other applications on the
+ left or right of the panel.
+ </description>
+ </key>
+ <key name="other-apps" type="as">
+ <default>[]</default>
+ <summary>Launchers for Other Apps</summary>
+ <description>
+ An array of desktop files for other applications to display.
+ </description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/extensions/panel-favorites/stylesheet.css b/extensions/panel-favorites/stylesheet.css
index 120adacb..8d24a827 100644
--- a/extensions/panel-favorites/stylesheet.css
+++ b/extensions/panel-favorites/stylesheet.css
@@ -2,13 +2,15 @@
spacing: 6px;
}
+.panel-launcher-icon {
+ icon-size: 1.5em;
+}
+
.panel-launcher-label {
border-radius: 7px;
padding: 4px 12px;
- background-color: rgba(0,0,0,0.9);
+ background-color: rgba(24,24,24,0.8);
color: white;
text-align: center;
- font-size: 9pt;
- font-weight: bold;
-y-offset: 6px;
}
--
2.41.0
From 1f9f4af38f991b462ee5f872a697d88a9e115499 Mon Sep 17 00:00:00 2001
From b87a0085342b9828e7e57e8db892b79e345bfbc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 20 Jan 2021 20:18:39 +0100
Subject: [PATCH 1/2] workspace-indicator: Add tooltips to workspace thumbnails
......@@ -11,7 +11,7 @@ those, so expose them as tooltip on hover.
1 file changed, 40 insertions(+)
diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js
index 69eef88c..b10e37ff 100644
index 69eef88c..d377f288 100644
--- a/extensions/workspace-indicator/extension.js
+++ b/extensions/workspace-indicator/extension.js
@@ -8,6 +8,7 @@ const ExtensionUtils = imports.misc.extensionUtils;
......@@ -72,7 +72,7 @@ index 69eef88c..b10e37ff 100644
+
+ Tweener.addTween(this._tooltip, {
+ opacity: this.hover ? 255 : 0,
+ time: TOOLTIP_ANIMATION_TIME * 1000,
+ time: TOOLTIP_ANIMATION_TIME / 1000,
+ transition: 'easeOutQuad',
+ onComplete: () => (this._tooltip.visible = this.hover),
+ });
......@@ -85,10 +85,10 @@ index 69eef88c..b10e37ff 100644
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
--
2.31.1
2.44.0
From 19e19e11214b6b9deae110cd6a4c9232d77c18cb Mon Sep 17 00:00:00 2001
From 36f2762c8c6cda512f164ea22b62d10d03a369b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 20 Jan 2021 20:29:01 +0100
Subject: [PATCH 2/2] window-list: Add tooltips to workspace thumbnails
......@@ -101,7 +101,7 @@ expose them as tooltip on hover.
1 file changed, 40 insertions(+)
diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js
index ca476111..33ec9b0e 100644
index ca476111..8ae9b288 100644
--- a/extensions/window-list/workspaceIndicator.js
+++ b/extensions/window-list/workspaceIndicator.js
@@ -5,10 +5,14 @@ const DND = imports.ui.dnd;
......@@ -159,7 +159,7 @@ index ca476111..33ec9b0e 100644
+
+ Tweener.addTween(this._tooltip, {
+ opacity: this.hover ? 255 : 0,
+ time: TOOLTIP_ANIMATION_TIME * 1000,
+ time: TOOLTIP_ANIMATION_TIME / 1000,
+ transition: 'easeOutQuad',
+ onComplete: () => (this._tooltip.visible = this.hover),
+ });
......@@ -172,5 +172,5 @@ index ca476111..33ec9b0e 100644
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
--
2.31.1
2.44.0
......@@ -6,7 +6,7 @@
Name: gnome-shell-extensions
Version: 3.32.1
Release: 34%{?dist}
Release: 39%{?dist}
Summary: Modify and extend GNOME Shell functionality and behavior
Group: User Interface/Desktops
......@@ -56,6 +56,9 @@ Patch0027: 0001-fileItem-Support-.desktop-files-of-type-Link.patch
Patch0028: 0001-classification-banner-Handle-fullscreen-monitors.patch
Patch0029: 0001-gesture-inhibitor-Allow-inhibiting-workspace-switch-.patch
Patch0030: 0001-desktop-icons-Don-t-use-blocking-IO.patch
Patch0031: 0001-panel-favorites-Update-to-upstream-version.patch
Patch0032: 0001-desktop-icons-Don-t-try-spawn-with-non-existent-work.patch
Patch0033: 0001-classification-banner-Hide-from-picks.patch
%description
GNOME Shell Extensions is a collection of extensions providing additional and
......@@ -520,6 +523,7 @@ cp $RPM_SOURCE_DIR/gnome-classic.desktop $RPM_BUILD_ROOT%{_datadir}/xsessions
%files -n %{pkg_prefix}-panel-favorites
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.panel-favorites.gschema.xml
%{_datadir}/gnome-shell/extensions/panel-favorites*/
......@@ -569,9 +573,25 @@ cp $RPM_SOURCE_DIR/gnome-classic.desktop $RPM_BUILD_ROOT%{_datadir}/xsessions
%changelog
* Wed Aug 16 2023 Florian Müllner <fmuellner@redhat.com> - 3.32.1-34
* Tue Apr 23 2024 Florian Müllner <fmuellner@redhat.com> - 3.32.1-39
- Fix tooltip animation times
Resolves: RHEL-33681
* Wed Feb 07 2024 Florian Müllner <fmuellner@redhat.com> - 3.32.1-38
- Hide classification banners from picks
Resolves: RHEL-24438
* Thu Nov 02 2023 Florian Müllner <fmuellner@redhat.com> - 3.32.1-37
- Fix spawning terminal without a desktop directory
Resolves: RHEL-15031
* Fri Sep 15 2023 Florian Müllner <fmuellner@redhat.com> - 3.32.1-36
- Update panel-favorites to matching upstream release
Resolves: RHEL-3536
* Wed Aug 16 2023 Florian Müllner <fmuellner@redhat.com> - 3.32.1-35
- Rebuild for custom context menu
Resolves: #2232335
Resolves: #2232333
* Tue Jan 17 2023 Florian Müllner <fmuellner@redhat.com> - 3.32.1-33
- Avoid blocking IO in desktop-icons
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment