Compare commits

...

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

49 changed files with 4968 additions and 82280 deletions

185
.gitignore vendored
View File

@ -1 +1,184 @@
SOURCES/gnome-shell-extensions-3.32.1.tar.xz /gnome-shell-extensions-3.1.91.tar.xz
/gnome-shell-extensions-e102c0c6.tar.xz
/gnome-shell-extensions-3.2.0.tar.xz
/gnome-shell-extensions-3.3.2.tar.xz
/gnome-shell-extensions-3.3.5.tar.xz
/gnome-shell-extensions-3.3.90.tar.xz
/gnome-shell-extensions-3.3.92.tar.xz
/gnome-shell-extensions-3.4.0.tar.xz
/gnome-shell-extensions-3.5.2.tar.xz
/gnome-shell-extensions-3.5.4.tar.xz
/gnome-shell-extensions-3.5.5.tar.xz
/gnome-shell-extensions-3.5.90.tar.xz
/gnome-shell-extensions-3.5.91.tar.xz
/gnome-shell-extensions-3.6.0.tar.xz
/gnome-shell-extensions-3.6.1.tar.xz
/gnome-shell-extensions-3.7.1.tar.xz
/gnome-shell-extensions-3.7.3.tar.xz
/gnome-shell-extensions-3.7.4.tar.xz
/gnome-shell-extensions-3.7.5.1.tar.xz
/gnome-shell-extensions-3.7.90.tar.xz
/gnome-shell-extensions-3.7.91.tar.xz
/gnome-shell-extensions-3.7.92.tar.xz
/gnome-shell-extensions-3.8.0.tar.xz
/gnome-shell-extensions-3.8.1.tar.xz
/gnome-shell-extensions-3.9.1.tar.xz
/gnome-shell-extensions-3.9.2.tar.xz
/gnome-shell-extensions-3.9.3.tar.xz
/gnome-shell-extensions-3.9.5.tar.xz
/gnome-shell-extensions-3.9.90.tar.xz
/gnome-shell-extensions-3.9.91.tar.xz
/gnome-shell-extensions-3.9.92.tar.xz
/gnome-shell-extensions-3.10.0.tar.xz
/gnome-shell-extensions-3.10.1.tar.xz
/gnome-shell-extensions-3.11.2.tar.xz
/gnome-shell-extensions-3.11.3.tar.xz
/gnome-shell-extensions-3.11.4.tar.xz
/gnome-shell-extensions-3.11.5.tar.xz
/gnome-shell-extensions-3.11.90.tar.xz
/gnome-shell-extensions-3.11.91.tar.xz
/gnome-shell-extensions-3.11.92.tar.xz
/gnome-shell-extensions-3.12.0.tar.xz
/gnome-shell-extensions-3.13.1.tar.xz
/gnome-shell-extensions-3.13.2.tar.xz
/gnome-shell-extensions-3.13.3.tar.xz
/gnome-shell-extensions-3.13.4.tar.xz
/gnome-shell-extensions-3.13.90.tar.xz
/gnome-shell-extensions-3.13.91.tar.xz
/gnome-shell-extensions-3.13.92.tar.xz
/gnome-shell-extensions-3.14.0.tar.xz
/gnome-shell-extensions-3.14.1.tar.xz
/gnome-shell-extensions-3.15.1.tar.xz
/gnome-shell-extensions-3.15.2.tar.xz
/gnome-shell-extensions-3.15.3.tar.xz
/gnome-shell-extensions-3.15.3.1.tar.xz
/gnome-shell-extensions-3.15.4.tar.xz
/gnome-shell-extensions-3.15.90.tar.xz
/gnome-shell-extensions-3.15.91.tar.xz
/gnome-shell-extensions-3.15.92.tar.xz
/gnome-shell-extensions-3.16.0.tar.xz
/gnome-shell-extensions-3.16.1.tar.xz
/gnome-shell-extensions-3.17.1.tar.xz
/gnome-shell-extensions-3.17.2.tar.xz
/gnome-shell-extensions-3.17.3.tar.xz
/gnome-shell-extensions-3.17.4.tar.xz
/gnome-shell-extensions-3.17.90.tar.xz
/gnome-shell-extensions-3.17.91.tar.xz
/gnome-shell-extensions-3.17.92.tar.xz
/gnome-shell-extensions-3.18.0.tar.xz
/gnome-shell-extensions-3.18.1.tar.xz
/gnome-shell-extensions-3.19.1.tar.xz
/gnome-shell-extensions-3.19.2.tar.xz
/gnome-shell-extensions-3.19.3.tar.xz
/gnome-shell-extensions-3.19.4.tar.xz
/gnome-shell-extensions-3.19.90.tar.xz
/gnome-shell-extensions-3.19.91.tar.xz
/gnome-shell-extensions-3.19.92.tar.xz
/gnome-shell-extensions-3.20.0.tar.xz
/gnome-shell-extensions-3.20.1.tar.xz
/gnome-shell-extensions-3.21.2.tar.xz
/gnome-shell-extensions-3.21.3.tar.xz
/gnome-shell-extensions-3.21.4.tar.xz
/gnome-shell-extensions-3.21.90.tar.xz
/gnome-shell-extensions-3.21.91.tar.xz
/gnome-shell-extensions-3.21.92.tar.xz
/gnome-shell-extensions-3.22.0.tar.xz
/gnome-shell-extensions-3.22.1.tar.xz
/gnome-shell-extensions-3.23.2.tar.xz
/gnome-shell-extensions-3.23.90.tar.xz
/gnome-shell-extensions-3.23.91.tar.xz
/gnome-shell-extensions-3.23.92.tar.xz
/gnome-shell-extensions-3.24.0.tar.xz
/gnome-shell-extensions-3.24.1.tar.xz
/gnome-shell-extensions-3.25.1.tar.xz
/gnome-shell-extensions-3.25.2.tar.xz
/gnome-shell-extensions-3.25.3.tar.xz
/gnome-shell-extensions-3.25.4.tar.xz
/gnome-shell-extensions-3.25.90.tar.xz
/gnome-shell-extensions-3.25.91.tar.xz
/gnome-shell-extensions-3.26.0.tar.xz
/gnome-shell-extensions-3.26.1.tar.xz
/gnome-shell-extensions-3.27.1.tar.xz
/gnome-shell-extensions-3.27.91.tar.xz
/gnome-shell-extensions-3.27.92.tar.xz
/gnome-shell-extensions-3.28.0.tar.xz
/gnome-shell-extensions-3.28.1.tar.xz
/gnome-shell-extensions-3.29.2.tar.xz
/gnome-shell-extensions-3.29.90.tar.xz
/gnome-shell-extensions-3.29.91.tar.xz
/gnome-shell-extensions-3.30.0.tar.xz
/gnome-shell-extensions-3.30.1.tar.xz
/gnome-shell-extensions-3.31.2.tar.xz
/gnome-shell-extensions-3.31.90.tar.xz
/gnome-shell-extensions-3.31.91.tar.xz
/gnome-shell-extensions-3.31.92.tar.xz
/gnome-shell-extensions-3.32.0.tar.xz
/gnome-shell-extensions-3.32.1.tar.xz
/gnome-shell-extensions-3.33.1.tar.xz
/gnome-shell-extensions-3.33.2.tar.xz
/gnome-shell-extensions-3.33.3.tar.xz
/gnome-shell-extensions-3.33.4.tar.xz
/gnome-shell-extensions-3.33.90.tar.xz
/gnome-shell-extensions-3.33.91.tar.xz
/gnome-shell-extensions-3.33.92.tar.xz
/gnome-shell-extensions-3.34.0.tar.xz
/gnome-shell-extensions-3.34.1.tar.xz
/gnome-shell-extensions-3.35.2.tar.xz
/gnome-shell-extensions-3.35.3.tar.xz
/gnome-shell-extensions-3.35.90.tar.xz
/gnome-shell-extensions-3.35.91.tar.xz
/gnome-shell-extensions-3.35.92.tar.xz
/gnome-shell-extensions-3.36.0.tar.xz
/gnome-shell-extensions-3.36.1.tar.xz
/gnome-shell-extensions-3.37.1.tar.xz
/gnome-shell-extensions-3.37.2.tar.xz
/gnome-shell-extensions-3.37.3.tar.xz
/gnome-shell-extensions-3.37.90.tar.xz
/gnome-shell-extensions-3.37.91.tar.xz
/gnome-shell-extensions-3.37.92.tar.xz
/gnome-shell-extensions-3.38.0.tar.xz
/gnome-shell-extensions-3.38.1.tar.xz
/gnome-shell-extensions-40.alpha.tar.xz
/gnome-shell-extensions-40.alpha.1.tar.xz
/gnome-shell-extensions-40.alpha.1-11-g9fa522c.tar.xz
/gnome-shell-extensions-40.beta.tar.xz
/gnome-shell-extensions-40.rc.tar.xz
/gnome-shell-extensions-40.0.tar.xz
/gnome-shell-extensions-40.1.tar.xz
/gnome-shell-extensions-40.2.tar.xz
/gnome-shell-extensions-40.3.tar.xz
/gnome-shell-extensions-41.beta.tar.xz
/gnome-shell-extensions-41.rc.tar.xz
/gnome-shell-extensions-41.rc.1.tar.xz
/gnome-shell-extensions-41.0.tar.xz
/gnome-shell-extensions-42.alpha.tar.xz
/gnome-shell-extensions-42.beta.tar.xz
/gnome-shell-extensions-42.rc.tar.xz
/gnome-shell-extensions-42.0.tar.xz
/gnome-shell-extensions-42.1.tar.xz
/gnome-shell-extensions-42.2.tar.xz
/gnome-shell-extensions-43.alpha.tar.xz
/gnome-shell-extensions-43.beta.tar.xz
/gnome-shell-extensions-43.rc.tar.xz
/gnome-shell-extensions-43.0.tar.xz
/gnome-shell-extensions-43.1.tar.xz
/gnome-shell-extensions-44.beta.tar.xz
/gnome-shell-extensions-44.rc.tar.xz
/gnome-shell-extensions-44.0.tar.xz
/gnome-shell-extensions-45.alpha.tar.xz
/gnome-shell-extensions-45.beta.tar.xz
/gnome-shell-extensions-45.rc.tar.xz
/gnome-shell-extensions-45.0.tar.xz
/gnome-shell-extensions-45.1.tar.xz
/gnome-shell-extensions-45.2.tar.xz
/gnome-shell-extensions-46.alpha.tar.xz
/gnome-shell-extensions-46.beta.tar.xz
/gnome-shell-extensions-46.rc.tar.xz
/gnome-shell-extensions-46.0.tar.xz
/gnome-shell-extensions-46.1.tar.xz
/gnome-shell-extensions-46.2.tar.xz
/gnome-shell-extensions-47.alpha.tar.xz
/gnome-shell-extensions-47.rc.tar.xz
/gnome-shell-extensions-47.0.tar.xz
/gnome-shell-extensions-47.1.tar.xz
/gnome-shell-extensions-47.2.tar.xz

View File

@ -1 +0,0 @@
51c1c16bcd0dc9125834b32d7c539c38fa9c4f52 SOURCES/gnome-shell-extensions-3.32.1.tar.xz

View File

@ -0,0 +1,32 @@
From b373d600104d6a5c4984521d934c5d02af3a2b99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 23 Feb 2018 16:56:46 +0100
Subject: [PATCH] Include status-icons in classic session
---
meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index d092830f..14143501 100644
--- a/meson.build
+++ b/meson.build
@@ -35,6 +35,7 @@ classic_extensions = [
'apps-menu',
'places-menu',
'launch-new-instance',
+ 'status-icons',
'window-list',
]
@@ -45,7 +46,6 @@ default_extensions += [
'heads-up-display',
'light-style',
'screenshot-window-sizer',
- 'status-icons',
'system-monitor',
'windowsNavigator',
'workspace-indicator',
--
2.47.1

View File

@ -1,186 +0,0 @@
From 2a498fef3ec02d834346b545aeacba0a6224494e Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 28 Jan 2021 00:06:12 +0100
Subject: [PATCH] Add gesture-inhibitor extension
This extension may disable default GNOME Shell gestures.
---
extensions/gesture-inhibitor/extension.js | 75 +++++++++++++++++++
extensions/gesture-inhibitor/meson.build | 8 ++
extensions/gesture-inhibitor/metadata.json.in | 12 +++
...l.extensions.gesture-inhibitor.gschema.xml | 25 +++++++
extensions/gesture-inhibitor/stylesheet.css | 1 +
meson.build | 1 +
6 files changed, 122 insertions(+)
create mode 100644 extensions/gesture-inhibitor/extension.js
create mode 100644 extensions/gesture-inhibitor/meson.build
create mode 100644 extensions/gesture-inhibitor/metadata.json.in
create mode 100644 extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
create mode 100644 extensions/gesture-inhibitor/stylesheet.css
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
new file mode 100644
index 00000000..e74ede2f
--- /dev/null
+++ b/extensions/gesture-inhibitor/extension.js
@@ -0,0 +1,75 @@
+/* extension.js
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/* exported init */
+
+const Clutter = imports.gi.Clutter;
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = ExtensionUtils.getCurrentExtension();
+const ViewSelector = imports.ui.viewSelector;
+const EdgeDragAction = imports.ui.edgeDragAction;
+const WindowManager = imports.ui.windowManager;
+const St = imports.gi.St;
+const Gio = imports.gi.Gio;
+
+class Extension {
+ constructor() {
+ this._settings = ExtensionUtils.getSettings();
+ let actions = global.stage.get_actions();
+
+ actions.forEach(a => {
+ if (a instanceof ViewSelector.ShowOverviewAction)
+ this._showOverview = a;
+ else if (a instanceof WindowManager.AppSwitchAction)
+ this._appSwitch = a;
+ else if (a instanceof EdgeDragAction.EdgeDragAction &&
+ a._side == St.Side.BOTTOM)
+ this._showOsk = a;
+ else if (a instanceof EdgeDragAction.EdgeDragAction &&
+ a._side == St.Side.TOP)
+ this._unfullscreen = a;
+ else if (a instanceof EdgeDragAction.EdgeDragAction)
+ this._showAppGrid = a;
+ });
+
+ this._map = [
+ { setting: 'overview', action: this._showOverview },
+ { setting: 'app-switch', action: this._appSwitch },
+ { setting: 'show-osk', action: this._showOsk },
+ { setting: 'unfullscreen', action: this._unfullscreen },
+ { setting: 'show-app-grid', action: this._showAppGrid }
+ ];
+ }
+
+ enable() {
+ this._map.forEach(m => {
+ this._settings.bind(m.setting, m.action, 'enabled',
+ Gio.SettingsBindFlags.DEFAULT);
+ });
+ }
+
+ disable() {
+ this._map.forEach(m => {
+ m.action.enabled = true;
+ });
+ }
+}
+
+function init() {
+ return new Extension();
+}
diff --git a/extensions/gesture-inhibitor/meson.build b/extensions/gesture-inhibitor/meson.build
new file mode 100644
index 00000000..fdad5cc8
--- /dev/null
+++ b/extensions/gesture-inhibitor/meson.build
@@ -0,0 +1,8 @@
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
+
+# extension_sources += files('prefs.js')
+extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/gesture-inhibitor/metadata.json.in b/extensions/gesture-inhibitor/metadata.json.in
new file mode 100644
index 00000000..37d6a117
--- /dev/null
+++ b/extensions/gesture-inhibitor/metadata.json.in
@@ -0,0 +1,12 @@
+{
+ "uuid": "@uuid@",
+ "extension-id": "@extension_id@",
+ "settings-schema": "@gschemaname@",
+ "gettext-domain": "@gettext_domain@",
+ "name": "Gesture Inhibitor",
+ "description": "Makes touchscreen gestures optional.",
+ "shell-version": [ "@shell_current@" ],
+ "original-authors": [ "cgarnach@redhat.com" ],
+ "url": "@url@"
+}
+
diff --git a/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml b/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
new file mode 100644
index 00000000..1d67dcc0
--- /dev/null
+++ b/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
@@ -0,0 +1,25 @@
+<schemalist>
+ <schema id="org.gnome.shell.extensions.gesture-inhibitor" path="/org/gnome/shell/extensions/gesture-inhibitor/">
+ <key name="show-app-grid" type="b">
+ <default>true</default>
+ <summary>Show app grid gesture</summary>
+ </key>
+ <key name="show-osk" type="b">
+ <default>true</default>
+ <summary>Show OSK gesture</summary>
+ </key>
+ <key name="overview" type="b">
+ <default>true</default>
+ <summary>Show Overview gesture</summary>
+ </key>
+ <key name="app-switch" type="b">
+ <default>true</default>
+ <summary>Application switch gesture</summary>
+ </key>
+ <key name="unfullscreen" type="b">
+ <default>true</default>
+ <summary>Unfullscreen gesture</summary>
+ </key>
+ </schema>
+</schemalist>
+
diff --git a/extensions/gesture-inhibitor/stylesheet.css b/extensions/gesture-inhibitor/stylesheet.css
new file mode 100644
index 00000000..37b93f21
--- /dev/null
+++ b/extensions/gesture-inhibitor/stylesheet.css
@@ -0,0 +1 @@
+/* Add your custom extension styling here */
diff --git a/meson.build b/meson.build
index e163b84d..ba84f8f3 100644
--- a/meson.build
+++ b/meson.build
@@ -55,6 +55,7 @@ all_extensions += [
'dash-to-dock',
'dash-to-panel',
'disable-screenshield',
+ 'gesture-inhibitor',
'native-window-placement',
'no-hot-corner',
'panel-favorites',
--
2.32.0

View File

@ -1,32 +0,0 @@
From a3db60786407481efbfc4875f887d03b58f0a7b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 23 Feb 2018 16:56:46 +0100
Subject: [PATCH] Include top-icons in classic session
---
meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index 6764f9a..32743ed 100644
--- a/meson.build
+++ b/meson.build
@@ -36,6 +36,7 @@ classic_extensions = [
'desktop-icons',
'places-menu',
'launch-new-instance',
+ 'top-icons',
'window-list'
]
@@ -56,7 +57,6 @@ all_extensions += [
'no-hot-corner',
'panel-favorites',
'systemMonitor',
- 'top-icons',
'updates-dialog',
'user-theme',
'window-grouper'
--
2.21.0

View File

@ -1,83 +0,0 @@
From f5e47cd8ca32ae433f6906b01a509c5a304894d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Sat, 24 Oct 2020 01:14:44 +0200
Subject: [PATCH] Update desktop-icons gettext domain
---
extensions/desktop-icons/createFolderDialog.js | 2 +-
extensions/desktop-icons/desktopGrid.js | 2 +-
extensions/desktop-icons/fileItem.js | 2 +-
extensions/desktop-icons/prefs.js | 8 +++++---
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/extensions/desktop-icons/createFolderDialog.js b/extensions/desktop-icons/createFolderDialog.js
index f3e40e9..5038762 100644
--- a/extensions/desktop-icons/createFolderDialog.js
+++ b/extensions/desktop-icons/createFolderDialog.js
@@ -21,7 +21,7 @@ const { Clutter, GObject, GLib, Gio, St } = imports.gi;
const Signals = imports.signals;
const Dialog = imports.ui.dialog;
-const Gettext = imports.gettext.domain('desktop-icons');
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js
index a2d1f12..94d2dfd 100644
--- a/extensions/desktop-icons/desktopGrid.js
+++ b/extensions/desktop-icons/desktopGrid.js
@@ -44,7 +44,7 @@ const Util = imports.misc.util;
const Clipboard = St.Clipboard.get_default();
const CLIPBOARD_TYPE = St.ClipboardType.CLIPBOARD;
-const Gettext = imports.gettext.domain('desktop-icons');
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 0c6a54d..d6d43c9 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -42,7 +42,7 @@ const Prefs = Me.imports.prefs;
const DBusUtils = Me.imports.dbusUtils;
const DesktopIconsUtil = Me.imports.desktopIconsUtil;
-const Gettext = imports.gettext.domain('desktop-icons');
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
diff --git a/extensions/desktop-icons/prefs.js b/extensions/desktop-icons/prefs.js
index 4b8d986..51daf15 100644
--- a/extensions/desktop-icons/prefs.js
+++ b/extensions/desktop-icons/prefs.js
@@ -26,7 +26,7 @@ const Gettext = imports.gettext;
const Config = imports.misc.config;
-var _ = Gettext.domain('desktop-icons').gettext;
+var _ = Gettext.domain('gnome-shell-extensions').gettext;
const SCHEMA_NAUTILUS = 'org.gnome.nautilus.preferences';
const SCHEMA_GTK = 'org.gtk.Settings.FileChooser';
@@ -51,11 +51,13 @@ var CLICK_POLICY_SINGLE = false;
function initTranslations() {
let extension = ExtensionUtils.getCurrentExtension();
+ let domain = extension.metadata['gettext-domain'] || 'desktop-icons';
+
let localedir = extension.dir.get_child('locale');
if (localedir.query_exists(null))
- Gettext.bindtextdomain('desktop-icons', localedir.get_path());
+ Gettext.bindtextdomain(domain, localedir.get_path());
else
- Gettext.bindtextdomain('desktop-icons', Config.LOCALEDIR);
+ Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
function init() {
--
2.21.1

View File

@ -1,98 +0,0 @@
From e768ad73e2d68b3f1567051675ba0539a75e3105 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Sat, 18 May 2019 19:37:05 +0200
Subject: [PATCH] Update style
---
data/gnome-shell-sass | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule data/gnome-shell-sass 1a56956..8842e57:
diff --git a/data/gnome-shell-sass/_common.scss b/data/gnome-shell-sass/_common.scss
index a6357ba..62d9c82 100644
--- a/data/gnome-shell-sass/_common.scss
+++ b/data/gnome-shell-sass/_common.scss
@@ -571,6 +571,18 @@ StScrollBar {
app menu inside the main app window itself rather than the top bar
*/
+/*************
+ * App Icons *
+ *************/
+/* Outline for low res icons */
+.lowres-icon {
+ icon-shadow: 0 1px 2px rgba(0,0,0,0.3);
+}
+
+/* Drapshadow for large icons */
+.icon-dropshadow {
+ icon-shadow: 0 1px 2px rgba(0,0,0,0.4);
+}
/* OSD */
.osd-window {
@@ -680,7 +692,8 @@ StScrollBar {
spacing: 8px;
}
- .ws-switcher-active-up, .ws-switcher-active-down {
+ .ws-switcher-active-up, .ws-switcher-active-down,
+ .ws-switcher-active-left, .ws-switcher-active-right {
height: 50px;
background-color: $selected_bg_color;
color: $selected_fg_color;
@@ -781,6 +794,11 @@ StScrollBar {
color: lighten($fg_color,10%);
}
+ .panel-logo-icon {
+ padding-right: .4em;
+ icon-size: 1em;
+ }
+
.system-status-icon { icon-size: 1.09em; padding: 0 5px; }
.unlock-screen &,
.login-screen &,
@@ -1406,6 +1424,14 @@ StScrollBar {
}
+ .app-well-hover-text {
+ text-align: center;
+ color: $osd_fg_color;
+ background-color: $osd_bg_color;
+ border-radius: 5px;
+ padding: 3px;
+ }
+
.app-well-app-running-dot { //running apps indicator
width: 10px; height: 3px;
background-color: $selected_bg_color;
@@ -1801,7 +1827,12 @@ StScrollBar {
.login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { spacing: 5px; }
.login-dialog-message-warning { color: $warning_color; }
- .login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
+ .login-dialog-message-hint, .login-dialog-message {
+ color: darken($osd_fg_color, 20%);
+ padding-top: 0;
+ padding-bottom: 20px;
+ min-height: 2.75em;
+ }
.login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label {
padding-left: 2px;
@@ -1856,6 +1887,10 @@ StScrollBar {
padding-bottom: 12px;
spacing: 8px;
width: 23em;
+ .login-dialog-timed-login-indicator {
+ height: 2px;
+ background-color: darken($fg_color,40%);
+ }
}
.login-dialog-prompt-label {
--
2.21.0

View File

@ -1,33 +0,0 @@
From 0bbeadadc41128b2be1f2b56c60b5a7a671d40da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 27 Jun 2019 03:57:53 +0200
Subject: [PATCH] apps-menu: Add missing chain-up
PanelMenu.Button is a bit weird in that it also "contains" its parent
actor. That container is supposed to be destroyed with the button, but
as we currently don't chain up to the parent class' _onDestroy(), we
leave behind an empty container every time the extension is disabled.
Fix this by adding the missing chain-up.
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/75
---
extensions/apps-menu/extension.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
index b9e7111..9803cc1 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -433,6 +433,8 @@ class ApplicationsButton extends PanelMenu.Button {
}
_onDestroy() {
+ super._onDestroy();
+
Main.overview.disconnect(this._showingId);
Main.overview.disconnect(this._hidingId);
appSys.disconnect(this._installedChangedId);
--
2.21.0

View File

@ -1,40 +0,0 @@
From 52ee25effa3debb21307e33ac223cf48ac7bc57a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 17 Mar 2016 17:15:38 +0100
Subject: [PATCH] apps-menu: Explicitly set label_actor
For some reason orca fails to pick up the label of category items,
so set the label_actor explicitly as workaround.
---
extensions/apps-menu/extension.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
index d62e3d7..cc399c6 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -29,7 +29,9 @@ class ActivitiesMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(button) {
super();
this._button = button;
- this.actor.add_child(new St.Label({ text: _('Activities Overview') }));
+ let label = new St.Label({ text: _('Activities Overview') });
+ this.actor.add_child(label);
+ this.actor.label_actor = label;
}
activate(event) {
@@ -120,7 +122,9 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
else
name = _('Favorites');
- this.actor.add_child(new St.Label({ text: name }));
+ let label = new St.Label({ text: name });
+ this.actor.add_child(label);
+ this.actor.label_actor = label;
this.actor.connect('motion-event', this._onMotionEvent.bind(this));
}
--
2.21.0

View File

@ -1,32 +0,0 @@
From 3e3634b59455da0cbae1de4af0ce5cf97be8b80d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 21 Jan 2014 16:48:17 -0500
Subject: [PATCH] apps-menu: add logo icon to Applications menu
Brand requested it.
---
extensions/apps-menu/extension.js | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
index d7ba570..d62e3d7 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -390,6 +390,14 @@ class ApplicationsButton extends PanelMenu.Button {
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
+ let iconFile = Gio.File.new_for_path(
+ '/usr/share/icons/hicolor/scalable/apps/start-here.svg');
+ this._icon = new St.Icon({
+ gicon: new Gio.FileIcon({ file: iconFile }),
+ style_class: 'panel-logo-icon'
+ });
+ hbox.add_actor(this._icon);
+
this._label = new St.Label({
text: _('Applications'),
y_expand: true,
--
2.21.0

View File

@ -1,33 +0,0 @@
From 8a5e793b3d984f3acc378cf8914410311e9dde0e Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Thu, 28 Jan 2021 16:33:50 +0800
Subject: [PATCH] auto-move-windows: Don't move windows already on all
workspaces
This fixes a particular case of mutter#992.
Although gnome-shell will also be softened to not crash in future, it's
also a good idea for the extension to explicitly decide how it wants to
handle windows that are already on all workspaces.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/157>
---
extensions/auto-move-windows/extension.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js
index b9bc3a0..3859809 100644
--- a/extensions/auto-move-windows/extension.js
+++ b/extensions/auto-move-windows/extension.js
@@ -72,7 +72,7 @@ class WindowMover {
}
_moveWindow(window, workspaceNum) {
- if (window.skip_taskbar)
+ if (window.skip_taskbar || window.is_on_all_workspaces())
return;
// ensure we have the required number of workspaces
--
2.37.1

View File

@ -1,68 +0,0 @@
From 3d32ab1848011a3a7af97255307b3541a7553b09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 14 Dec 2022 16:55:51 +0100
Subject: [PATCH] classification-banner: Handle fullscreen monitors
When a monitor is in fullscreen, we don't want its classification
banner to be offset by an imaginary panel, but at the top of the
screen.
---
extensions/classification-banner/extension.js | 22 +++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/extensions/classification-banner/extension.js b/extensions/classification-banner/extension.js
index 6c2fe007..1cf03b3f 100644
--- a/extensions/classification-banner/extension.js
+++ b/extensions/classification-banner/extension.js
@@ -27,16 +27,19 @@ const Main = imports.ui.main;
const ClassificationBanner = GObject.registerClass(
class ClassificationBanner extends Clutter.Actor {
_init(index) {
+ const constraint = new Layout.MonitorConstraint({index});
super._init({
layout_manager: new Clutter.BinLayout(),
- constraints: new Layout.MonitorConstraint({
- work_area: true,
- index,
- }),
+ constraints: constraint,
});
+ this._monitorConstraint = constraint;
this._settings = ExtensionUtils.getSettings();
this.connect('destroy', () => {
+ if (this._fullscreenChangedId)
+ global.display.disconnect(this._fullscreenChangedId);
+ delete this._fullscreenChangedId;
+
if (this._settings)
this._settings.run_dispose();
this._settings = null;
@@ -95,6 +98,11 @@ class ClassificationBanner extends Clutter.Actor {
userLabel, 'visible',
Gio.SettingsBindFlags.GET);
+ this._fullscreenChangedId =
+ global.display.connect('in-fullscreen-changed',
+ () => this._updateMonitorConstraint());
+ this._updateMonitorConstraint();
+
this._settings.connect('changed::color',
() => this._updateStyles());
this._settings.connect('changed::background-color',
@@ -111,6 +119,12 @@ class ClassificationBanner extends Clutter.Actor {
return `${key}: rgba(${red},${green},${blue},${alpha / 255});`;
}
+ _updateMonitorConstraint() {
+ const {index} = this._monitorConstraint;
+ this._monitorConstraint.work_area =
+ !global.display.get_monitor_in_fullscreen(index);
+ }
+
_updateStyles() {
const bgStyle = this._getColorSetting('background-color');
const fgStyle = this._getColorSetting('color');
--
2.38.1

View File

@ -1,39 +0,0 @@
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

View File

@ -1,208 +0,0 @@
From 3c62051c0a154ae987bb0126e8adb6cd86aa69a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 24 Feb 2020 16:17:05 +0100
Subject: [PATCH] dashToDock: Handle no-overview case
There is no longer an overview in GNOME Classic, so in order to be
used in that environment, the extension must deal with that case.
---
extensions/dash-to-dock/docking.js | 122 ++++++++++++++++-------------
1 file changed, 68 insertions(+), 54 deletions(-)
diff --git a/extensions/dash-to-dock/docking.js b/extensions/dash-to-dock/docking.js
index d35094b..2b8353a 100644
--- a/extensions/dash-to-dock/docking.js
+++ b/extensions/dash-to-dock/docking.js
@@ -233,7 +233,7 @@ var DockedDash = class DashToDock {
// Create a new dash object
this.dash = new MyDash.MyDash(this._settings, this._remoteModel, this._monitorIndex);
- if (!this._settings.get_boolean('show-show-apps-button'))
+ if (Main.overview.isDummy || !this._settings.get_boolean('show-show-apps-button'))
this.dash.hideShowAppsButton();
// Create the main actor and the containers for sliding in and out and
@@ -272,45 +272,11 @@ var DockedDash = class DashToDock {
this.dash.actor.add_constraint(this.constrainSize);
this._signalsHandler.add([
- Main.overview,
- 'item-drag-begin',
- this._onDragStart.bind(this)
- ], [
- Main.overview,
- 'item-drag-end',
- this._onDragEnd.bind(this)
- ], [
- Main.overview,
- 'item-drag-cancelled',
- this._onDragEnd.bind(this)
- ], [
// update when workarea changes, for instance if other extensions modify the struts
//(like moving th panel at the bottom)
global.display,
'workareas-changed',
this._resetPosition.bind(this)
- ], [
- Main.overview,
- 'showing',
- this._onOverviewShowing.bind(this)
- ], [
- Main.overview,
- 'hiding',
- this._onOverviewHiding.bind(this)
- ], [
- // Hide on appview
- Main.overview.viewSelector,
- 'page-changed',
- this._pageChanged.bind(this)
- ], [
- Main.overview.viewSelector,
- 'page-empty',
- this._onPageEmpty.bind(this)
- ], [
- // Ensure the ShowAppsButton status is kept in sync
- Main.overview.viewSelector._showAppsButton,
- 'notify::checked',
- this._syncShowAppsButtonToggled.bind(this)
], [
global.display,
'in-fullscreen-changed',
@@ -325,15 +291,6 @@ var DockedDash = class DashToDock {
this.dash,
'icon-size-changed',
() => { Main.overview.dashIconSize = this.dash.iconSize; }
- ], [
- // This duplicate the similar signal which is in owerview.js.
- // Being connected and thus executed later this effectively
- // overwrite any attempt to use the size of the default dash
- //which given the customization is usually much smaller.
- // I can't easily disconnect the original signal
- Main.overview._controls.dash,
- 'icon-size-changed',
- () => { Main.overview.dashIconSize = this.dash.iconSize; }
], [
// sync hover after a popupmenu is closed
this.dash,
@@ -341,6 +298,53 @@ var DockedDash = class DashToDock {
() => { this._box.sync_hover() }
]);
+ if (!Main.overview.isDummy) {
+ this._signalsHandler.add([
+ Main.overview,
+ 'item-drag-begin',
+ this._onDragStart.bind(this)
+ ], [
+ Main.overview,
+ 'item-drag-end',
+ this._onDragEnd.bind(this)
+ ], [
+ Main.overview,
+ 'item-drag-cancelled',
+ this._onDragEnd.bind(this)
+ ], [
+ Main.overview,
+ 'showing',
+ this._onOverviewShowing.bind(this)
+ ], [
+ Main.overview,
+ 'hiding',
+ this._onOverviewHiding.bind(this)
+ ], [
+ // Hide on appview
+ Main.overview.viewSelector,
+ 'page-changed',
+ this._pageChanged.bind(this)
+ ], [
+ Main.overview.viewSelector,
+ 'page-empty',
+ this._onPageEmpty.bind(this)
+ ], [
+ // Ensure the ShowAppsButton status is kept in sync
+ Main.overview.viewSelector._showAppsButton,
+ 'notify::checked',
+ this._syncShowAppsButtonToggled.bind(this)
+ ], [
+ // This duplicate the similar signal which is in owerview.js.
+ // Being connected and thus executed later this effectively
+ // overwrite any attempt to use the size of the default dash
+ //which given the customization is usually much smaller.
+ // I can't easily disconnect the original signal
+ Main.overview._controls.dash,
+ 'icon-size-changed',
+ () => { Main.overview.dashIconSize = this.dash.iconSize; }
+ ]);
+ }
+
this._injectionsHandler = new Utils.InjectionsHandler();
this._themeManager = new Theming.ThemeManager(this._settings, this);
@@ -370,14 +374,17 @@ var DockedDash = class DashToDock {
this._dashSpacer = new OverviewControls.DashSpacer();
this._dashSpacer.setDashActor(this._box);
- if (this._position == St.Side.LEFT)
- Main.overview._controls._group.insert_child_at_index(this._dashSpacer, this._rtl ? -1 : 0); // insert on first
- else if (this._position == St.Side.RIGHT)
- Main.overview._controls._group.insert_child_at_index(this._dashSpacer, this._rtl ? 0 : -1); // insert on last
- else if (this._position == St.Side.TOP)
- Main.overview._overview.insert_child_at_index(this._dashSpacer, 0);
- else if (this._position == St.Side.BOTTOM)
- Main.overview._overview.insert_child_at_index(this._dashSpacer, -1);
+ if (!Main.overview.isDummy) {
+ const { _controls, _overview } = Main.overview;
+ if (this._position == St.Side.LEFT)
+ _controls._group.insert_child_at_index(this._dashSpacer, this._rtl ? -1 : 0); // insert on first
+ else if (this._position == St.Side.RIGHT)
+ _controls._group.insert_child_at_index(this._dashSpacer, this._rtl ? 0 : -1); // insert on last
+ else if (this._position == St.Side.TOP)
+ _overview.insert_child_at_index(this._dashSpacer, 0);
+ else if (this._position == St.Side.BOTTOM)
+ _overview.insert_child_at_index(this._dashSpacer, -1);
+ }
// Add dash container actor and the container to the Chrome.
this.actor.set_child(this._slider);
@@ -412,7 +419,7 @@ var DockedDash = class DashToDock {
// Since Gnome 3.8 dragging an app without having opened the overview before cause the attemp to
//animate a null target since some variables are not initialized when the viewSelector is created
- if (Main.overview.viewSelector._activePage == null)
+ if (!Main.overview.isDummy && Main.overview.viewSelector._activePage == null)
Main.overview.viewSelector._activePage = Main.overview.viewSelector._workspacesPage;
this._updateVisibilityMode();
@@ -493,7 +500,8 @@ var DockedDash = class DashToDock {
this._settings,
'changed::show-show-apps-button',
() => {
- if (this._settings.get_boolean('show-show-apps-button'))
+ if (!Main.overview.isDummy &&
+ this._settings.get_boolean('show-show-apps-button'))
this.dash.showShowAppsButton();
else
this.dash.hideShowAppsButton();
@@ -1681,6 +1689,9 @@ var DockManager = class DashToDock_DockManager {
// set stored icon size to the new dash
Main.overview.dashIconSize = this._allDocks[0].dash.iconSize;
+ if (Main.overview.isDummy)
+ return;
+
// Hide usual Dash
Main.overview._controls.dash.actor.hide();
@@ -1707,6 +1718,9 @@ var DockManager = class DashToDock_DockManager {
}
_restoreDash() {
+ if (Main.overview.isDummy)
+ return;
+
Main.overview._controls.dash.actor.show();
Main.overview._controls.dash.actor.set_width(-1); //reset default dash size
// This force the recalculation of the icon size
--
2.25.0

View File

@ -1,33 +0,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

View File

@ -1,76 +0,0 @@
From 93e3e938b322433aff862bbc46f80c60ab7dc2ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 17 Jan 2023 20:31:21 +0100
Subject: [PATCH] desktop-icons: Don't use blocking IO
---
extensions/desktop-icons/desktopManager.js | 35 +++++++++++++++++-----
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index 399aee03..2ce6eefb 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -53,6 +53,21 @@ function findMonitorIndexForPos(x, y) {
return getDpy().get_monitor_index_for_rect(new Meta.Rectangle({x, y}));
}
+async function queryInfo(file, attributes = DesktopIconsUtil.DEFAULT_ATTRIBUTES, cancellable = null) {
+ const flags = Gio.FileQueryInfoFlags.NONE;
+ const priority = GLib.PRIORITY_DEFAULT;
+ return new Promise((resolve, reject) => {
+ file.query_info_async(attributes, flags, priority, cancellable, (o, res) => {
+ try {
+ const info = file.query_info_finish(res);
+ resolve(info);
+ } catch (e) {
+ reject(e);
+ }
+ });
+ });
+}
+
var DesktopManager = GObject.registerClass({
Properties: {
@@ -221,9 +236,7 @@ var DesktopManager = GObject.registerClass({
if (!this._unixMode) {
let desktopDir = DesktopIconsUtil.getDesktopDir();
- let fileInfo = desktopDir.query_info(Gio.FILE_ATTRIBUTE_UNIX_MODE,
- Gio.FileQueryInfoFlags.NONE,
- null);
+ let fileInfo = await queryInfo(desktopDir, Gio.FILE_ATTRIBUTE_UNIX_MODE);
this._unixMode = fileInfo.get_attribute_uint32(Gio.FILE_ATTRIBUTE_UNIX_MODE);
this._setWritableByOthers((this._unixMode & S_IWOTH) != 0);
}
@@ -268,14 +281,22 @@ var DesktopManager = GObject.registerClass({
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT,
this._desktopEnumerateCancellable,
- (source, result) => {
+ async (source, result) => {
try {
let fileEnum = source.enumerate_children_finish(result);
+ let extraFolders = await Promise.all(DesktopIconsUtil.getExtraFolders()
+ .map(async ([folder, extras]) => {
+ const info = await queryInfo(folder,
+ DesktopIconsUtil.DEFAULT_ATTRIBUTES,
+ this._desktopEnumerateCancellable);
+ return [folder, info, extras];
+ }));
+
let resultGenerator = function *() {
+ for (let [newFolder, info, extras] of extraFolders)
+ yield [newFolder, info, extras];
+
let info;
- for (let [newFolder, extras] of DesktopIconsUtil.getExtraFolders()) {
- yield [newFolder, newFolder.query_info(DesktopIconsUtil.DEFAULT_ATTRIBUTES, Gio.FileQueryInfoFlags.NONE, this._desktopEnumerateCancellable), extras];
- }
while ((info = fileEnum.next_file(null)))
yield [fileEnum.get_child(info), info, Prefs.FileType.NONE];
}.bind(this);
--
2.38.1

View File

@ -1,179 +0,0 @@
From b334c8c248f849be996963cdafb1b0b69476bdf1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@redhat.com>
Date: Tue, 2 Nov 2021 09:20:11 +0100
Subject: [PATCH] desktop-icons: Fix stuck grab issue with rubber banding
The desktop icons extension can get into a state where the desktop no longer
takes mouse input.
This happens if a user starts a rubber banding operation and then drags
the mouse to somewhere on screen that has a pop up menu, and then pops
the menu up.
This commit addresses the bug by limiting the grab actor to the
backgrounds, and by explicitly ending the rubber banding operation
when one of the icons own menus is shown.
One side effect of limiting the grab actor to the backgrounds, is the
rubber banding code never gets to see motion outside of the backgrounds
anymore. In order to keep drag operations feeling fluid when the user moves
toward the edge of the screen, this commit also overrides the
grab helpers captured-event handler so those motion events keep coming.
We also start to end the rubber band if for any reason the grab it had
was released.
---
extensions/desktop-icons/desktopGrid.js | 1 +
extensions/desktop-icons/desktopManager.js | 75 ++++++++++++++--------
extensions/desktop-icons/fileItem.js | 1 +
3 files changed, 49 insertions(+), 28 deletions(-)
diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js
index 602fa7f..bd27e2a 100644
--- a/extensions/desktop-icons/desktopGrid.js
+++ b/extensions/desktop-icons/desktopGrid.js
@@ -365,6 +365,7 @@ var DesktopGrid = class {
}
_openMenu(x, y) {
+ Extension.desktopManager.endRubberBand();
Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0);
this.actor._desktopBackgroundMenu.open(BoxPointer.PopupAnimation.NONE);
/* Since the handler is in the press event it needs to ignore the release event
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index a70cd98..c37e1e7 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -79,6 +79,7 @@ var DesktopManager = GObject.registerClass({
this._queryFileInfoCancellable = null;
this._unixMode = null;
this._writableByOthers = null;
+ this._rubberBandActive = false;
this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', () => this._recreateDesktopIcons());
this._rubberBand = new St.Widget({ style_class: 'rubber-band' });
@@ -86,6 +87,20 @@ var DesktopManager = GObject.registerClass({
Main.layoutManager._backgroundGroup.add_child(this._rubberBand);
this._grabHelper = new GrabHelper.GrabHelper(global.stage);
+ let origCapturedEvent = this._grabHelper.onCapturedEvent;
+ this._grabHelper.onCapturedEvent = (event) => {
+ if (event.type() === Clutter.EventType.MOTION) {
+ /* We handle motion events from a captured event handler so we
+ * we can see motion over actors that are on other parts of the
+ * stage.
+ */
+ this._handleMotion(event);
+ return Clutter.EVENT_STOP;
+ }
+
+ return origCapturedEvent.bind(this._grabHelper)(event);
+ };
+
this._addDesktopIcons();
this._monitorDesktopFolder();
@@ -108,30 +123,15 @@ var DesktopManager = GObject.registerClass({
this._initRubberBandColor();
this._updateRubberBand(x, y);
this._rubberBand.show();
- this._grabHelper.grab({ actor: global.stage });
+ this._rubberBandActive = true;
+ this._grabHelper.grab({
+ actor: Main.layoutManager._backgroundGroup,
+ onUngrab: () => this.endRubberBand(false),
+ });
Extension.lockActivitiesButton = true;
this._stageReleaseEventId = global.stage.connect('button-release-event', (actor, event) => {
this.endRubberBand();
});
- this._rubberBandId = global.stage.connect('motion-event', (actor, event) => {
- /* In some cases, when the user starts a rubberband selection and ends it
- * (by releasing the left button) over a window instead of doing it over
- * the desktop, the stage doesn't receive the "button-release" event.
- * This happens currently with, at least, Dash to Dock extension, but
- * it probably also happens with other applications or extensions.
- * To fix this, we also end the rubberband selection if we detect mouse
- * motion in the stage without the left button pressed during a
- * rubberband selection.
- * */
- let button = event.get_state();
- if (!(button & Clutter.ModifierType.BUTTON1_MASK)) {
- this.endRubberBand();
- return;
- }
- [x, y] = event.get_coords();
- this._updateRubberBand(x, y);
- this._updateSelection(x, y);
- });
this._rubberBandTouchId = global.stage.connect('touch-event', (actor, event) => {
// Let x11 pointer emulation do the job on X11
if (!Meta.is_wayland_compositor())
@@ -175,14 +175,37 @@ var DesktopManager = GObject.registerClass({
}
}
- endRubberBand() {
+ _handleMotion(event) {
+ /* In some cases, when the user starts a rubberband selection and ends it
+ * (by releasing the left button) over a window instead of doing it over
+ * the desktop, the stage doesn't receive the "button-release" event.
+ * This happens currently with, at least, Dash to Dock extension, but
+ * it probably also happens with other applications or extensions.
+ * To fix this, we also end the rubberband selection if we detect mouse
+ * motion in the stage without the left button pressed during a
+ * rubberband selection.
+ * */
+ let button = event.get_state();
+ if (!(button & Clutter.ModifierType.BUTTON1_MASK)) {
+ this.endRubberBand();
+ return;
+ }
+ let [x, y] = event.get_coords();
+ this._updateRubberBand(x, y);
+ this._updateSelection(x, y);
+ }
+
+ endRubberBand(ungrab=true) {
+ if (!this._rubberBandActive)
+ return;
+
+ this._rubberBandActive = false;
this._rubberBand.hide();
Extension.lockActivitiesButton = false;
- this._grabHelper.ungrab();
- global.stage.disconnect(this._rubberBandId);
+ if (ungrab)
+ this._grabHelper.ungrab();
global.stage.disconnect(this._rubberBandTouchId);
global.stage.disconnect(this._stageReleaseEventId);
- this._rubberBandId = 0;
this._rubberBandTouchId = 0;
this._stageReleaseEventId = 0;
@@ -760,10 +783,6 @@ var DesktopManager = GObject.registerClass({
global.stage.disconnect(this._stageReleaseEventId);
this._stageReleaseEventId = 0;
- if (this._rubberBandId)
- global.stage.disconnect(this._rubberBandId);
- this._rubberBandId = 0;
-
if (this._rubberBandTouchId)
global.stage.disconnect(this._rubberBandTouchId);
this._rubberBandTouchId = 0;
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 1cb47e8..90f326d 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -676,6 +676,7 @@ var FileItem = class {
}
_onPressButton(actor, event) {
+ Extension.desktopManager.endRubberBand();
this._updateClickState(event);
let button = this._eventButton(event);
if (button == 3) {
--
2.31.1

View File

@ -1,31 +0,0 @@
From 0a7248c75c084a83852aa3d0e7a36ccebd365b81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 27 Jan 2021 11:51:28 +0100
Subject: [PATCH] desktop-icons: Update Japanese translation
---
po/ja.po | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/po/ja.po b/po/ja.po
index df5646d..4d780b9 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -293,13 +293,8 @@ msgid "Workspace %d"
msgstr "ワークスペース %d"
#: desktopGrid.js:334
-#, fuzzy
msgid "Display Settings"
-msgstr ""
-"#-#-#-#-# ja.po (gnome-shell-extensions master) #-#-#-#-#\n"
-"ディスプレイ設定\n"
-"#-#-#-#-# ja.po (desktop-icons master) #-#-#-#-#\n"
-"ディスプレイの設定"
+msgstr "ディスプレイ設定"
#: schemas/org.gnome.shell.extensions.desktop-icons.gschema.xml:11
#, fuzzy
--
2.29.2

View File

@ -1,28 +0,0 @@
From 81b5163b43b7d45ca8bc9205476ef67789e283a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 29 Nov 2021 16:48:53 +0100
Subject: [PATCH] desktop-icons: Use a single unique name to access nautilus
... otherwise dbus-daemon will assume that activating one of the
services failed, because its executable exits early (after activating
the primary instance).
---
extensions/desktop-icons/dbusUtils.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/desktop-icons/dbusUtils.js b/extensions/desktop-icons/dbusUtils.js
index 19fe9878..b44ffa59 100644
--- a/extensions/desktop-icons/dbusUtils.js
+++ b/extensions/desktop-icons/dbusUtils.js
@@ -64,7 +64,7 @@ function init() {
FreeDesktopFileManagerProxy = new FreeDesktopFileManagerProxyInterface(
Gio.DBus.session,
- 'org.freedesktop.FileManager1',
+ 'org.gnome.Nautilus',
'/org/freedesktop/FileManager1',
(proxy, error) => {
if (error) {
--
2.33.1

View File

@ -1,83 +0,0 @@
From f78b19068654412ca9e73a229e1537d080759c47 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 27 Jan 2021 16:55:10 +0100
Subject: [PATCH] fileItem: Ignore double click distance clicking on items
Imitate the behavior of Nautilus canvas WRT double clicks being
handled on all of the icon(s) without accounting for the double
click distance. As the extension does already lean on Nautilus
look & feel, it seems to make sense doing this.
This is not as crucial for mice as it is for touchscreens, where
the default 5px limit may be a bit on the short side depending
on device sensitivity.
---
extensions/desktop-icons/fileItem.js | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index d6d43c9..5d3195f 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -65,6 +65,9 @@ var FileItem = class {
this._setMetadataCancellable = null;
this._queryFileInfoCancellable = null;
this._isSpecial = this._fileExtra != Prefs.FileType.NONE;
+ this._lastClickTime = 0;
+ this._lastClickButton = 0;
+ this._clickCount = 0;
this._file = file;
@@ -642,7 +645,24 @@ var FileItem = class {
DesktopIconsUtil.launchTerminal(this.file.get_path());
}
+ _updateClickState(event) {
+ let settings = Clutter.Settings.get_default();
+ if ((event.get_button() == this._lastClickButton) &&
+ ((event.get_time() - this._lastClickTime) < settings.double_click_time))
+ this._clickCount++;
+ else
+ this._clickCount = 1;
+
+ this._lastClickTime = event.get_time();
+ this._lastClickButton = event.get_button();
+ }
+
+ _getClickCount() {
+ return this._clickCount;
+ }
+
_onPressButton(actor, event) {
+ this._updateClickState(event);
let button = event.get_button();
if (button == 3) {
if (!this.isSelected)
@@ -661,7 +681,7 @@ var FileItem = class {
this._actionTrash.setSensitive(!specialFilesSelected);
return Clutter.EVENT_STOP;
} else if (button == 1) {
- if (event.get_click_count() == 1) {
+ if (this._getClickCount() == 1) {
let [x, y] = event.get_coords();
this._primaryButtonPressed = true;
this._buttonPressInitialX = x;
@@ -710,12 +730,12 @@ var FileItem = class {
this._primaryButtonPressed = false;
let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
- if ((event.get_click_count() == 1) && Prefs.CLICK_POLICY_SINGLE && !shiftPressed && !controlPressed)
+ if ((this._getClickCount() == 1) && Prefs.CLICK_POLICY_SINGLE && !shiftPressed && !controlPressed)
this.doOpen();
this.emit('selected', shiftPressed || controlPressed, false, true);
return Clutter.EVENT_STOP;
}
- if ((event.get_click_count() == 2) && (!Prefs.CLICK_POLICY_SINGLE))
+ if ((this._getClickCount() == 2) && (!Prefs.CLICK_POLICY_SINGLE))
this.doOpen();
}
return Clutter.EVENT_PROPAGATE;
--
2.29.2

View File

@ -1,31 +0,0 @@
From 506c6d69eaa5e056d9580a28e9c200586b0e1fb0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 2 Dec 2022 15:20:40 +0100
Subject: [PATCH] fileItem: Just destroy menus
The menu manager is smart enough to remove the menu automatically,
and the actor will be destroyed alongside the menu. Not doing those
actions explicitly allows the automatic handling to proceed without
confusing the grab state.
---
extensions/desktop-icons/fileItem.js | 4 ----
1 file changed, 4 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 44a93352..f2f03440 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -575,10 +575,6 @@ var FileItem = class {
_removeMenu() {
if (this._menu != null) {
- if (this._menuManager != null)
- this._menuManager.removeMenu(this._menu);
-
- Main.layoutManager.uiGroup.remove_child(this._menu.actor);
this._menu.destroy();
this._menu = null;
}
--
2.38.1

View File

@ -1,147 +0,0 @@
From be4ab59a3f2bb9829dde390db3dd8868a08840eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 2 Dec 2022 19:28:54 +0100
Subject: [PATCH] fileItem: Support .desktop files of type Link
Gio only has direct support for .desktop files of type Application.
However in the context of desktop icons (and file managers), shortcuts
of URLs are useful as well, so add explicit support for .desktop files
of type Link.
---
extensions/desktop-icons/fileItem.js | 71 +++++++++++++++++++++++-----
1 file changed, 60 insertions(+), 11 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index f2f03440..1c9a1e55 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -239,12 +239,32 @@ var FileItem = class {
log(`desktop-icons: File ${this._displayName} is writable by others - will not allow launching`);
if (this._isDesktopFile) {
- this._desktopFile = Gio.DesktopAppInfo.new_from_filename(this._file.get_path());
- if (!this._desktopFile) {
- log(`Couldnt parse ${this._displayName} as a desktop file, will treat it as a regular file.`);
+ try {
+ const keyFile = new GLib.KeyFile();
+ keyFile.load_from_file(this._file.get_path(), GLib.KeyFileFlags.NONE);
+
+ const type = keyFile.get_string(
+ GLib.KEY_FILE_DESKTOP_GROUP, GLib.KEY_FILE_DESKTOP_KEY_TYPE);
+ switch (type) {
+ case GLib.KEY_FILE_DESKTOP_TYPE_APPLICATION:
+ this._desktopFile = Gio.DesktopAppInfo.new_from_keyfile(keyFile);
+ if (!this._desktopFile) {
+ log(`Couldnt parse ${this._displayName} as a desktop file, will treat it as a regular file.`);
+ this._isValidDesktopFile = false;
+ } else {
+ this._isValidDesktopFile = true;
+ }
+ break;
+ case GLib.KEY_FILE_DESKTOP_TYPE_LINK:
+ const url = keyFile.get_string(
+ GLib.KEY_FILE_DESKTOP_GROUP, GLib.KEY_FILE_DESKTOP_KEY_URL);
+ if (url)
+ this._linkFile = keyFile;
+ default: // fall-through
+ this._isValidDesktopFile = false;
+ }
+ } catch (e) {
this._isValidDesktopFile = false;
- } else {
- this._isValidDesktopFile = true;
}
} else {
this._isValidDesktopFile = false;
@@ -356,8 +376,17 @@ var FileItem = class {
if (this._isBrokenSymlink) {
this._icon.child = this._createEmblemedStIcon(null, 'text-x-generic');
} else {
- if (this.trustedDesktopFile && this._desktopFile.has_key('Icon'))
- this._icon.child = this._createEmblemedStIcon(null, this._desktopFile.get_string('Icon'));
+ let iconName = null;
+
+ try {
+ if (this.trustedDesktopFile)
+ iconName = this._desktopFile.get_string('Icon');
+ else if (this._linkFile)
+ iconName = this._linkFile.get_string(GLib.KEY_FILE_DESKTOP_GROUP, GLib.KEY_FILE_DESKTOP_KEY_ICON);
+ } catch (e) {}
+
+ if (iconName)
+ this._icon.child = this._createEmblemedStIcon(null, iconName);
else
this._icon.child = this._createEmblemedStIcon(this._fileInfo.get_icon(), null);
}
@@ -411,7 +440,7 @@ var FileItem = class {
itemIcon.add_emblem(Gio.Emblem.new(Gio.ThemedIcon.new('emblem-unreadable')));
else
itemIcon.add_emblem(Gio.Emblem.new(Gio.ThemedIcon.new('emblem-symbolic-link')));
- } else if (this.trustedDesktopFile) {
+ } else if (this.trustedDesktopFile || this._linkFile) {
itemIcon.add_emblem(Gio.Emblem.new(Gio.ThemedIcon.new('emblem-symbolic-link')));
}
@@ -440,6 +469,12 @@ var FileItem = class {
return;
}
+ if (this._linkFile) {
+ this._openUri(this._linkFile.get_string(
+ GLib.KEY_FILE_DESKTOP_GROUP, GLib.KEY_FILE_DESKTOP_KEY_URL));
+ return;
+ }
+
if (this._attributeCanExecute &&
!this._isDirectory &&
!this._isValidDesktopFile &&
@@ -449,13 +484,17 @@ var FileItem = class {
return;
}
- Gio.AppInfo.launch_default_for_uri_async(this.file.get_uri(),
+ this._openUri(this.file.get_uri());
+ }
+
+ _openUri(uri) {
+ Gio.AppInfo.launch_default_for_uri_async(uri,
null, null,
(source, result) => {
try {
Gio.AppInfo.launch_default_for_uri_finish(result);
} catch (e) {
- log('Error opening file ' + this.file.get_uri() + ': ' + e.message);
+ log('Error opening file ' + uri + ': ' + e.message);
}
}
);
@@ -555,7 +594,9 @@ var FileItem = class {
}
canRename() {
- return !this.trustedDesktopFile && this._fileExtra == Prefs.FileType.NONE;
+ return !this.trustedDesktopFile &&
+ !this._linkFile &&
+ this._fileExtra == Prefs.FileType.NONE;
}
_doOpenWith() {
@@ -819,6 +860,14 @@ var FileItem = class {
if (this.trustedDesktopFile)
return this._desktopFile.get_name();
+ if (this._linkFile) {
+ try {
+ const name = this._linkFile.get_string(
+ GLib.KEY_FILE_DESKTOP_GROUP, GLib.KEY_FILE_DESKTOP_KEY_NAME);
+ return name;
+ } catch (e) {}
+ }
+
return this._displayName || null;
}
--
2.38.1

View File

@ -1,45 +0,0 @@
From ee89a91a9ac235b69ff3c47af14d702c0309e892 Mon Sep 17 00:00:00 2001
From: Sergio Costas <raster@rastersoft.com>
Date: Thu, 25 Jul 2019 00:12:09 +0200
Subject: [PATCH] general: launch only executable files
Until now, if a file has the "execute" flag, clicking on it will try
to execute it, no matter if it is really an executable. This means
that a non-executable file (like a JPEG picture, or a text file)
won't be opened with its desired application if it has set the
executable flag.
This patch fixes this, by ensuring that the only files that can be
executed when the "execute" flag is set, are the ones that makes
sense to execute.
Fixes https://gitlab.gnome.org/World/ShellExtensions/desktop-icons/issues/144
---
extensions/desktop-icons/fileItem.js | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index d6d43c9f..44a93352 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -440,10 +440,13 @@ var FileItem = class {
return;
}
- if (this._attributeCanExecute && !this._isDirectory && !this._isValidDesktopFile) {
- if (this._execLine)
- Util.spawnCommandLine(this._execLine);
- return;
+ if (this._attributeCanExecute &&
+ !this._isDirectory &&
+ !this._isValidDesktopFile &&
+ Gio.content_type_can_be_executable(this._attributeContentType)) {
+ if (this._execLine)
+ Util.spawnCommandLine(this._execLine);
+ return;
}
Gio.AppInfo.launch_default_for_uri_async(this.file.get_uri(),
--
2.31.1

View File

@ -1,51 +0,0 @@
From ce75829479b1e7bf99e74bf835174e91c8da2276 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 9 Dec 2022 15:31:08 +0100
Subject: [PATCH] gesture-inhibitor: Allow inhibiting workspace switch gesture
---
extensions/gesture-inhibitor/extension.js | 5 ++++-
.../org.gnome.shell.extensions.gesture-inhibitor.gschema.xml | 4 ++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
index e74ede2f..bf02d075 100644
--- a/extensions/gesture-inhibitor/extension.js
+++ b/extensions/gesture-inhibitor/extension.js
@@ -37,6 +37,8 @@ class Extension {
this._showOverview = a;
else if (a instanceof WindowManager.AppSwitchAction)
this._appSwitch = a;
+ else if (a instanceof WindowManager.WorkspaceSwitchAction)
+ this._workspaceSwitch = a;
else if (a instanceof EdgeDragAction.EdgeDragAction &&
a._side == St.Side.BOTTOM)
this._showOsk = a;
@@ -52,7 +54,8 @@ class Extension {
{ setting: 'app-switch', action: this._appSwitch },
{ setting: 'show-osk', action: this._showOsk },
{ setting: 'unfullscreen', action: this._unfullscreen },
- { setting: 'show-app-grid', action: this._showAppGrid }
+ { setting: 'show-app-grid', action: this._showAppGrid },
+ { setting: 'workspace-switch', action: this._workspaceSwitch },
];
}
diff --git a/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml b/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
index 1d67dcc0..a5e97a3d 100644
--- a/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
+++ b/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
@@ -16,6 +16,10 @@
<default>true</default>
<summary>Application switch gesture</summary>
</key>
+ <key name="workspace-switch" type="b">
+ <default>true</default>
+ <summary>Workspace switch gesture</summary>
+ </key>
<key name="unfullscreen" type="b">
<default>true</default>
<summary>Unfullscreen gesture</summary>
--
2.38.1

View File

@ -1,41 +0,0 @@
From dfdd10b46d670674d5e0e38f7adcd007f5884822 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 29 Sep 2021 14:33:25 +0200
Subject: [PATCH] gesture-inhibitor: Put a foot down with self-enabling
gestures
If a gesture (unfullscreen, I'm looking at you) controls its 'enabled'
property, it will bypass the will of this extension. Make it sure that
gestures are forced-off if the extension says so.
---
extensions/gesture-inhibitor/extension.js | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
index e74ede2..66c706e 100644
--- a/extensions/gesture-inhibitor/extension.js
+++ b/extensions/gesture-inhibitor/extension.js
@@ -59,13 +59,19 @@ class Extension {
enable() {
this._map.forEach(m => {
this._settings.bind(m.setting, m.action, 'enabled',
- Gio.SettingsBindFlags.DEFAULT);
+ Gio.SettingsBindFlags.GET);
+ m.handler = m.action.connect('notify::enabled', () => {
+ if (m.action.enabled && !this._settings.get_boolean(m.setting))
+ m.action.enabled = this._settings.get_boolean(m.setting);
+ });
});
}
disable() {
this._map.forEach(m => {
m.action.enabled = true;
+ if (m.handler > 0)
+ m.action.disconnect(m.handler);
});
}
}
--
2.31.1

View File

@ -1,831 +0,0 @@
From 8da1760af68496c6073be4d6b3c8266b64347925 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 24 Aug 2021 15:03:57 -0400
Subject: [PATCH] heads-up-display: Add extension for showing persistent heads
up display message
---
extensions/heads-up-display/extension.js | 320 ++++++++++++++++++
extensions/heads-up-display/headsUpMessage.js | 150 ++++++++
extensions/heads-up-display/meson.build | 8 +
extensions/heads-up-display/metadata.json.in | 11 +
...ll.extensions.heads-up-display.gschema.xml | 54 +++
extensions/heads-up-display/prefs.js | 175 ++++++++++
extensions/heads-up-display/stylesheet.css | 32 ++
meson.build | 1 +
8 files changed, 751 insertions(+)
create mode 100644 extensions/heads-up-display/extension.js
create mode 100644 extensions/heads-up-display/headsUpMessage.js
create mode 100644 extensions/heads-up-display/meson.build
create mode 100644 extensions/heads-up-display/metadata.json.in
create mode 100644 extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml
create mode 100644 extensions/heads-up-display/prefs.js
create mode 100644 extensions/heads-up-display/stylesheet.css
diff --git a/extensions/heads-up-display/extension.js b/extensions/heads-up-display/extension.js
new file mode 100644
index 00000000..e4ef9e85
--- /dev/null
+++ b/extensions/heads-up-display/extension.js
@@ -0,0 +1,320 @@
+/* exported init enable disable */
+
+
+const Signals = imports.signals;
+
+const {
+ Atk, Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St,
+} = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = ExtensionUtils.getCurrentExtension();
+
+const Main = imports.ui.main;
+const HeadsUpMessage = Me.imports.headsUpMessage;
+
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
+const _ = Gettext.gettext;
+
+class Extension {
+ constructor() {
+ ExtensionUtils.initTranslations();
+ }
+
+ enable() {
+ this._settings = ExtensionUtils.getSettings('org.gnome.shell.extensions.heads-up-display');
+ this._idleTimeoutChangedId = this._settings.connect('changed::idle-timeout', this._onIdleTimeoutChanged.bind(this));
+ this._settingsChangedId = this._settings.connect('changed', this._updateMessage.bind(this));
+
+ this._idleMonitor = Meta.IdleMonitor.get_core();
+ this._messageInhibitedUntilIdle = false;
+ this._oldMapWindow = Main.wm._mapWindow;
+ Main.wm._mapWindow = this._mapWindow;
+ this._windowManagerMapId = global.window_manager.connect('map', this._onWindowMap.bind(this));
+
+ if (Main.layoutManager._startingUp)
+ this._startupCompleteId = Main.layoutManager.connect('startup-complete', this._onStartupComplete.bind(this));
+ else
+ this._onStartupComplete(this);
+ }
+
+ disable() {
+ this._dismissMessage();
+
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+
+ if (this._sessionModeUpdatedId) {
+ Main.sessionMode.disconnect(this._sessionModeUpdatedId);
+ this._sessionModeUpdatedId = 0;
+ }
+
+ if (this._overviewShowingId) {
+ Main.overview.disconnect(this._overviewShowingId);
+ this._overviewShowingId = 0;
+ }
+
+ if (this._overviewHiddenId) {
+ Main.overview.disconnect(this._overviewHiddenId);
+ this._overviewHiddenId = 0;
+ }
+
+ if (this._panelConnectionId) {
+ Main.layoutManager.panelBox.disconnect(this._panelConnectionId);
+ this._panelConnectionId = 0;
+ }
+
+ if (this._oldMapWindow) {
+ Main.wm._mapWindow = this._oldMapWindow;
+ this._oldMapWindow = null;
+ }
+
+ if (this._windowManagerMapId) {
+ global.window_manager.disconnect(this._windowManagerMapId);
+ this._windowManagerMapId = 0;
+ }
+
+ if (this._startupCompleteId) {
+ Main.layoutManager.disconnect(this._startupCompleteId);
+ this._startupCompleteId = 0;
+ }
+
+ if (this._settingsChangedId) {
+ this._settings.disconnect(this._settingsChangedId);
+ this._settingsChangedId = 0;
+ }
+ }
+
+ _onWindowMap(shellwm, actor) {
+ let windowObject = actor.meta_window;
+ let windowType = windowObject.get_window_type();
+
+ if (windowType != Meta.WindowType.NORMAL)
+ return;
+
+ if (!this._message || !this._message.visible)
+ return;
+
+ let messageRect = new Meta.Rectangle({ x: this._message.x, y: this._message.y, width: this._message.width, height: this._message.height });
+ let windowRect = windowObject.get_frame_rect();
+
+ if (windowRect.intersect(messageRect)) {
+ windowObject.move_frame(false, windowRect.x, this._message.y + this._message.height);
+ }
+ }
+
+ _onStartupComplete() {
+ this._overviewShowingId = Main.overview.connect('showing', this._updateMessage.bind(this));
+ this._overviewHiddenId = Main.overview.connect('hidden', this._updateMessage.bind(this));
+ this._panelConnectionId = Main.layoutManager.panelBox.connect('notify::visible', this._updateMessage.bind(this));
+ this._sessionModeUpdatedId = Main.sessionMode.connect('updated', this._onSessionModeUpdated.bind(this));
+
+ this._updateMessage();
+ }
+
+ _onSessionModeUpdated() {
+ if (!Main.sessionMode.hasWindows)
+ this._messageInhibitedUntilIdle = false;
+ this._updateMessage();
+ }
+
+ _onIdleTimeoutChanged() {
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+ this._messageInhibitedUntilIdle = false;
+ }
+
+ _updateMessage() {
+ if (this._messageInhibitedUntilIdle) {
+ if (this._message)
+ this._dismissMessage();
+ return;
+ }
+
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+
+ if (Main.sessionMode.hasOverview && Main.overview.visible) {
+ this._dismissMessage();
+ return;
+ }
+
+ if (!Main.layoutManager.panelBox.visible) {
+ this._dismissMessage();
+ return;
+ }
+
+ let supportedModes = [];
+
+ if (this._settings.get_boolean('show-when-unlocked'))
+ supportedModes.push('user');
+
+ if (this._settings.get_boolean('show-when-unlocking'))
+ supportedModes.push('unlock-dialog');
+
+ if (this._settings.get_boolean('show-when-locked'))
+ supportedModes.push('lock-screen');
+
+ if (this._settings.get_boolean('show-on-login-screen'))
+ supportedModes.push('gdm');
+
+ if (!supportedModes.includes(Main.sessionMode.currentMode) &&
+ !supportedModes.includes(Main.sessionMode.parentMode)) {
+ this._dismissMessage();
+ return;
+ }
+
+ let heading = this._settings.get_string('message-heading');
+ let body = this._settings.get_string('message-body');
+
+ if (!heading && !body) {
+ this._dismissMessage();
+ return;
+ }
+
+ if (!this._message) {
+ this._message = new HeadsUpMessage.HeadsUpMessage(heading, body);
+
+ this._message.connect('notify::allocation', this._adaptSessionForMessage.bind(this));
+ this._message.connect('clicked', this._onMessageClicked.bind(this));
+ }
+
+ this._message.reactive = true;
+ this._message.track_hover = true;
+
+ this._message.setHeading(heading);
+ this._message.setBody(body);
+
+ if (!Main.sessionMode.hasWindows) {
+ this._message.track_hover = false;
+ this._message.reactive = false;
+ }
+ }
+
+ _onMessageClicked() {
+ if (!Main.sessionMode.hasWindows)
+ return;
+
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+
+ let idleTimeout = this._settings.get_uint('idle-timeout');
+ this._idleWatchId = this._idleMonitor.add_idle_watch(idleTimeout * 1000, this._onUserIdle.bind(this));
+ this._messageInhibitedUntilIdle = true;
+ this._updateMessage();
+ }
+
+ _onUserIdle() {
+ this._messageInhibitedUntilIdle = false;
+ this._updateMessage();
+ }
+
+ _dismissMessage() {
+ if (!this._message) {
+ return;
+ }
+
+ this._message.visible = false;
+ this._message.destroy();
+ this._message = null;
+ this._resetMessageTray();
+ this._resetLoginDialog();
+ }
+
+ _resetMessageTray() {
+ if (!Main.messageTray)
+ return;
+
+ Main.messageTray.actor.set_translation(0, 0, 0);
+ }
+
+ _alignMessageTray() {
+ if (!Main.messageTray)
+ return;
+
+ if (!this._message || !this._message.visible) {
+ this._resetMessageTray()
+ return;
+ }
+
+ let panelBottom = Main.layoutManager.panelBox.y + Main.layoutManager.panelBox.height;
+ let messageBottom = this._message.y + this._message.height;
+
+ Main.messageTray.actor.set_translation(0, messageBottom - panelBottom, 0);
+ }
+
+ _resetLoginDialog() {
+ if (!Main.sessionMode.isGreeter)
+ return;
+
+ if (!Main.screenShield || !Main.screenShield._dialog)
+ return;
+
+ let dialog = Main.screenShield._dialog;
+
+ if (this._authPromptAllocatedId) {
+ dialog.disconnect(this._authPromptAllocatedId);
+ this._authPromptAllocatedId = 0;
+ }
+
+ dialog.style = null;
+ dialog._bannerView.style = null;
+ }
+
+ _adaptLoginDialogForMessage() {
+ if (!Main.sessionMode.isGreeter)
+ return;
+
+ if (!Main.screenShield || !Main.screenShield._dialog)
+ return;
+
+ if (!this._message || !this._message.visible) {
+ this._resetLoginDialog()
+ return;
+ }
+
+ let dialog = Main.screenShield._dialog;
+
+ let messageHeight = this._message.y + this._message.height;
+ if (dialog._logoBin.visible)
+ messageHeight -= dialog._logoBin.height;
+
+ if (messageHeight <= 0) {
+ dialog.style = null;
+ dialog._bannerView.style = null;
+ } else {
+ dialog.style = `margin-top: ${messageHeight}px;`;
+
+ let bannerOnSide = dialog._bannerView.x + dialog._bannerView.width < dialog._authPrompt.actor.x;
+
+ if (bannerOnSide)
+ dialog._bannerView.style = `margin-bottom: ${messageHeight}px;`;
+ else
+ dialog._bannerView.style = `margin-top: ${messageHeight}px`;
+ }
+ }
+
+ _adaptSessionForMessage() {
+ this._alignMessageTray();
+
+ if (Main.sessionMode.isGreeter) {
+ this._adaptLoginDialogForMessage();
+ if (!this._authPromptAllocatedId) {
+ let dialog = Main.screenShield._dialog;
+ this._authPromptAllocatedId = dialog._authPrompt.actor.connect("notify::allocation", this._adaptLoginDialogForMessage.bind(this));
+ }
+ }
+ }
+}
+
+function init() {
+ return new Extension();
+}
diff --git a/extensions/heads-up-display/headsUpMessage.js b/extensions/heads-up-display/headsUpMessage.js
new file mode 100644
index 00000000..d828d8c9
--- /dev/null
+++ b/extensions/heads-up-display/headsUpMessage.js
@@ -0,0 +1,150 @@
+const { Atk, Clutter, GObject, Pango, St } = imports.gi;
+const Layout = imports.ui.layout;
+const Main = imports.ui.main;
+const Signals = imports.signals;
+
+var HeadsUpMessageBodyLabel = GObject.registerClass({
+}, class HeadsUpMessageBodyLabel extends St.Label {
+ _init(params) {
+ super._init(params);
+
+ this.clutter_text.single_line_mode = false;
+ this.clutter_text.line_wrap = true;
+ }
+
+ vfunc_get_preferred_width(forHeight) {
+ let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+
+ let [labelMinimumWidth, labelNaturalWidth] = super.vfunc_get_preferred_width(forHeight);
+
+ labelMinimumWidth = Math.min(labelMinimumWidth, .75 * workArea.width);
+ labelNaturalWidth = Math.min(labelNaturalWidth, .75 * workArea.width);
+
+ return [labelMinimumWidth, labelNaturalWidth];
+ }
+
+ vfunc_get_preferred_height(forWidth) {
+ let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+ let labelHeightUpperBound = .25 * workArea.height;
+
+ this.clutter_text.single_line_mode = true;
+ this.clutter_text.line_wrap = false;
+ let [lineHeight] = super.vfunc_get_preferred_height(-1);
+ let numberOfLines = Math.floor(labelHeightUpperBound / lineHeight);
+ numberOfLines = Math.max(numberOfLines, 1);
+
+ let labelHeight = lineHeight * numberOfLines;
+
+ this.clutter_text.single_line_mode = false;
+ this.clutter_text.line_wrap = true;
+ let [labelMinimumHeight, labelNaturalHeight] = super.vfunc_get_preferred_height(forWidth);
+
+ labelMinimumHeight = Math.min(labelMinimumHeight, labelHeight);
+ labelNaturalHeight = Math.min(labelNaturalHeight, labelHeight);
+
+ return [labelMinimumHeight, labelNaturalHeight];
+ }
+
+ vfunc_allocate(box, flags) {
+ if (!this.visible)
+ return;
+
+ super.vfunc_allocate(box, flags);
+ }
+});
+
+var HeadsUpMessage = GObject.registerClass({
+}, class HeadsUpMessage extends St.Button {
+ _init(heading, body) {
+ super._init({
+ style_class: 'message',
+ accessible_role: Atk.Role.NOTIFICATION,
+ can_focus: false,
+ });
+
+ Main.layoutManager.addChrome(this, { affectsInputRegion: true });
+
+ this.add_style_class_name('heads-up-display-message');
+
+ this._panelAllocationId = Main.layoutManager.panelBox.connect ("notify::allocation", this._alignWithPanel.bind(this));
+ this.connect("notify::allocation", this._alignWithPanel.bind(this));
+
+ this._messageTraySnappingId = Main.messageTray.connect ("notify::y", () => {
+ if (!this.visible)
+ return;
+
+ if (!Main.messageTray.visible)
+ return;
+
+ if (Main.messageTray.y >= this.y && Main.messageTray.y < this.y + this.height)
+ Main.messageTray.y = this.y + this.height;
+ });
+
+
+ let contentsBox = new St.BoxLayout({ style_class: 'heads-up-message-content',
+ vertical: true,
+ x_align: Clutter.ActorAlign.CENTER });
+ this.add_actor(contentsBox);
+
+ this.headingLabel = new St.Label({ style_class: 'heads-up-message-heading',
+ x_expand: true,
+ x_align: Clutter.ActorAlign.CENTER });
+ this.setHeading(heading);
+ contentsBox.add_actor(this.headingLabel);
+ this.contentsBox = contentsBox;
+
+ this.bodyLabel = new HeadsUpMessageBodyLabel({ style_class: 'heads-up-message-body',
+ x_expand: true,
+ y_expand: true });
+ contentsBox.add_actor(this.bodyLabel);
+
+ this.setBody(body);
+ this.bodyLabel.clutter_text.label = this.bodyLabel;
+ }
+
+ _alignWithPanel() {
+ if (!this.visible)
+ return;
+
+ this.x = Main.panel.actor.x;
+ this.x += Main.panel.actor.width / 2;
+ this.x -= this.width / 2;
+ this.x = Math.floor(this.x);
+ this.y = Main.panel.actor.y + Main.panel.actor.height;
+ this.queue_relayout();
+ }
+
+ setHeading(text) {
+ if (text) {
+ let heading = text ? text.replace(/\n/g, ' ') : '';
+ this.headingLabel.text = heading;
+ this.headingLabel.visible = true;
+ } else {
+ this.headingLabel.text = text;
+ this.headingLabel.visible = false;
+ }
+ }
+
+ setBody(text) {
+ this.bodyLabel.text = text;
+ if (text) {
+ this.bodyLabel.visible = true;
+ } else {
+ this.bodyLabel.visible = false;
+ }
+ }
+
+ destroy() {
+ if (this._panelAllocationId) {
+ Main.layoutManager.panelBox.disconnect(this._panelAllocationId);
+ this._panelAllocationId = 0;
+ }
+
+ if (this._messageTraySnappingId) {
+ Main.messageTray.disconnect(this._messageTraySnappingId);
+ this._messageTraySnappingId = 0;
+ }
+
+ super.destroy();
+ }
+});
diff --git a/extensions/heads-up-display/meson.build b/extensions/heads-up-display/meson.build
new file mode 100644
index 00000000..40c3de0a
--- /dev/null
+++ b/extensions/heads-up-display/meson.build
@@ -0,0 +1,8 @@
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
+
+extension_sources += files('headsUpMessage.js', 'prefs.js')
+extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/heads-up-display/metadata.json.in b/extensions/heads-up-display/metadata.json.in
new file mode 100644
index 00000000..e7ab71aa
--- /dev/null
+++ b/extensions/heads-up-display/metadata.json.in
@@ -0,0 +1,11 @@
+{
+"extension-id": "@extension_id@",
+"uuid": "@uuid@",
+"gettext-domain": "@gettext_domain@",
+"name": "Heads-up Display Message",
+"description": "Add a message to be displayed on screen always above all windows and chrome.",
+"original-authors": [ "rstrode@redhat.com" ],
+"shell-version": [ "@shell_current@" ],
+"url": "@url@",
+"session-modes": [ "gdm", "lock-screen", "unlock-dialog", "user" ]
+}
diff --git a/extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml b/extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml
new file mode 100644
index 00000000..ea1f3774
--- /dev/null
+++ b/extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml
@@ -0,0 +1,54 @@
+<schemalist gettext-domain="gnome-shell-extensions">
+ <schema id="org.gnome.shell.extensions.heads-up-display"
+ path="/org/gnome/shell/extensions/heads-up-display/">
+ <key name="idle-timeout" type="u">
+ <default>30</default>
+ <summary>Idle Timeout</summary>
+ <description>
+ Number of seconds until message is reshown after user goes idle.
+ </description>
+ </key>
+ <key name="message-heading" type="s">
+ <default>""</default>
+ <summary>Message to show at top of display</summary>
+ <description>
+ The top line of the heads up display message.
+ </description>
+ </key>
+ <key name="message-body" type="s">
+ <default>""</default>
+ <summary>Banner message</summary>
+ <description>
+ A message to always show at the top of the screen.
+ </description>
+ </key>
+ <key name="show-on-login-screen" type="b">
+ <default>true</default>
+ <summary>Show on login screen</summary>
+ <description>
+ Whether or not the message should display on the login screen
+ </description>
+ </key>
+ <key name="show-when-locked" type="b">
+ <default>false</default>
+ <summary>Show on screen shield</summary>
+ <description>
+ Whether or not the message should display when the screen is locked
+ </description>
+ </key>
+ <key name="show-when-unlocking" type="b">
+ <default>false</default>
+ <summary>Show on unlock screen</summary>
+ <description>
+ Whether or not the message should display on the unlock screen.
+ </description>
+ </key>
+ <key name="show-when-unlocked" type="b">
+ <default>false</default>
+ <summary>Show in user session</summary>
+ <description>
+ Whether or not the message should display when the screen is unlocked.
+ </description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/extensions/heads-up-display/prefs.js b/extensions/heads-up-display/prefs.js
new file mode 100644
index 00000000..b4b6f94c
--- /dev/null
+++ b/extensions/heads-up-display/prefs.js
@@ -0,0 +1,175 @@
+
+/* Desktop Icons GNOME Shell extension
+ *
+ * Copyright (C) 2017 Carlos Soriano <csoriano@redhat.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+const { Gio, GObject, Gdk, Gtk } = imports.gi;
+const ExtensionUtils = imports.misc.extensionUtils;
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
+const _ = Gettext.gettext;
+const N_ = e => e;
+const cssData = `
+ .no-border {
+ border: none;
+ }
+
+ .border {
+ border: 1px solid;
+ border-radius: 3px;
+ border-color: #b6b6b3;
+ box-shadow: inset 0 0 0 1px rgba(74, 144, 217, 0);
+ background-color: white;
+ }
+
+ .margins {
+ padding-left: 8px;
+ padding-right: 8px;
+ padding-bottom: 8px;
+ }
+
+ .message-label {
+ font-weight: bold;
+ }
+`;
+
+var settings;
+
+function init() {
+ settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.heads-up-display");
+ let cssProvider = new Gtk.CssProvider();
+ cssProvider.load_from_data(cssData);
+
+ let screen = Gdk.Screen.get_default();
+ Gtk.StyleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function buildPrefsWidget() {
+ ExtensionUtils.initTranslations();
+
+ let contents = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ border_width: 20,
+ spacing: 10,
+ });
+
+ contents.add(buildSwitch('show-when-locked', _("Show message when screen is locked")));
+ contents.add(buildSwitch('show-when-unlocking', _("Show message on unlock screen")));
+ contents.add(buildSwitch('show-when-unlocked', _("Show message when screen is unlocked")));
+ contents.add(buildSpinButton('idle-timeout', _("Seconds after user goes idle before reshowing message")));
+
+ let outerMessageBox = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ border_width: 0,
+ spacing: 5,
+ });
+ contents.add(outerMessageBox);
+
+ let messageLabel = new Gtk.Label({
+ label: 'Message',
+ halign: Gtk.Align.START,
+ });
+ messageLabel.get_style_context().add_class("message-label");
+ outerMessageBox.add(messageLabel);
+
+ let innerMessageBox = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ border_width: 0,
+ spacing: 0,
+ });
+ innerMessageBox.get_style_context().add_class("border");
+ outerMessageBox.add(innerMessageBox);
+
+ innerMessageBox.add(buildEntry('message-heading', _("Message Heading")));
+ innerMessageBox.add(buildTextView('message-body', _("Message Body")));
+ contents.show_all();
+ return contents;
+}
+
+function buildTextView(key, labelText) {
+ let textView = new Gtk.TextView({
+ accepts_tab: false,
+ wrap_mode: Gtk.WrapMode.WORD,
+ });
+ settings.bind(key, textView.get_buffer(), 'text', Gio.SettingsBindFlags.DEFAULT);
+
+ let scrolledWindow = new Gtk.ScrolledWindow({
+ expand: true,
+ });
+ let styleContext = scrolledWindow.get_style_context();
+ styleContext.add_class("margins");
+
+ scrolledWindow.add(textView);
+ return scrolledWindow;
+}
+function buildEntry(key, labelText) {
+ let entry = new Gtk.Entry({ placeholder_text: labelText });
+ let styleContext = entry.get_style_context();
+ styleContext.add_class("no-border");
+ settings.bind(key, entry, 'text', Gio.SettingsBindFlags.DEFAULT);
+
+ entry.get_settings()['gtk-entry-select-on-focus'] = false;
+
+ return entry;
+}
+
+function buildSpinButton(key, labelText) {
+ let hbox = new Gtk.Box({
+ orientation: Gtk.Orientation.HORIZONTAL,
+ spacing: 10,
+ });
+ let label = new Gtk.Label({
+ label: labelText,
+ xalign: 0,
+ });
+ let adjustment = new Gtk.Adjustment({
+ value: 0,
+ lower: 0,
+ upper: 2147483647,
+ step_increment: 1,
+ page_increment: 60,
+ page_size: 60,
+ });
+ let spinButton = new Gtk.SpinButton({
+ adjustment: adjustment,
+ climb_rate: 1.0,
+ digits: 0,
+ max_width_chars: 3,
+ width_chars: 3,
+ });
+ settings.bind(key, spinButton, 'value', Gio.SettingsBindFlags.DEFAULT);
+ hbox.pack_start(label, true, true, 0);
+ hbox.add(spinButton);
+ return hbox;
+}
+
+function buildSwitch(key, labelText) {
+ let hbox = new Gtk.Box({
+ orientation: Gtk.Orientation.HORIZONTAL,
+ spacing: 10,
+ });
+ let label = new Gtk.Label({
+ label: labelText,
+ xalign: 0,
+ });
+ let switcher = new Gtk.Switch({
+ active: settings.get_boolean(key),
+ });
+ settings.bind(key, switcher, 'active', Gio.SettingsBindFlags.DEFAULT);
+ hbox.pack_start(label, true, true, 0);
+ hbox.add(switcher);
+ return hbox;
+}
diff --git a/extensions/heads-up-display/stylesheet.css b/extensions/heads-up-display/stylesheet.css
new file mode 100644
index 00000000..93034469
--- /dev/null
+++ b/extensions/heads-up-display/stylesheet.css
@@ -0,0 +1,32 @@
+.heads-up-display-message {
+ background-color: rgba(0.24, 0.24, 0.24, 0.80);
+ border: 1px solid black;
+ border-radius: 6px;
+ color: #eeeeec;
+ font-size: 11pt;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ padding: 0.9em;
+}
+
+.heads-up-display-message:insensitive {
+ background-color: rgba(0.24, 0.24, 0.24, 0.33);
+}
+
+.heads-up-display-message:hover {
+ background-color: rgba(0.24, 0.24, 0.24, 0.2);
+ border: 1px solid rgba(0.0, 0.0, 0.0, 0.5);
+ color: #4d4d4d;
+ transition-duration: 250ms;
+}
+
+.heads-up-message-heading {
+ height: 1.75em;
+ font-size: 1.25em;
+ font-weight: bold;
+ text-align: center;
+}
+
+.heads-up-message-body {
+ text-align: center;
+}
diff --git a/meson.build b/meson.build
index ba84f8f3..c5fc86ef 100644
--- a/meson.build
+++ b/meson.build
@@ -44,6 +44,7 @@ classic_extensions = [
default_extensions = classic_extensions
default_extensions += [
'drive-menu',
+ 'heads-up-display',
'screenshot-window-sizer',
'windowsNavigator',
'workspace-indicator'
--
2.32.0

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
From ce48dc2f4fba6a7084540df256cb5b3eb0da43da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 2 Jun 2021 17:32:21 +0200
Subject: [PATCH] top-icons: Don't use wm_class as role
This prevents adding icons for multiple instances of the same app,
which may be desirable in some circumstances.
---
extensions/top-icons/extension.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/top-icons/extension.js b/extensions/top-icons/extension.js
index 79e2f423..3dfba469 100644
--- a/extensions/top-icons/extension.js
+++ b/extensions/top-icons/extension.js
@@ -63,7 +63,7 @@ class SysTray {
button.destroy();
});
- let role = wmClass || `${icon}`;
+ const role = `${icon}`;
Main.panel.addToStatusArea(role, button);
}
--
2.31.1

View File

@ -1,55 +0,0 @@
From b4eeaf7ea12fa7d9713e80371490d8060396b3cb Mon Sep 17 00:00:00 2001
From: Milan Crha <mcrha@redhat.com>
Date: Fri, 17 Apr 2020 09:21:42 +0200
Subject: [PATCH] window-list: Invalid current mode selected in Preferences
It seems that gtk+ resets the active radio whenever a new radio button
is added into the group, thus rather restore the current mode after
the group is fully populated.
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/119
---
extensions/window-list/prefs.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/extensions/window-list/prefs.js b/extensions/window-list/prefs.js
index 78792b5..17e9799 100644
--- a/extensions/window-list/prefs.js
+++ b/extensions/window-list/prefs.js
@@ -50,6 +50,7 @@ class WindowListPrefsWidget extends Gtk.Grid {
};
let radio = null;
+ let currentRadio = null;
for (let i = 0; i < modes.length; i++) {
let mode = modes[i];
let label = modeLabels[mode];
@@ -59,18 +60,24 @@ class WindowListPrefsWidget extends Gtk.Grid {
}
radio = new Gtk.RadioButton({
- active: currentMode == mode,
+ active: !i,
label: label,
group: radio
});
grid.add(radio);
+ if (currentMode === mode)
+ currentRadio = radio;
+
radio.connect('toggled', button => {
if (button.active)
this._settings.set_string('grouping-mode', mode);
});
}
+ if (currentRadio)
+ currentRadio.active = true;
+
let check = new Gtk.CheckButton({
label: _('Show on all monitors'),
margin_top: 6
--
2.26.2

View File

@ -1,30 +0,0 @@
From ee25c2aac70b86f31c91f6491dad4c67a59bc261 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 26 Jan 2021 21:14:47 +0100
Subject: [PATCH] window-list: Leave "fake overview" when destroyed
Otherwise we leave an incomplete overview-like state around, which
can cause issues later when the extension is re-enabled (for example
when coming back from screen lock).
https://bugzilla.redhat.com/show_bug.cgi?id=1904371
---
extensions/window-list/windowPicker.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js
index 12a7627..afb5d27 100644
--- a/extensions/window-list/windowPicker.js
+++ b/extensions/window-list/windowPicker.js
@@ -210,6 +210,8 @@ var WindowPicker = class {
}
_onDestroy() {
+ this._fakeOverviewVisible(false);
+
if (this._monitorsChangedId)
Main.layoutManager.disconnect(this._monitorsChangedId);
this._monitorsChangedId = 0;
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +0,0 @@
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
When showing previews instead of the menu, the workspace names from
our preferences don't appear anywhere. Some users care strongly about
those, so expose them as tooltip on hover.
---
extensions/workspace-indicator/extension.js | 40 +++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js
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;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
+const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
@@ -15,6 +16,9 @@ const _ = Gettext.gettext;
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
const WORKSPACE_KEY = 'workspace-names';
+const TOOLTIP_OFFSET = 6;
+const TOOLTIP_ANIMATION_TIME = 150;
+
let WindowPreview = GObject.registerClass({
GTypeName: 'WorkspaceIndicatorWindowPreview'
}, class WindowPreview extends St.Button {
@@ -117,7 +121,14 @@ let WorkspaceThumbnail = GObject.registerClass({
y_fill: true
});
+ this._tooltip = new St.Label({
+ style_class: 'dash-label',
+ visible: false,
+ });
+ Main.uiGroup.add_child(this._tooltip);
+
this.connect('destroy', this._onDestroy.bind(this));
+ this.connect('notify::hover', this._syncTooltip.bind(this));
this._index = index;
this._delegate = this; // needed for DND
@@ -204,7 +215,36 @@ let WorkspaceThumbnail = GObject.registerClass({
ws.activate(global.get_current_time());
}
+ _syncTooltip() {
+ if (this.hover) {
+ this._tooltip.text = Meta.prefs_get_workspace_name(this._index);
+ this._tooltip.opacity = 0;
+ this._tooltip.show();
+
+ const [stageX, stageY] = this.get_transformed_position();
+ const thumbWidth = this.allocation.get_width();
+ const thumbHeight = this.allocation.get_height();
+ const tipWidth = this._tooltip.width;
+ const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
+ const monitor = Main.layoutManager.findMonitorForActor(this);
+ const x = Math.min(
+ Math.max(stageX + xOffset, monitor.x),
+ monitor.x + monitor.width - tipWidth);
+ const y = stageY + thumbHeight + TOOLTIP_OFFSET;
+ this._tooltip.set_position(x, y);
+ }
+
+ Tweener.addTween(this._tooltip, {
+ opacity: this.hover ? 255 : 0,
+ time: TOOLTIP_ANIMATION_TIME / 1000,
+ transition: 'easeOutQuad',
+ onComplete: () => (this._tooltip.visible = this.hover),
+ });
+ }
+
_onDestroy() {
+ this._tooltip.destroy();
+
this._workspace.disconnect(this._windowAddedId);
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
--
2.44.0
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
When showing previews instead of the menu, the workspace names
don't appear anywhere. Some users care strongly about those, so
expose them as tooltip on hover.
---
extensions/window-list/workspaceIndicator.js | 40 ++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js
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;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
+const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
+const TOOLTIP_OFFSET = 6;
+const TOOLTIP_ANIMATION_TIME = 150;
+
let WindowPreview = GObject.registerClass({
GTypeName: 'WindowListWindowPreview'
}, class WindowPreview extends St.Button {
@@ -111,7 +115,14 @@ let WorkspaceThumbnail = GObject.registerClass({
y_fill: true
});
+ this._tooltip = new St.Label({
+ style_class: 'dash-label',
+ visible: false,
+ });
+ Main.uiGroup.add_child(this._tooltip);
+
this.connect('destroy', this._onDestroy.bind(this));
+ this.connect('notify::hover', this._syncTooltip.bind(this));
this._index = index;
this._delegate = this; // needed for DND
@@ -198,7 +209,36 @@ let WorkspaceThumbnail = GObject.registerClass({
ws.activate(global.get_current_time());
}
+ _syncTooltip() {
+ if (this.hover) {
+ this._tooltip.text = Meta.prefs_get_workspace_name(this._index);
+ this._tooltip.opacity = 0;
+ this._tooltip.show();
+
+ const [stageX, stageY] = this.get_transformed_position();
+ const thumbWidth = this.allocation.get_width();
+ const tipWidth = this._tooltip.width;
+ const tipHeight = this._tooltip.height;
+ const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
+ const monitor = Main.layoutManager.findMonitorForActor(this);
+ const x = Math.min(
+ Math.max(stageX + xOffset, monitor.x),
+ monitor.x + monitor.width - tipWidth);
+ const y = stageY - tipHeight - TOOLTIP_OFFSET;
+ this._tooltip.set_position(x, y);
+ }
+
+ Tweener.addTween(this._tooltip, {
+ opacity: this.hover ? 255 : 0,
+ time: TOOLTIP_ANIMATION_TIME / 1000,
+ transition: 'easeOutQuad',
+ onComplete: () => (this._tooltip.visible = this.hover),
+ });
+ }
+
_onDestroy() {
+ this._tooltip.destroy();
+
this._workspace.disconnect(this._windowAddedId);
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
--
2.44.0

View File

@ -1,267 +0,0 @@
From bcbf9709802e7644c5911615dabdee7d8ca07719 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 31 May 2021 19:29:34 +0200
Subject: [PATCH 1/3] desktopManager: Handle TOUCH_UPDATE/END events explicitly
for rubberband
These events need specific handling for Wayland, as we do not get emulated
pointer events in that platform. Handle these for rubberband selection.
---
extensions/desktop-icons/desktopManager.js | 67 ++++++++++++++++------
1 file changed, 48 insertions(+), 19 deletions(-)
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index 399aee0..a70cd98 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -130,26 +130,49 @@ var DesktopManager = GObject.registerClass({
}
[x, y] = event.get_coords();
this._updateRubberBand(x, y);
- let x0, y0, x1, y1;
- if (x >= this._rubberBandInitialX) {
- x0 = this._rubberBandInitialX;
- x1 = x;
- } else {
- x1 = this._rubberBandInitialX;
- x0 = x;
- }
- if (y >= this._rubberBandInitialY) {
- y0 = this._rubberBandInitialY;
- y1 = y;
- } else {
- y1 = this._rubberBandInitialY;
- y0 = y;
- }
- for (let [fileUri, fileItem] of this._fileItems) {
- fileItem.emit('selected', true, true,
- fileItem.intersectsWith(x0, y0, x1 - x0, y1 - y0));
- }
+ this._updateSelection(x, y);
});
+ this._rubberBandTouchId = global.stage.connect('touch-event', (actor, event) => {
+ // Let x11 pointer emulation do the job on X11
+ if (!Meta.is_wayland_compositor())
+ return Clutter.EVENT_PROPAGATE;
+ if (!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
+ return Clutter.EVENT_PROPAGATE;
+
+ if (event.type() == Clutter.EventType.TOUCH_END) {
+ this.endRubberBand();
+ return Clutter.EVENT_STOP;
+ } else if (event.type() == Clutter.EventType.TOUCH_UPDATE) {
+ [x, y] = event.get_coords();
+ this._updateRubberBand(x, y);
+ this._updateSelection(x, y);
+ return Clutter.EVENT_STOP;
+ }
+
+ return Clutter.EVENT_PROPAGATE;
+ });
+ }
+
+ _updateSelection(x, y) {
+ let x0, y0, x1, y1;
+ if (x >= this._rubberBandInitialX) {
+ x0 = this._rubberBandInitialX;
+ x1 = x;
+ } else {
+ x1 = this._rubberBandInitialX;
+ x0 = x;
+ }
+ if (y >= this._rubberBandInitialY) {
+ y0 = this._rubberBandInitialY;
+ y1 = y;
+ } else {
+ y1 = this._rubberBandInitialY;
+ y0 = y;
+ }
+ for (let [fileUri, fileItem] of this._fileItems) {
+ fileItem.emit('selected', true, true,
+ fileItem.intersectsWith(x0, y0, x1 - x0, y1 - y0));
+ }
}
endRubberBand() {
@@ -157,8 +180,10 @@ var DesktopManager = GObject.registerClass({
Extension.lockActivitiesButton = false;
this._grabHelper.ungrab();
global.stage.disconnect(this._rubberBandId);
+ global.stage.disconnect(this._rubberBandTouchId);
global.stage.disconnect(this._stageReleaseEventId);
this._rubberBandId = 0;
+ this._rubberBandTouchId = 0;
this._stageReleaseEventId = 0;
this._selection = new Set([...this._selection, ...this._currentSelection]);
@@ -739,6 +764,10 @@ var DesktopManager = GObject.registerClass({
global.stage.disconnect(this._rubberBandId);
this._rubberBandId = 0;
+ if (this._rubberBandTouchId)
+ global.stage.disconnect(this._rubberBandTouchId);
+ this._rubberBandTouchId = 0;
+
this._rubberBand.destroy();
if (this._queryFileInfoCancellable)
--
2.31.1
From 0733004ffeb517f7a80ff41e7181027e8b92b17e Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 31 May 2021 19:31:03 +0200
Subject: [PATCH 2/3] desktopGrid: Handle TOUCH_BEGIN events explicitly
We do not get pointer emulated events on Wayland, so touch events should
be handled explicitly there. Handle starting rubberband selection via
touch.
---
extensions/desktop-icons/desktopGrid.js | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js
index 94d2dfd..602fa7f 100644
--- a/extensions/desktop-icons/desktopGrid.js
+++ b/extensions/desktop-icons/desktopGrid.js
@@ -21,6 +21,7 @@ const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
+const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -123,6 +124,7 @@ var DesktopGrid = class {
() => this._backgroundDestroyed());
this._grid.connect('button-press-event', (actor, event) => this._onPressButton(actor, event));
+ this._grid.connect('touch-event', (actor, event) => this._onTouchEvent(actor, event));
this._grid.connect('key-press-event', this._onKeyPress.bind(this));
@@ -506,6 +508,23 @@ var DesktopGrid = class {
return Clutter.EVENT_PROPAGATE;
}
+ _onTouchEvent(actor, event) {
+ // Let x11 pointer emulation do the job on X11
+ if (!Meta.is_wayland_compositor())
+ return Clutter.EVENT_PROPAGATE;
+
+ if (event.type() == Clutter.EventType.TOUCH_BEGIN &&
+ global.display.is_pointer_emulating_sequence(event.get_event_sequence())) {
+ Extension.desktopManager.clearSelection();
+ let [x, y] = event.get_coords();
+ let [gridX, gridY] = this._grid.get_transformed_position();
+ Extension.desktopManager.startRubberBand(x, y, gridX, gridY);
+ return Clutter.EVENT_STOP;
+ }
+
+ return Clutter.EVENT_PROPAGATE;
+ }
+
_addDesktopBackgroundMenu() {
this.actor._desktopBackgroundMenu = this._createDesktopBackgroundMenu();
this.actor._desktopBackgroundManager = new PopupMenu.PopupMenuManager({ actor: this.actor });
--
2.31.1
From 2d978ffc58562c4f4d00b1afb03da58be3102e29 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 31 May 2021 19:31:50 +0200
Subject: [PATCH 3/3] fileItem: Handle (multi) touch explicitly via touch
events
Wayland does not get pointer emulated events, so we must handle TOUCH_BEGIN/
END here for file clicking/tapping to work there.
---
extensions/desktop-icons/fileItem.js | 34 ++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 143cb9b..1cb47e8 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -117,6 +117,7 @@ var FileItem = class {
this._container.connect('motion-event', (actor, event) => this._onMotion(actor, event));
this._container.connect('leave-event', (actor, event) => this._onLeave(actor, event));
this._container.connect('button-release-event', (actor, event) => this._onReleaseButton(actor, event));
+ this._container.connect('touch-event', (actor, event) => this._onTouchEvent(actor, event));
/* Set the metadata and update relevant UI */
this._updateMetadataFromFileInfo(fileInfo);
@@ -648,16 +649,26 @@ var FileItem = class {
DesktopIconsUtil.launchTerminal(this.file.get_path());
}
+ _eventButton(event) {
+ // Emulate button1 press on touch events
+ if (event.type() == Clutter.EventType.TOUCH_BEGIN ||
+ event.type() == Clutter.EventType.TOUCH_END ||
+ event.type() == Clutter.EventType.TOUCH_UPDATE)
+ return 1;
+
+ return event.get_button();
+ }
+
_updateClickState(event) {
let settings = Clutter.Settings.get_default();
- if ((event.get_button() == this._lastClickButton) &&
+ if ((this._eventButton(event) == this._lastClickButton) &&
((event.get_time() - this._lastClickTime) < settings.double_click_time))
this._clickCount++;
else
this._clickCount = 1;
this._lastClickTime = event.get_time();
- this._lastClickButton = event.get_button();
+ this._lastClickButton = this._eventButton(event);
}
_getClickCount() {
@@ -666,7 +677,7 @@ var FileItem = class {
_onPressButton(actor, event) {
this._updateClickState(event);
- let button = event.get_button();
+ let button = this._eventButton(event);
if (button == 3) {
if (!this.isSelected)
this.emit('selected', false, false, true);
@@ -725,7 +736,7 @@ var FileItem = class {
}
_onReleaseButton(actor, event) {
- let button = event.get_button();
+ let button = this._eventButton(event);
if (button == 1) {
// primaryButtonPressed is TRUE only if the user has pressed the button
// over an icon, and if (s)he has not started a drag&drop operation
@@ -744,6 +755,21 @@ var FileItem = class {
return Clutter.EVENT_PROPAGATE;
}
+ _onTouchEvent(actor, event) {
+ // Let x11 pointer emulation do the job on X11
+ if (!Meta.is_wayland_compositor())
+ return Clutter.EVENT_PROPAGATE;
+ if (!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
+ return Clutter.EVENT_PROPAGATE;
+
+ if (event.type() == Clutter.EventType.TOUCH_BEGIN)
+ this._onPressButton(actor, event);
+ else if (event.type() == Clutter.EventType.TOUCH_UPDATE)
+ this._onMotion(actor, event);
+ else if (event.type() == Clutter.EventType.TOUCH_END)
+ this._onReleaseButton(actor, event);
+ }
+
get savedCoordinates() {
return this._savedCoordinates;
}
--
2.31.1

View File

@ -1,27 +0,0 @@
[Desktop Entry]
Name[de]=Klassisch (Wayland Anzeige-Server)
Name[es]=Clásico (servidor gráfico Wayland)
Name[fr]=Classic (serveur affichage Wayland)
Name[it]=Classico (server grafico Wayland)
Name[ja]= (Wayland )
Name[ko]= (Wayland )
Name[pt_BR]=Clássico (servidor de exibição Wayland)
Name[ru]=Классический (дисплейный сервер Wayland)
Name[zh_CN]=Wayland
Name[zh_TW]=Wayland
Name=Classic (Wayland display server)
Comment[de]=Diese Sitzung meldet Sie in GNOME Classic an
Comment[es]=Esta sesión inicia GNOME clásico
Comment[fr]=Cette session vous connnecte à GNOME Classique
Comment[it]=Questa sessione si avvia con GNOME classico
Comment[ja]=GNOME
Comment[ko]=
Comment[pt_BR]=Essa sessão se inicia como GNOME Clássico
Comment[ru]=Данный сеанс использует классический рабочий стол GNOME
Comment[zh_CN]=GNOME
Comment[zh_TW]= GNOME Classic
Comment=This session logs you into GNOME Classic
Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session --session gnome-classic
TryExec=gnome-session
Type=Application
DesktopNames=GNOME-Classic;GNOME;

View File

@ -1,27 +0,0 @@
[Desktop Entry]
Name[de]=Klassisch (X11 Anzeige-Server)
Name[es]=Clásico (servidor gráfico X11)
Name[fr]=Classic (serveur affichage X11)
Name[it]=Classico (server grafico X11)
Name[ja]= (X11 )
Name[ko]= (X11 )
Name[pt_BR]=Clássico (servidor de exibição X11)
Name[ru]=Классический (дисплейный сервер X11)
Name[zh_CN]=X11
Name[zh_TW]=X11
Name=Classic (X11 display server)
Comment[de]=Diese Sitzung meldet Sie in GNOME Classic an
Comment[es]=Esta sesión inicia GNOME clásico
Comment[fr]=Cette session vous connnecte à GNOME Classique
Comment[it]=Questa sessione si avvia con GNOME classico
Comment[ja]=GNOME
Comment[ko]=
Comment[pt_BR]=Essa sessão se inicia como GNOME Clássico
Comment[ru]=Данный сеанс использует классический рабочий стол GNOME
Comment[zh_CN]=GNOME
Comment[zh_TW]= GNOME Classic
Comment=This session logs you into GNOME Classic
Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session --session gnome-classic
TryExec=gnome-session
Type=Application
DesktopNames=GNOME-Classic;GNOME;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +0,0 @@
From f8ec838485ae81cf2e8ab2b899ad4154c7c06fbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 21 Apr 2022 16:34:50 +0200
Subject: [PATCH 1/2] window-list: Fix primary button action on touch
If a click event was triggered via touch rather than a pointer
device, the button parameter is 0 rather than a mouse button
number.
Account for that to make sure that touch events are not misinterpreted
as right clicks.
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/146
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/233>
---
extensions/window-list/extension.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 1f854aa2..fedc4195 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -358,7 +358,7 @@ class WindowButton extends BaseButton {
return;
}
- if (button == 1)
+ if (!button || button === 1)
_minimizeOrActivateWindow(this.metaWindow);
else
_openMenu(this._contextMenu);
@@ -601,7 +601,7 @@ class AppButton extends BaseButton {
if (contextMenuWasOpen)
this._contextMenu.close();
- if (button == 1) {
+ if (!button || button === 1) {
if (menuWasOpen)
return;
--
2.36.1
From d3cf07f8065935736e8a79d06ec79c971c453453 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 5 May 2022 20:55:20 +0200
Subject: [PATCH 2/2] window-list: Open menu on long press
Right-click isn't available on touch, so implement long-press as
an alternative.
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/146
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/233>
---
extensions/window-list/extension.js | 45 +++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index fedc4195..0baaeecb 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -229,6 +229,9 @@ class BaseButton {
this.actor.connect('clicked', this._onClicked.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('popup-menu', this._onPopupMenu.bind(this));
+ this.actor.connect('button-press-event', this._onButtonPress.bind(this));
+ this.actor.connect('button-release-event', this._onButtonRelease.bind(this));
+ this.actor.connect('touch-event', this._onTouch.bind(this));
this._contextMenuManager = new PopupMenu.PopupMenuManager(this);
@@ -250,6 +253,48 @@ class BaseButton {
return this.actor.has_style_class_name('focused');
}
+ _setLongPressTimeout() {
+ if (this._longPressTimeoutId)
+ return;
+
+ const { longPressDuration } = Clutter.Settings.get_default();
+ this._longPressTimeoutId =
+ GLib.timeout_add(GLib.PRIORITY_DEFAULT, longPressDuration, () => {
+ delete this._longPressTimeoutId;
+
+ if (this._canOpenPopupMenu() && !this._contextMenu.isOpen)
+ _openMenu(this._contextMenu);
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ _removeLongPressTimeout() {
+ if (!this._longPressTimeoutId)
+ return;
+ GLib.source_remove(this._longPressTimeoutId);
+ delete this._longPressTimeoutId;
+ }
+
+ _onButtonPress(button, event) {
+ if (event.get_button() === 1)
+ this._setLongPressTimeout();
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ _onButtonRelease() {
+ this._removeLongPressTimeout();
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ _onTouch(event) {
+ const type = event.get_type();
+ if (type === Clutter.EventType.TOUCH_BEGIN)
+ this._setLongPressTimeout();
+ else if (type === Clutter.EventType.TOUCH_END)
+ this._removeLongPressTimeout();
+ return Clutter.EVENT_PROPAGATE;
+ }
+
activate() {
if (this.active)
return;
--
2.36.1

File diff suppressed because it is too large Load Diff

700
changelog Normal file
View File

@ -0,0 +1,700 @@
* Sun Mar 19 2023 Florian Müllner <fmuellner@redhat.com> - 44.0-1
- Update to 44.0
* Mon Mar 06 2023 Florian Müllner <fmuellner@redhat.com> - 44~rc-1
- Update to 44.rc
* Tue Feb 14 2023 Florian Müllner <fmuellner@redhat.com> - 44~beta-1
- Update to 44.beta
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 43.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Fri Oct 28 2022 Florian Müllner <fmuellner@redhat.com> - 43.1-2
- Adjust gnome-shell dependency
* Wed Oct 26 2022 Florian Müllner <fmuellner@redhat.com> - 43.1-1
- Update to 43.1
* Sat Sep 17 2022 Florian Müllner <fmuellner@redhat.com> - 43.0-1
- Update to 43.0
* Sun Sep 04 2022 Florian Müllner <fmuellner@redhat.com> - 43~rc-1
- Update to 43.rc
* Wed Aug 10 2022 Florian Müllner <fmuellner@redhat.com> - 43~beta-1
- Update to 43.beta
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 43~alpha-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Sun Jul 10 2022 Florian Müllner <fmuellner@redhat.com> - 43~alpha-1
- Update to 43.alpha
* Sat May 28 2022 Florian Müllner <fmuellner@redhat.com> - 42.2-1
- Update to 42.2
* Fri May 06 2022 Florian Müllner <fmuellner@redhat.com> - 42.1-1
- Update to 42.1
* Sun Mar 13 2022 Florian Müllner <fmuellner@redhat.com> - 42.0-1
- Update to 42.0
* Mon Mar 07 2022 Florian Müllner <fmuellner@redhat.com> - 42~rc-1
- Update to 42.rc
* Tue Feb 15 2022 Florian Müllner <fmuellner@redhat.com> - 42~beta-1
- Update to 42.beta
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 42~alpha-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Tue Jan 11 2022 Florian Müllner <fmuellner@redhat.com> - 42~alpha-1
- Update to 42.alpha
* Fri Oct 29 2021 Neal Gompa <ngompa@fedoraproject.org> - 41.0-2
- Backport GNOME Classic session for Wayland (#2015741)
* Sun Sep 19 2021 Florian Müllner <fmuellner@redhat.com> - 41.0-1
- Update to 41.0
* Mon Sep 06 2021 Florian Müllner <fmuellner@redhat.com> - 41~rc.1-1
- Update to 41.rc.1
* Sun Sep 05 2021 Florian Müllner <fmuellner@redhat.com> - 41~rc-1
- Update to 41.rc
* Wed Aug 18 2021 Florian Müllner <fmuellner@redhat.com> - 41~beta-1
- Update to 41.beta
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 40.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jul 12 2021 Florian Müllner <fmuellner@redhat.com> - 40.3-1
- Update to 40.3
* Thu Jun 10 2021 Florian Müllner <fmuellner@redhat.com> - 40.2-1
- Update to 40.2
* Thu May 13 2021 Florian Müllner <fmuellner@redhat.com> - 40.1-1
- Update to 40.1
* Sat Mar 20 2021 Florian Müllner <fmuellner@redhat.com> - 40.0-1
- Update to 40.0
* Mon Mar 15 2021 Florian Müllner <fmuellner@redhat.com> - 40.rc-1
- Update to 40.rc
* Wed Feb 24 2021 Florian Müllner <fmuellner@redhat.com> - 40.beta-1
- Update to 40.beta
* Thu Feb 18 2021 Kalev Lember <klember@redhat.com> - 40.0~alpha.1-6.20210212git9fa522c
- Fix typo in horizontal-workspaces obsoletes package name
* Thu Feb 18 2021 Kalev Lember <klember@redhat.com> - 40.0~alpha.1-5.20210212git9fa522c
- Fix obsoletes version
* Mon Feb 15 2021 Mohamed El Morabity <melmorabity@fedoraproject.org> - 40.0~alpha.1-4.20210212git9fa522c
- Add Obsoletes for horizontal-workspaces extension to fix upgrades to Fedora 34
(RHBZ #1928415)
* Fri Feb 12 2021 Florian Müllner <fmuellner@redhat.com> - 40.0~alpha.1-3.20210212git9fa522c
- Build snapshot of current upstream
- Drop horizontal-workspaces subpackage
(removed upstream, because horizontal workspaces are the default now)
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 40.0~alpha.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Jan 15 2021 Florian Müllner <fmuellner@redhat.com> - 40.0~alpha.1-1
- Update to 40.alpha.1
* Wed Dec 02 2020 Florian Müllner <fmuellner@redhat.com> - 40.0~alpha-1
- Update to 40.alpha
* Mon Oct 05 2020 Florian Müllner <fmuellner@redhat.com> - 3.38.1-1
- Update to 3.38.1
* Mon Sep 14 2020 Florian Müllner <fmuellner@redhat.com> - 3.38.0-1
- Update to 3.38.0
* Sun Sep 06 2020 Florian Müllner <fmuellner@redhat.com> - 3.37.92-1
- Update to 3.37.92
* Mon Aug 24 2020 Florian Müllner <fmuellner@redhat.com> - 3.37.91-1
- Update to 3.37.91
* Wed Aug 19 2020 Kalev Lember <klember@redhat.com> - 3.37.90-2
- Rebuild
* Tue Aug 11 2020 Florian Müllner <fmuellner@redhat.com> - 3.37.90-1
- Update to 3.37.90
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.37.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jul 07 2020 Florian Müllner <fmuellner@redhat.com> - 3.37.3-1
- Update to 3.37.3
* Wed Jun 03 2020 Florian Müllner <fmuellner@redhat.com> - 3.37.2-1
- Update to 3.37.2
* Thu Apr 30 2020 Florian Müllner <fmuellner@redhat.com> - 3.37.1-1
- Update to 3.37.1
* Tue Mar 31 2020 Florian Müllner <fmuellner@redhat.com> - 3.36.1-1
- Update to 3.36.1
* Sat Mar 07 2020 Florian Müllner <fmuellner@redhat.com> - 3.36.0-1
- Update to 3.36.0
* Sun Mar 01 2020 Florian Müllner <fmuellner@redhat.com> - 3.35.92-1
- Update to 3.35.92
* Tue Feb 18 2020 Florian Müllner <fmuellner@redhat.com> - 3.35.91-1
- Update to 3.35.91
* Thu Feb 06 2020 Florian Müllner <fmuellner@redhat.com> - 3.35.90-1
- Update to 3.35.90
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.35.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sun Jan 05 2020 Florian Müllner <fmuellner@redhat.com> - 3.35.3-1
- Update to 3.35.3
* Wed Dec 11 2019 Florian Müllner <fmuellner@redhat.com> - 3.35.2-1
- Update to 3.35.2
* Wed Oct 09 2019 Florian Müllner <fmuellner@redhat.com> - 3.34.1-1
- Update to 3.34.1
* Wed Sep 25 2019 Debarshi Ray <rishi@fedoraproject.org> - 3.34.0-2
- Unbreak the 'classic' GNOME session
* Mon Sep 09 2019 Florian Müllner <fmuellner@redhat.com> - 3.34.0-1
- Update to 3.34.0
* Wed Sep 04 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.92-1
- Update to 3.33.92
* Wed Aug 21 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.91-1
- Update to 3.33.91
* Sat Aug 10 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.90-1
- Update to 3.33.90
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.33.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sat Jul 20 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.4-1
- Update to 3.33.4
* Mon Jun 24 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.3-1
- Update to 3.33.3
* Wed May 22 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.2-1
- Update to 3.33.2
* Tue May 14 2019 Florian Müllner <fmuellner@redhat.com> - 3.33.1-1
- Update to 3.33.1
* Wed Apr 17 2019 Florian Müllner <fmuellner@redhat.com> - 3.32.1-1
- Update to 3.32.1
* Tue Mar 12 2019 Florian Müllner <fmuellner@redhat.com> - 3.32.0-1
- Update to 3.32.0
* Tue Mar 05 2019 Florian Müllner <fmuellner@redhat.com> - 3.31.92-1
- Update to 3.31.92
* Thu Feb 21 2019 Florian Müllner <fmuellner@redhat.com> - 3.31.91-1
- Update to 3.31.91
* Thu Feb 07 2019 Florian Müllner <fmuellner@redhat.com> - 3.31.90-1
- Update to 3.31.90
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.31.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Nov 21 2018 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.31.2-2
- Fix alternate-tab extension Obsoletes tag (RHBZ #1650519)
* Wed Nov 14 2018 Florian Müllner <fmuellner@redhat.com> - 3.31.2-1
- Update to 3.31.2
* Mon Oct 08 2018 Florian Müllner <fmuellner@redhat.com> - 3.30.1-1
- Update to 3.30.1
* Tue Sep 04 2018 Florian Müllner <fmuellner@redhat.com> - 3.30.0-1
- Update to 3.30.0
* Mon Aug 20 2018 Florian Müllner <fmuellner@redhat.com> - 3.29.91-1
- Update to 3.29.91
* Wed Aug 01 2018 Florian Müllner <fmuellner@redhat.com> - 3.29.90-1
- Update to 3.29.90
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.29.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu May 24 2018 Florian Müllner <fmuellner@redhat.com> - 3.29.2-1
- Update to 3.29.2
* Fri Apr 13 2018 Florian Müllner <fmuellner@redhat.com> - 3.28.1-1
- Update to 3.28.1
* Mon Mar 12 2018 Florian Müllner <fmuellner@redhat.com> - 3.28.0-1
- Update to 3.28.0
* Mon Mar 05 2018 Florian Müllner <fmuellner@redhat.com> - 3.27.92-1
- Update to 3.27.92
* Thu Feb 22 2018 Florian Müllner <fmuellner@redhat.com> - 3.27.91-1
- Update to 3.27.91
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.27.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Sat Jan 06 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 3.27.1-2
- Remove obsolete scriptlets
* Tue Oct 17 2017 Florian Müllner <fmuellner@redhat.com> - 3.27.1-1
- Update to 3.27.1
* Wed Oct 04 2017 Florian Müllner <fmuellner@redhat.com> - 3.26.1-1
- Update to 3.26.1
* Tue Sep 12 2017 Florian Müllner <fmuellner@redhat.com> - 3.26.0-1
- Update to 3.26.0
* Tue Aug 22 2017 Florian Müllner <fmuellner@redhat.com> - 3.25.91-1
- Update to 3.25.91
* Fri Aug 11 2017 Kevin Fenzi <kevin@scrye.com> - 3.25.90-2
- Rebuild with older working rpm
* Thu Aug 10 2017 Florian Müllner <fmuellner@redhat.com> - 3.25.90-1
- Update to 3.25.90
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.25.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Thu Jul 20 2017 Florian Müllner <fmuellner@redhat.com> - 3.25.4-1
- Update to 3.25.4
* Wed Jun 21 2017 Florian Müllner <fmuellner@redhat.com> - 3.25.3-1
- Update to 3.25.3
* Thu May 25 2017 Florian Müllner <fmuellner@redhat.com> - 3.25.2-1
- Update to 3.25.2
* Thu Apr 27 2017 Florian Müllner <fmuellner@redhat.com> - 3.25.1-1
- Update to 3.25.1
* Tue Apr 11 2017 Florian Müllner <fmuellner@redhat.com> - 3.24.1-1
- Update to 3.24.1
* Mon Mar 20 2017 Florian Müllner <fmuellner@redhat.com> - 3.24.0-1
- Update to 3.24.0
* Tue Mar 14 2017 Florian Müllner <fmuellner@redhat.com> - 3.23.92-1
- Update to 3.23.92
* Wed Mar 01 2017 Florian Müllner <fmuellner@redhat.com> - 3.23.91-1
- Update to 3.23.91
* Thu Feb 16 2017 Florian Müllner <fmuellner@redhat.com> - 3.23.90-1
- Update to 3.23.90
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.23.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Wed Nov 23 2016 Florian Müllner <fmuellner@redhat.com> - 3.23.2-1
- Update to 3.23.2
* Tue Oct 11 2016 Florian Müllner <fmuellner@redhat.com> - 3.22.1-1
- Update to 3.22.1
* Mon Sep 19 2016 Florian Müllner <fmuellner@redhat.com> - 3.22.0-1
- Update to 3.22.0
* Tue Sep 13 2016 Florian Müllner <fmuellner@redhat.com> - 3.21.92-1
- Update to 3.21.92
* Tue Aug 30 2016 Florian Müllner <fmuellner@redhat.com> - 3.21.91-1
- Update to 3.21.91
* Fri Aug 19 2016 Florian Müllner <fmuellner@redhat.com> - 3.21.90-1
- Update to 3.21.90
* Wed Jul 20 2016 Florian Müllner <fmuellner@redhat.com> - 3.21.4-1
- Update to 3.21.4
* Tue Jun 21 2016 Florian Müllner <fmuellner@redhat.com> - 3.21.3-1
- Update to 3.21.3
* Fri May 27 2016 Florian Müllner <fmuellner@redhat.com> - 3.21.2-1
- Update to 3.21.2
* Tue May 10 2016 Florian Müllner <fmuellner@redhat.com> - 3.20.1-1
- Update to 3.20.1
* Tue Mar 22 2016 Florian Müllner <fmuellner@redhat.com> - 3.20.0-1
- Update to 3.20.0
* Wed Mar 16 2016 Florian Müllner <fmuellner@redhat.com> - 3.19.92-1
- Update to 3.19.92
* Thu Mar 03 2016 Florian Müllner <fmuellner@redhat.com> - 3.19.91-1
- Update to 3.19.91
* Fri Feb 19 2016 Florian Müllner <fmuellner@redhat.com> - 3.19.90-1
- Update to 3.19.90
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 3.19.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Thu Jan 21 2016 Florian Müllner <fmuellner@redhat.com> - 3.19.4-1
- Update to 3.19.4
* Thu Dec 17 2015 Florian Müllner <fmuellner@redhat.com> - 3.19.3-1
- Update to 3.19.3
* Wed Nov 25 2015 Florian Müllner <fmuellner@redhat.com> - 3.19.2-1
- Update to 3.19.2
* Thu Oct 29 2015 Florian Müllner <fmuellner@redhat.com> - 3.19.1-1
- Update to 3.19.1
* Thu Oct 15 2015 Florian Müllner <fmuellner@redhat.com> - 3.18.1-1
- Update to 3.18.1
* Mon Sep 21 2015 Florian Müllner <fmuellner@redhat.com> - 3.18.0-1
- Update to 3.18.0
* Wed Sep 16 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.92-1
- Update to 3.17.92
* Thu Sep 03 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.91-1
- Update to 3.17.91
* Thu Aug 20 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.90-1
- Update to 3.17.90
* Wed Aug 19 2015 Kalev Lember <klember@redhat.com> - 3.17.4-2
- Don't own /usr/share/gnome-shell/extensions directory: now part of
gnome-shell package
* Thu Jul 23 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.4-1
- Update to 3.17.4
* Thu Jul 02 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.3-1
- Update to 3.17.3
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.17.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Wed May 27 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.2-1
- Update to 3.17.2
* Fri May 01 2015 Kalev Lember <kalevlember@gmail.com> - 3.17.1-2
- Add glib-compile-schemas rpm scripts for screenshot-window-sizer
* Thu Apr 30 2015 Florian Müllner <fmuellner@redhat.com> - 3.17.1-1
- Update to 3.17.1
* Tue Apr 14 2015 Florian Müllner <fmuellner@redhat.com> - 3.16.1-1
- Update to 3.16.1
* Mon Mar 23 2015 Florian Müllner <fmuellner@redhat.com> - 3.16.0-1
- Update to 3.16.0
* Tue Mar 17 2015 Florian Müllner <fmuellner@redhat.com> - 3.15.92-1
- Update to 3.15.92
* Thu Mar 05 2015 Kalev Lember <kalevlember@gmail.com> - 3.15.91-2
- Obsolete the systemMonitor extension that was dropped in 3.15.91
* Thu Mar 05 2015 Florian Müllner <fmuellner@redhat.com> - 3.15.91-1
- Update to 3.15.91
* Fri Feb 20 2015 Florian Müllner <fmuellner@redhat.com> - 3.15.90-1
- Update to 3.15.90
* Wed Jan 21 2015 Florian Müllner <fmuellner@redhat.com> - 3.15.4-1
- Update to 3.15.4
* Fri Dec 19 2014 Florian Müllner <fmuellner@redhat.com> - 3.15.3.1-1
- Update to 3.15.3.1
* Fri Dec 19 2014 Florian Müllner <fmuellner@redhat.com> - 3.15.3-1
- Update to 3.15.3
* Thu Nov 27 2014 Florian Müllner <fmuellner@redhat.com> - 3.15.2-1
- Update to 3.15.2
* Thu Oct 30 2014 Florian Müllner <fmuellner@redhat.com> - 3.15.1-1
- Update to 3.15.1
* Tue Oct 14 2014 Florian Müllner <fmuellner@redhat.com> - 3.14.1-1
- Update to 3.14.1
* Mon Sep 22 2014 Florian Müllner <fmuellner@redhat.com> - 3.14.0-1
- Update to 3.14.0
* Wed Sep 17 2014 Florian Müllner <fmuellner@redhat.com> - 3.13.92-1
- Update to 3.13.92
* Wed Sep 03 2014 Florian Müllner <fmuellner@redhat.com> - 3.13.91-1
- Update to 3.13.91
* Wed Aug 20 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.13.90-1
- Update to 3.13.90
* Thu Jul 24 2014 Kalev Lember <kalevlember@gmail.com> - 3.13.4-1
- Update to 3.13.4
* Thu Jun 26 2014 Richard Hughes <rhughes@redhat.com> - 3.13.3-1
- Update to 3.13.3
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.13.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Wed May 28 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.13.2-1
- Update to 3.13.2
* Fri May 02 2014 Kalev Lember <kalevlember@gmail.com> - 3.13.1-1
- Update to 3.13.1
* Tue Mar 25 2014 Richard Hughes <rhughes@redhat.com> - 3.12.0-1
- Update to 3.12.0
* Thu Mar 20 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.92-1
- Update to 3.11.92
* Thu Mar 06 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.91-1
- Update to 3.11.91
* Thu Feb 20 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.90-1
- Update to 3.11.90
* Wed Feb 05 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.5-1
- Update to 3.11.5
* Mon Feb 03 2014 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.4-1
- Update to 3.11.4
* Sun Dec 22 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.3-1
- Update to 3.11.3
* Wed Nov 13 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.11.2-1
- Update to 3.11.2
* Wed Oct 16 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.10.1-1
- Update to 3.10.1
* Tue Sep 24 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.10.0-1
- Update to 3.10.0
* Tue Sep 17 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.92-1
- Update to 3.9.92
* Tue Sep 03 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.91-1
- Update to 3.9.91
* Thu Aug 22 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.90-1
- Update to 3.9.90
- Drop xrand-indicator subpackage, no longer provided upstream
* Mon Aug 12 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.5-3
- Fix alternative-status-menu subpackage obsoleting
* Mon Aug 12 2013 Nils Philippsen <nils@redhat.com> - 3.9.5-2
- obsolete alternative-status-menu subpackage to allow smooth upgrades
* Sun Aug 04 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.5-1
- Update to 3.9.5
- Drop alternative-status-menu subpackage, no longer provided upstream
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.9.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Thu Jun 20 2013 Rahul Sundaram <sundaram@fedoraproject.org> - 3.9.3-1
- Update to 3.9.3
- Obsolete default-min-max and static workspaces extensions
- Use make_install macro
- Fix bogus dates in spec changelog
* Tue May 28 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.2-1
- Update to 3.9.2
* Fri May 10 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.9.1-1
- Update to 3.9.1
* Fri May 10 2013 Kalev Lember <kalevlember@gmail.com> - 3.8.1-3
- Obsolete gnome-applet-sensors
* Wed May 01 2013 Kalev Lember <kalevlember@gmail.com> - 3.8.1-2
- Obsolete a few more fallback mode packages
- Remove gnome-panel provides
* Tue Apr 16 2013 Matthias Clasen <mclasen@redhat.com> - 3.8.1-1
- Update to 3.8.1
* Tue Mar 26 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.8.0-1
- Update to 3.8.0
* Tue Mar 19 2013 Ray Strode <rstrode@redhat.com> 3.7.92-1
- Update to 3.7.92
* Tue Mar 05 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.7.91-1
- Update to 3.7.91
* Sat Mar 02 2013 Adel Gadllah <adel.gadllah@gmail.com> - 3.7.90-2
- Obsolete gnome-panel
* Fri Feb 22 2013 Kalev Lember <kalevlember@gmail.com> - 3.7.90-1
- Update to 3.7.90
* Thu Feb 07 2013 Kalev Lember <kalevlember@gmail.com> - 3.7.5.1-2
- Depend on gnome-shell 3.7.5, there's no 3.7.5.1
* Thu Feb 07 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.7.5.1-1
- Update to 3.7.5
- Enable new launch-new-instance and window-list extensions, and add them in the
classic-mode extension set
- Re-add places-menu in the classic-mode extension set
* Wed Jan 16 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.7.4-1
- Update to 3.7.4
- places-menu extension no longer part of the classic-mode extension set
* Tue Jan 01 2013 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.7.3-1
- Update to 3.7.3
- Enable new default-min-max and static-workspaces extensions
- Provide new subpackage gnome-classic-session
- Revamp summaries and descriptions
* Tue Oct 30 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.7.1-1
- Update to 3.7.1
- Drop dock and gajim extensions, no longer provided
* Tue Oct 30 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.6.1-1
- Update to 3.6.1
* Tue Oct 02 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.6.0-1
- Update to 3.6.0
* Thu Sep 06 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.5.91-1
- Update to 3.5.91
* Wed Aug 29 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.5.90-1
- Update to 3.5.90
* Sat Aug 11 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.5.5-1
- Update to 3.5.5
* Sun Jul 22 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.5.4-1
- Update to 3.5.4
* Wed Jul 18 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.5.2-1
- Update to 3.5.2
- Drop useless Provides/Obsoletes
* Sat Mar 24 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.4.0-1
- Update to 3.4.0
- Minor spec fixes
* Sat Mar 24 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.3.92-1
- Update to 3.3.92
* Tue Feb 28 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.3.90-1
- Update to 3.3.90
* Thu Feb 16 2012 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.3.5-1
- Update to 3.3.5
- Spec cleanup
* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
* Wed Nov 30 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.3.2-1
- Update to 3.3.2
* Wed Nov 30 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.2.1-1
- Update to 3.2.1
- Fix alternative-status-menu extension crash when login
* Wed Nov 09 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.2.0-2
- Fix dock and alternate-tab extensions
- Fix GNOME Shell version to work with GS 3.2.1
* Mon Oct 03 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.2.0-1
- Update to 3.2.0
* Mon Sep 26 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.1.91-3.20111001gite102c0c6
- Update to a newer git snapshot
- Fix GNOME Shell version to work with GS 3.2.0
- Add Requires on GS 3.2.0 or above to gnome-shell-common
* Wed Sep 14 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.1.91-2
- Enable xrandr-indicator and workspace-indicator extensions
* Mon Sep 12 2011 Michel Salim <salimma@fedoraproject.org> - 3.1.91-1
- Update to 3.1.91
- add more documentation
* Thu Sep 1 2011 Michel Salim <salimma@fedoraproject.org> - 3.1.4-3.20110830git6b5e3a3e
- Update to git snapshot, for gnome-shell 3.1.90
* Sun Aug 21 2011 Michel Salim <salimma@fedoraproject.org> - 3.1.4-2
- Enable apps-menu extension
- Spec cleanup
* Sun Aug 21 2011 Michel Salim <salimma@fedoraproject.org> - 3.1.4-1
- Update to 3.1.4
- Enable systemMonitor extension
- Prepare xrandr-indicator, commenting out since it does not seem to work yet
- Rename subpackages in line with new guidelines (# 715367)
- Sort subpackages in alphabetical order
* Sat May 28 2011 Timur Kristóf <venemo@fedoraproject.org> - 3.0.2-1.g63dd27cgit
- Update to a newer git snapshot
- Fix RHBZ bug #708230
- Enabled systemMonitor extension, but commented out since the requirements are not available
* Fri May 13 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.0.1-3.03660fgit
- Update to a newer git snapshot
- Enable native-window-placement extension
* Fri May 06 2011 Rahul Sundaram <sundaram@fedoraproject.org> - 3.0.1-2b20cbagit
- Fix description
* Thu May 5 2011 Elad Alfassa <elad@fedoraproject.org> - 3.0.1-1.b20cbagit
- Update to a newer git snapshot
- Enabled the places-menu extension
* Tue Apr 26 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.0.1-1.f016b9git
- Update to a newer git snapshot (post-3.0.1 release)
- Enable drive-menu extension
* Mon Apr 11 2011 Mohamed El Morabity <melmorabity@fedoraproject.org> - 3.0.0-5.6d56cfgit
- Enable auto-move-windows extension
* Mon Apr 11 2011 Rahul Sundaram <sundaram@fedoraproject.org> - 3.0.0-4.6d56cfgit
- Add glib2-devel as build requires
* Mon Apr 11 2011 Rahul Sundaram <sundaram@fedoraproject.org> - 3.0.0-3.6d56cfgit
- Tweak description
- Fix typo in configure
* Mon Apr 11 2011 Rahul Sundaram <sundaram@fedoraproject.org> - 3.0.0-2.6d56cfgit
- Added the user-theme extension
- Patch from Timur Kristóf <venemo@msn.com>
* Fri Apr 08 2011 Rahul Sundaram <sundaram@fedoraproject.org> - 3.0.0-1.6d56cfgit
- Make sure configure doesn't get called twice
* Fri Apr 08 2011 Rahul Sundaram <sundaram@fedoraproject.org> - 3.0.0-0.6d56cfgit
- Initial build

View File

@ -0,0 +1,187 @@
From 3de025618170bde16ab5e0bd7928ce387aa75350 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 28 Jan 2021 00:06:12 +0100
Subject: [PATCH 1/5] Add gesture-inhibitor extension
This extension may disable default GNOME Shell gestures.
---
extensions/gesture-inhibitor/extension.js | 79 +++++++++++++++++++
extensions/gesture-inhibitor/meson.build | 8 ++
extensions/gesture-inhibitor/metadata.json.in | 12 +++
...l.extensions.gesture-inhibitor.gschema.xml | 25 ++++++
meson.build | 7 +-
5 files changed, 130 insertions(+), 1 deletion(-)
create mode 100644 extensions/gesture-inhibitor/extension.js
create mode 100644 extensions/gesture-inhibitor/meson.build
create mode 100644 extensions/gesture-inhibitor/metadata.json.in
create mode 100644 extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
new file mode 100644
index 00000000..872020ba
--- /dev/null
+++ b/extensions/gesture-inhibitor/extension.js
@@ -0,0 +1,79 @@
+// SPDX-FileCopyrightText: 2021 Carlos Garnacho <carlosg@gnome.org>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+
+import Clutter from 'gi://Clutter';
+import Gio from 'gi://Gio';
+import St from 'gi://St';
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+import {AppSwitchAction} from 'resource:///org/gnome/shell/ui/windowManager.js';
+import {EdgeDragAction} from 'resource:///org/gnome/shell/ui/edgeDragAction.js';
+
+import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
+
+export default class GestureInhibitorExtension extends Extension {
+ constructor(metadata) {
+ super(metadata);
+
+ let actions = global.stage.get_actions();
+
+ actions.forEach(a => {
+ if (a instanceof AppSwitchAction)
+ this._appSwitch = a;
+ else if (a instanceof EdgeDragAction &&
+ a._side === St.Side.BOTTOM)
+ this._showOsk = a;
+ else if (a instanceof EdgeDragAction &&
+ a._side === St.Side.TOP)
+ this._unfullscreen = a;
+ });
+
+ this._map = [
+ {setting: 'overview', action: Main.overview._swipeTracker},
+ {setting: 'app-switch', action: this._appSwitch},
+ {setting: 'show-osk', action: this._showOsk},
+ {setting: 'unfullscreen', action: this._unfullscreen},
+ {setting: 'workspace-switch', action: Main.wm._workspaceAnimation._swipeTracker},
+ ];
+
+ this._enabledDesc = Object.getOwnPropertyDescriptor(
+ Clutter.ActorMeta.prototype, 'enabled');
+ }
+
+ _overrideEnabledSetter(obj, set) {
+ if (!(obj instanceof Clutter.ActorMeta))
+ return;
+
+ const desc = set
+ ? {...this._enabledDesc, set}
+ : {...this._enabledDesc};
+ Object.defineProperty(obj, 'enabled', desc);
+ }
+
+ enable() {
+ const settings = this.getSettings();
+
+ this._map.forEach(m => {
+ settings.bind(m.setting, m.action, 'enabled',
+ Gio.SettingsBindFlags.DEFAULT);
+
+ this._overrideEnabledSetter(m.action, function (value) {
+ if (settings.get_boolean(m.setting)) {
+ // eslint-disable-next-line no-invalid-this
+ this.set_enabled(value);
+ }
+ });
+ });
+ }
+
+ disable() {
+ this._map.forEach(m => {
+ Gio.Settings.unbind(m.action, 'enabled');
+ this._overrideEnabledSetter(m.action);
+ m.action.enabled = true;
+ });
+ }
+}
diff --git a/extensions/gesture-inhibitor/meson.build b/extensions/gesture-inhibitor/meson.build
new file mode 100644
index 00000000..fdad5cc8
--- /dev/null
+++ b/extensions/gesture-inhibitor/meson.build
@@ -0,0 +1,8 @@
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
+
+# extension_sources += files('prefs.js')
+extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/gesture-inhibitor/metadata.json.in b/extensions/gesture-inhibitor/metadata.json.in
new file mode 100644
index 00000000..37d6a117
--- /dev/null
+++ b/extensions/gesture-inhibitor/metadata.json.in
@@ -0,0 +1,12 @@
+{
+ "uuid": "@uuid@",
+ "extension-id": "@extension_id@",
+ "settings-schema": "@gschemaname@",
+ "gettext-domain": "@gettext_domain@",
+ "name": "Gesture Inhibitor",
+ "description": "Makes touchscreen gestures optional.",
+ "shell-version": [ "@shell_current@" ],
+ "original-authors": [ "cgarnach@redhat.com" ],
+ "url": "@url@"
+}
+
diff --git a/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml b/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
new file mode 100644
index 00000000..b06d027a
--- /dev/null
+++ b/extensions/gesture-inhibitor/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
@@ -0,0 +1,25 @@
+<schemalist>
+ <schema id="org.gnome.shell.extensions.gesture-inhibitor" path="/org/gnome/shell/extensions/gesture-inhibitor/">
+ <key name="show-osk" type="b">
+ <default>true</default>
+ <summary>Show OSK gesture</summary>
+ </key>
+ <key name="overview" type="b">
+ <default>true</default>
+ <summary>Show Overview gesture</summary>
+ </key>
+ <key name="app-switch" type="b">
+ <default>true</default>
+ <summary>Application switch gesture</summary>
+ </key>
+ <key name="workspace-switch" type="b">
+ <default>true</default>
+ <summary>Workspace switch gesture</summary>
+ </key>
+ <key name="unfullscreen" type="b">
+ <default>true</default>
+ <summary>Unfullscreen gesture</summary>
+ </key>
+ </schema>
+</schemalist>
+
diff --git a/meson.build b/meson.build
index 873da7bd..f21d0410 100644
--- a/meson.build
+++ b/meson.build
@@ -50,7 +50,12 @@ default_extensions += [
]
all_extensions = default_extensions
-all_extensions += ['auto-move-windows', 'native-window-placement', 'user-theme']
+all_extensions += [
+ 'auto-move-windows',
+ 'gesture-inhibitor',
+ 'native-window-placement',
+ 'user-theme',
+]
enabled_extensions = get_option('enable_extensions')
--
2.47.1

View File

@ -0,0 +1,479 @@
From a30e0f7d6e93eb84f0864574b0da9816c0bbec83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 2 Dec 2021 19:39:50 +0100
Subject: [PATCH 2/5] Add classification-banner
---
extensions/classification-banner/extension.js | 163 +++++++++++++++
extensions/classification-banner/meson.build | 9 +
.../classification-banner/metadata.json.in | 11 +
...tensions.classification-banner.gschema.xml | 29 +++
extensions/classification-banner/prefs.js | 192 ++++++++++++++++++
.../classification-banner/stylesheet.css | 3 +
meson.build | 1 +
7 files changed, 408 insertions(+)
create mode 100644 extensions/classification-banner/extension.js
create mode 100644 extensions/classification-banner/meson.build
create mode 100644 extensions/classification-banner/metadata.json.in
create mode 100644 extensions/classification-banner/org.gnome.shell.extensions.classification-banner.gschema.xml
create mode 100644 extensions/classification-banner/prefs.js
create mode 100644 extensions/classification-banner/stylesheet.css
diff --git a/extensions/classification-banner/extension.js b/extensions/classification-banner/extension.js
new file mode 100644
index 00000000..32c7d794
--- /dev/null
+++ b/extensions/classification-banner/extension.js
@@ -0,0 +1,163 @@
+// SPDX-FileCopyrightText: 2021 Florian Müllner <fmuellner@gnome.org>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+import Clutter from 'gi://Clutter';
+import Cogl from 'gi://Cogl';
+import Gio from 'gi://Gio';
+import GLib from 'gi://GLib';
+import GObject from 'gi://GObject';
+import Shell from 'gi://Shell';
+import St from 'gi://St';
+
+import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+import {MonitorConstraint} from 'resource:///org/gnome/shell/ui/layout.js';
+
+class ClassificationBanner extends Clutter.Actor {
+ static {
+ GObject.registerClass(this);
+ }
+
+ #topBanner;
+ #bottomBanner;
+ #monitorConstraint;
+ #settings;
+
+ constructor(index, settings) {
+ const constraint = new MonitorConstraint({index});
+ super({
+ layout_manager: new Clutter.BinLayout(),
+ constraints: constraint,
+ });
+ this.#monitorConstraint = constraint;
+
+ Shell.util_set_hidden_from_pick(this, true);
+
+ this.#settings = settings;
+
+ this.#topBanner = new St.BoxLayout({
+ style_class: 'classification-banner',
+ x_expand: true,
+ y_expand: true,
+ y_align: Clutter.ActorAlign.START,
+ });
+ this.add_child(this.#topBanner);
+ this.#settings.bind('top-banner',
+ this.#topBanner, 'visible',
+ Gio.SettingsBindFlags.GET);
+
+ this.#bottomBanner = new St.BoxLayout({
+ style_class: 'classification-banner',
+ x_expand: true,
+ y_expand: true,
+ y_align: Clutter.ActorAlign.END,
+ });
+ this.add_child(this.#bottomBanner);
+ this.#settings.bind('bottom-banner',
+ this.#bottomBanner, 'visible',
+ Gio.SettingsBindFlags.GET);
+
+ for (const banner of [this.#topBanner, this.#bottomBanner]) {
+ const label = new St.Label({
+ style_class: 'classification-message',
+ x_align: Clutter.ActorAlign.CENTER,
+ x_expand: true,
+ });
+ banner.add_child(label);
+
+ this.#settings.bind('message',
+ label, 'text',
+ Gio.SettingsBindFlags.GET);
+ }
+
+ const hostLabel = new St.Label({
+ style_class: 'classification-system-info',
+ text: GLib.get_host_name(),
+ });
+ this.#topBanner.insert_child_at_index(hostLabel, 0);
+ this.#settings.bind('system-info',
+ hostLabel, 'visible',
+ Gio.SettingsBindFlags.GET);
+
+ const userLabel = new St.Label({
+ style_class: 'classification-system-info',
+ text: GLib.get_user_name(),
+ });
+ this.#topBanner.add_child(userLabel);
+ this.#settings.bind('system-info',
+ userLabel, 'visible',
+ Gio.SettingsBindFlags.GET);
+
+ global.display.connectObject('in-fullscreen-changed',
+ () => this.#updateMonitorConstraint(), this);
+ this.#updateMonitorConstraint();
+
+ this.#settings.connectObject(
+ 'changed::color', () => this.#updateStyles(),
+ 'changed::background-color', () => this.#updateStyles(),
+ this);
+ this.#updateStyles();
+ }
+
+ #getColorSetting(key) {
+ const str = this.#settings.get_string(key);
+ const [valid, color] = Cogl.Color.from_string(str);
+ if (!valid)
+ return '';
+ const {red, green, blue, alpha} = color;
+ return `${key}: rgba(${red},${green},${blue},${alpha / 255});`;
+ }
+
+ #updateMonitorConstraint() {
+ const {index} = this.#monitorConstraint;
+ this.#monitorConstraint.work_area =
+ !global.display.get_monitor_in_fullscreen(index);
+ }
+
+ #updateStyles() {
+ const bgStyle = this.#getColorSetting('background-color');
+ const fgStyle = this.#getColorSetting('color');
+ const style = `${bgStyle}${fgStyle}`;
+ this.#topBanner.set({style});
+ this.#bottomBanner.set({style});
+ }
+}
+
+export default class ClassificationBannerExtension extends Extension {
+ #banners = [];
+
+ #updateMonitors() {
+ const {monitors, panelBox, primaryIndex} = Main.layoutManager;
+ if (monitors.length !== this.#banners.length) {
+ this.#clearBanners();
+
+ const settings = this.getSettings();
+ for (let i = 0; i < monitors.length; i++) {
+ const banner = new ClassificationBanner(i, settings);
+ Main.uiGroup.add_child(banner);
+ this.#banners.push(banner);
+ }
+ }
+
+ const primaryBanner = this.#banners[primaryIndex];
+ if (primaryBanner)
+ Main.uiGroup.set_child_below_sibling(primaryBanner, panelBox);
+ }
+
+ #clearBanners() {
+ this.#banners.forEach(b => b.destroy());
+ this.#banners = [];
+ }
+
+ enable() {
+ Main.layoutManager.connectObject('monitors-changed',
+ () => this.#updateMonitors(), this);
+ this.#updateMonitors();
+ }
+
+ disable() {
+ Main.layoutManager.disconnectObject(this);
+ this.#clearBanners();
+ }
+}
diff --git a/extensions/classification-banner/meson.build b/extensions/classification-banner/meson.build
new file mode 100644
index 00000000..aa943741
--- /dev/null
+++ b/extensions/classification-banner/meson.build
@@ -0,0 +1,9 @@
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
+extension_data += files('stylesheet.css')
+
+extension_sources += files('prefs.js')
+extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/classification-banner/metadata.json.in b/extensions/classification-banner/metadata.json.in
new file mode 100644
index 00000000..f93b1a2d
--- /dev/null
+++ b/extensions/classification-banner/metadata.json.in
@@ -0,0 +1,11 @@
+{
+"extension-id": "@extension_id@",
+"uuid": "@uuid@",
+"settings-schema": "@gschemaname@",
+"gettext-domain": "@gettext_domain@",
+"name": "Classification Banner",
+"description": "Display classification level banner",
+"shell-version": [ "@shell_current@" ],
+"session-modes": [ "gdm", "unlock-dialog", "user" ],
+"url": "@url@"
+}
diff --git a/extensions/classification-banner/org.gnome.shell.extensions.classification-banner.gschema.xml b/extensions/classification-banner/org.gnome.shell.extensions.classification-banner.gschema.xml
new file mode 100644
index 00000000..0314ef60
--- /dev/null
+++ b/extensions/classification-banner/org.gnome.shell.extensions.classification-banner.gschema.xml
@@ -0,0 +1,29 @@
+<schemalist gettext-domain="gnome-shell-extensions">
+ <schema id="org.gnome.shell.extensions.classification-banner"
+ path="/org/gnome/shell/extensions/classification-banner/">
+ <key name="top-banner" type="b">
+ <default>true</default>
+ <summary>Show a banner at the top</summary>
+ </key>
+ <key name="bottom-banner" type="b">
+ <default>true</default>
+ <summary>Show a banner at the bottom</summary>
+ </key>
+ <key name="message" type="s">
+ <default>"UNCLASSIFIED"</default>
+ <summary>classification message</summary>
+ </key>
+ <key name="color" type="s">
+ <default>"#fff"</default>
+ <summary>text color</summary>
+ </key>
+ <key name="background-color" type="s">
+ <default>"rgba(0,122,51,0.75)"</default>
+ <summary>background color</summary>
+ </key>
+ <key name="system-info" type="b">
+ <default>false</default>
+ <summary>Include system info in top banner</summary>
+ </key>
+ </schema>
+</schemalist>
diff --git a/extensions/classification-banner/prefs.js b/extensions/classification-banner/prefs.js
new file mode 100644
index 00000000..dc73ddae
--- /dev/null
+++ b/extensions/classification-banner/prefs.js
@@ -0,0 +1,192 @@
+import Adw from 'gi://Adw';
+import Gdk from 'gi://Gdk';
+import Gio from 'gi://Gio';
+import GObject from 'gi://GObject';
+import Gtk from 'gi://Gtk';
+
+import {ExtensionPreferences, gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
+
+class GenericPrefs extends Adw.PreferencesGroup {
+ static {
+ GObject.registerClass(this);
+ }
+
+ #actionGroup = new Gio.SimpleActionGroup();
+ #settings;
+
+ constructor(settings) {
+ super();
+
+ this.#settings = settings;
+ this.insert_action_group('options', this.#actionGroup);
+
+ this.#actionGroup.add_action(settings.create_action('top-banner'));
+ this.#actionGroup.add_action(settings.create_action('bottom-banner'));
+ this.#actionGroup.add_action(settings.create_action('system-info'));
+
+ this.add(new Adw.SwitchRow({
+ title: _('Top Banner'),
+ action_name: 'options.top-banner',
+ }));
+
+ this.add(new Adw.SwitchRow({
+ title: _('Bottom Banner'),
+ action_name: 'options.bottom-banner',
+ }));
+
+ this.add(new Adw.SwitchRow({
+ title: _('System Info'),
+ action_name: 'options.system-info',
+ }));
+ }
+}
+
+class BannerPreset extends GObject.Object {
+ static [GObject.properties] = {
+ 'message': GObject.ParamSpec.string(
+ 'message', 'message', 'message',
+ GObject.ParamFlags.READWRITE,
+ null),
+ 'color': GObject.ParamSpec.string(
+ 'color', 'color', 'color',
+ GObject.ParamFlags.READWRITE,
+ null),
+ 'background-color': GObject.ParamSpec.string(
+ 'background-color', 'background-color', 'background-color',
+ GObject.ParamFlags.READWRITE,
+ null),
+ };
+
+ static {
+ GObject.registerClass(this);
+ }
+}
+
+class AppearancePrefs extends Adw.PreferencesGroup {
+ static {
+ GObject.registerClass(this);
+ }
+
+ #settings;
+
+ constructor(settings) {
+ super();
+
+ this.#settings = settings;
+
+ const model = new Gio.ListStore({item_type: BannerPreset.$gtype});
+ model.append(new BannerPreset({
+ message: 'UNCLASSIFIED',
+ color: '#fff',
+ background_color: 'rgba(0, 122, 51, 0.75)',
+ }));
+ model.append(new BannerPreset({
+ message: 'CONFIDENTIAL',
+ color: '#fff',
+ background_color: 'rgba(0, 51, 160, 0.75)',
+ }));
+ model.append(new BannerPreset({
+ message: 'SECRET',
+ color: '#fff',
+ background_color: 'rgba(200, 16, 46, 0.75)',
+ }));
+ model.append(new BannerPreset({
+ message: 'TOP SECRET',
+ color: '#fff',
+ background_color: 'rgba(255, 103, 31, 0.75)',
+ }));
+ model.append(new BannerPreset({
+ message: 'TOP SECRET//SCI',
+ color: '#000',
+ background_color: 'rgba(247, 234, 72, 0.75)',
+ }));
+
+ let row, activatableWidget;
+ row = this.#createPresetsRow(model);
+ row.connect('notify::selected-item', comboRow => {
+ const {message, color, backgroundColor} = comboRow.selected_item;
+ this.#settings.set_string('message', message);
+ this.#settings.set_string('color', color);
+ this.#settings.set_string('background-color', backgroundColor);
+ });
+ this.add(row);
+
+ activatableWidget = new Gtk.Entry({
+ valign: Gtk.Align.CENTER,
+ });
+ this.#settings.bind('message',
+ activatableWidget, 'text',
+ Gio.SettingsBindFlags.DEFAULT);
+ row = new Adw.ActionRow({title: _('Message'), activatableWidget});
+ row.add_suffix(activatableWidget);
+ this.add(row);
+
+ activatableWidget = this.#createColorButton('background-color', {
+ use_alpha: true,
+ });
+ row = new Adw.ActionRow({title: _('Background color'), activatableWidget});
+ row.add_suffix(activatableWidget);
+ this.add(row);
+
+ activatableWidget = this.#createColorButton('color');
+ row = new Adw.ActionRow({title: _('Text color'), activatableWidget});
+ row.add_suffix(activatableWidget);
+ this.add(row);
+ }
+
+ #createPresetsRow(model) {
+ const listFactory = new Gtk.SignalListItemFactory();
+ listFactory.connect('setup',
+ (f, item) => item.set_child(new Gtk.Label()));
+ listFactory.connect('bind', (f, listItem) => {
+ const {child, item} = listItem;
+
+ const provider = new Gtk.CssProvider();
+ provider.load_from_data(`* {
+ border-radius: 99px;
+ padding: 6px;
+ color: ${item.color};
+ background-color: ${item.background_color};
+ }`, -1);
+ child.get_style_context().add_provider(provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+ child.label = item.message;
+ });
+
+ return new Adw.ComboRow({
+ title: _('Presets'),
+ model,
+ listFactory,
+ expression: Gtk.ConstantExpression.new_for_value(''),
+ });
+ }
+
+ #createColorButton(key, params = {}) {
+ const rgba = new Gdk.RGBA();
+ rgba.parse(this.#settings.get_string(key));
+
+ const button = new Gtk.ColorButton({
+ ...params,
+ rgba,
+ valign: Gtk.Align.CENTER,
+ });
+ this.#settings.connect(`changed::${key}`, () => {
+ const newRgba = new Gdk.RGBA();
+ newRgba.parse(this.#settings.get_string(key));
+ if (!newRgba.equal(button.rgba))
+ button.set({rgba: newRgba});
+ });
+ button.connect('notify::rgba',
+ () => this.#settings.set_string(key, button.rgba.to_string()));
+ return button;
+ }
+}
+
+export default class ClassificationPrefs extends ExtensionPreferences {
+ getPreferencesWidget() {
+ const page = new Adw.PreferencesPage();
+ page.add(new AppearancePrefs(this.getSettings()));
+ page.add(new GenericPrefs(this.getSettings()));
+ return page;
+ }
+}
diff --git a/extensions/classification-banner/stylesheet.css b/extensions/classification-banner/stylesheet.css
new file mode 100644
index 00000000..fb6a697e
--- /dev/null
+++ b/extensions/classification-banner/stylesheet.css
@@ -0,0 +1,3 @@
+.classification-system-info { padding: 0 24px; }
+.classification-message { font-weight: bold; }
+.classification-banner { font-size: 0.9em; }
diff --git a/meson.build b/meson.build
index f21d0410..0f12b451 100644
--- a/meson.build
+++ b/meson.build
@@ -52,6 +52,7 @@ default_extensions += [
all_extensions = default_extensions
all_extensions += [
'auto-move-windows',
+ 'classification-banner',
'gesture-inhibitor',
'native-window-placement',
'user-theme',
--
2.47.1

View File

@ -0,0 +1,878 @@
From 7b2627e3110daa4cb98a67a94f7ffa7361569003 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 24 Aug 2021 15:03:57 -0400
Subject: [PATCH 3/5] Add heads-up-display
---
extensions/heads-up-display/extension.js | 404 ++++++++++++++++++
extensions/heads-up-display/headsUpMessage.js | 166 +++++++
extensions/heads-up-display/meson.build | 13 +
extensions/heads-up-display/metadata.json.in | 12 +
...ll.extensions.heads-up-display.gschema.xml | 60 +++
extensions/heads-up-display/prefs.js | 92 ++++
extensions/heads-up-display/stylesheet.css | 38 ++
meson.build | 1 +
po/POTFILES.in | 1 +
9 files changed, 787 insertions(+)
create mode 100644 extensions/heads-up-display/extension.js
create mode 100644 extensions/heads-up-display/headsUpMessage.js
create mode 100644 extensions/heads-up-display/meson.build
create mode 100644 extensions/heads-up-display/metadata.json.in
create mode 100644 extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml
create mode 100644 extensions/heads-up-display/prefs.js
create mode 100644 extensions/heads-up-display/stylesheet.css
diff --git a/extensions/heads-up-display/extension.js b/extensions/heads-up-display/extension.js
new file mode 100644
index 00000000..a71b5925
--- /dev/null
+++ b/extensions/heads-up-display/extension.js
@@ -0,0 +1,404 @@
+// SPDX-FileCopyrightText: 2021 Ray Strode <rstrode@redhat.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+import GObject from 'gi://GObject';
+import Meta from 'gi://Meta';
+import Mtk from 'gi://Mtk';
+
+import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+import {MonitorConstraint} from 'resource:///org/gnome/shell/ui/layout.js';
+
+import {HeadsUpMessage} from './headsUpMessage.js';
+
+var HeadsUpConstraint = GObject.registerClass({
+ Properties: {
+ 'offset': GObject.ParamSpec.int(
+ 'offset', 'Offset', 'offset',
+ GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
+ -1, 0, -1),
+ 'active': GObject.ParamSpec.boolean(
+ 'active', 'Active', 'active',
+ GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
+ true),
+ },
+}, class HeadsUpConstraint extends MonitorConstraint {
+ constructor(props) {
+ super(props);
+ this._offset = 0;
+ this._active = true;
+ }
+
+ get offset() {
+ return this._offset;
+ }
+
+ set offset(o) {
+ this._offset = o;
+ }
+
+ get active() {
+ return this._active;
+ }
+
+ set active(a) {
+ this._active = a;
+ }
+
+ vfunc_update_allocation(actor, actorBox) {
+ if (!Main.layoutManager.primaryMonitor)
+ return;
+
+ if (!this.active)
+ return;
+
+ if (actor.has_allocation())
+ return;
+
+ const workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+ actorBox.init_rect(workArea.x, workArea.y + this.offset, workArea.width, workArea.height - this.offset);
+ }
+});
+
+export default class HeadsUpDisplayExtension extends Extension {
+ enable() {
+ this._settings = this.getSettings('org.gnome.shell.extensions.heads-up-display');
+ this._settings.connectObject('changed',
+ () => this._updateMessage(), this);
+
+ this._idleMonitor = global.backend.get_core_idle_monitor();
+ this._messageInhibitedUntilIdle = false;
+ global.window_manager.connectObject('map',
+ this._onWindowMap.bind(this), this);
+
+ if (Main.layoutManager._startingUp)
+ Main.layoutManager.connectObject('startup-complete', () => this._onStartupComplete(), this);
+ else
+ this._onStartupComplete();
+ }
+
+ disable() {
+ this._dismissMessage();
+
+ this._stopWatchingForIdle();
+
+ Main.sessionMode.disconnectObject(this);
+ Main.overview.disconnectObject(this);
+ Main.layoutManager.panelBox.disconnectObject(this);
+ Main.layoutManager.disconnectObject(this);
+ global.window_manager.disconnectObject(this);
+
+ if (this._screenShieldVisibleId) {
+ Main.screenShield._dialog._clock.disconnect(this._screenShieldVisibleId);
+ this._screenShieldVisibleId = 0;
+ }
+
+ this._settings.disconnectObject(this);
+ delete this._settings;
+ }
+
+ _onWindowMap(shellwm, actor) {
+ const windowObject = actor.meta_window;
+ const windowType = windowObject.get_window_type();
+
+ if (windowType !== Meta.WindowType.NORMAL)
+ return;
+
+ if (!this._message || !this._message.visible)
+ return;
+
+ const messageRect = new Mtk.Rectangle({
+ x: this._message.x,
+ y: this._message.y,
+ width: this._message.width,
+ height: this._message.height,
+ });
+ const windowRect = windowObject.get_frame_rect();
+
+ if (windowRect.intersect(messageRect))
+ windowObject.move_frame(false, windowRect.x, this._message.y + this._message.height);
+ }
+
+ _onStartupComplete() {
+ Main.overview.connectObject(
+ 'showing', () => this._updateMessage(),
+ 'hidden', () => this._updateMessage(),
+ this);
+ Main.layoutManager.panelBox.connectObject('notify::visible',
+ () => this._updateMessage(), this);
+ Main.sessionMode.connectObject('updated',
+ () => this._onSessionModeUpdated(), this);
+
+ this._updateMessage();
+ }
+
+ _onSessionModeUpdated() {
+ if (!Main.sessionMode.hasWindows)
+ this._messageInhibitedUntilIdle = false;
+
+ const dialog = Main.screenShield._dialog;
+ if (!Main.sessionMode.isGreeter && dialog && !this._screenShieldVisibleId) {
+ this._screenShieldVisibleId = dialog._clock.connect('notify::visible', this._updateMessage.bind(this));
+ this._screenShieldDestroyId = dialog._clock.connect('destroy', () => {
+ this._screenShieldVisibleId = 0;
+ this._screenShieldDestroyId = 0;
+ });
+ }
+ this._updateMessage();
+ }
+
+ _stopWatchingForIdle() {
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+
+ if (this._idleTimeoutChangedId) {
+ this._settings.disconnect(this._idleTimeoutChangedId);
+ this._idleTimeoutChangedId = 0;
+ }
+ }
+
+ _onIdleTimeoutChanged() {
+ this._stopWatchingForIdle();
+ this._messageInhibitedUntilIdle = false;
+ }
+
+ _onUserIdle() {
+ this._messageInhibitedUntilIdle = false;
+ this._updateMessage();
+ }
+
+ _watchForIdle() {
+ this._stopWatchingForIdle();
+
+ const idleTimeout = this._settings.get_uint('idle-timeout');
+
+ this._idleTimeoutChangedId =
+ this._settings.connect('changed::idle-timeout',
+ this._onIdleTimeoutChanged.bind(this));
+ this._idleWatchId = this._idleMonitor.add_idle_watch(idleTimeout * 1000,
+ this._onUserIdle.bind(this));
+ }
+
+ _updateMessage() {
+ if (this._messageInhibitedUntilIdle) {
+ if (this._message)
+ this._dismissMessage();
+ return;
+ }
+
+ this._stopWatchingForIdle();
+
+ if (Main.sessionMode.hasOverview && Main.overview.visible) {
+ this._dismissMessage();
+ return;
+ }
+
+ if (!Main.layoutManager.panelBox.visible) {
+ this._dismissMessage();
+ return;
+ }
+
+ let supportedModes = [];
+
+ if (this._settings.get_boolean('show-when-unlocked'))
+ supportedModes.push('user');
+
+ if (this._settings.get_boolean('show-when-unlocking') ||
+ this._settings.get_boolean('show-when-locked'))
+ supportedModes.push('unlock-dialog');
+
+ if (this._settings.get_boolean('show-on-login-screen'))
+ supportedModes.push('gdm');
+
+ if (!supportedModes.includes(Main.sessionMode.currentMode) &&
+ !supportedModes.includes(Main.sessionMode.parentMode)) {
+ this._dismissMessage();
+ return;
+ }
+
+ if (Main.sessionMode.currentMode === 'unlock-dialog') {
+ const dialog = Main.screenShield._dialog;
+ if (!this._settings.get_boolean('show-when-locked')) {
+ if (dialog._clock.visible) {
+ this._dismissMessage();
+ return;
+ }
+ }
+
+ if (!this._settings.get_boolean('show-when-unlocking')) {
+ if (!dialog._clock.visible) {
+ this._dismissMessage();
+ return;
+ }
+ }
+ }
+
+ const heading = this._settings.get_string('message-heading');
+ const body = this._settings.get_string('message-body');
+
+ if (!heading && !body) {
+ this._dismissMessage();
+ return;
+ }
+
+ if (!this._message) {
+ this._message = new HeadsUpMessage(heading, body);
+
+ this._message.connect('notify::allocation', this._adaptSessionForMessage.bind(this));
+ this._message.connect('clicked', this._onMessageClicked.bind(this));
+ }
+
+ this._message.reactive = true;
+ this._message.track_hover = true;
+
+ this._message.setHeading(heading);
+ this._message.setBody(body);
+
+ if (!Main.sessionMode.hasWindows) {
+ this._message.track_hover = false;
+ this._message.reactive = false;
+ }
+ }
+
+ _onMessageClicked() {
+ if (!Main.sessionMode.hasWindows)
+ return;
+
+ this._watchForIdle();
+ this._messageInhibitedUntilIdle = true;
+ this._updateMessage();
+ }
+
+ _dismissMessage() {
+ if (!this._message)
+ return;
+
+ this._message.visible = false;
+ this._message.destroy();
+ this._message = null;
+ this._resetMessageTray();
+ this._resetLoginDialog();
+ }
+
+ _resetMessageTray() {
+ if (!Main.messageTray)
+ return;
+
+ if (this._updateMessageTrayId) {
+ global.stage.disconnect(this._updateMessageTrayId);
+ this._updateMessageTrayId = 0;
+ }
+
+ if (this._messageTrayConstraint) {
+ Main.messageTray.remove_constraint(this._messageTrayConstraint);
+ this._messageTrayConstraint = null;
+ }
+ }
+
+ _alignMessageTray() {
+ if (!Main.messageTray)
+ return;
+
+ if (!this._message || !this._message.visible) {
+ this._resetMessageTray();
+ return;
+ }
+
+ if (this._updateMessageTrayId)
+ return;
+
+ this._updateMessageTrayId = global.stage.connect('before-update', () => {
+ if (!this._messageTrayConstraint) {
+ this._messageTrayConstraint = new HeadsUpConstraint({primary: true});
+
+ Main.layoutManager.panelBox.bind_property('visible',
+ this._messageTrayConstraint, 'active',
+ GObject.BindingFlags.SYNC_CREATE);
+
+ Main.messageTray.add_constraint(this._messageTrayConstraint);
+ }
+
+ const panelBottom = Main.layoutManager.panelBox.y + Main.layoutManager.panelBox.height;
+ const messageBottom = this._message.y + this._message.height;
+
+ this._messageTrayConstraint.offset = messageBottom - panelBottom;
+ global.stage.disconnect(this._updateMessageTrayId);
+ this._updateMessageTrayId = 0;
+ });
+ }
+
+ _resetLoginDialog() {
+ if (!Main.sessionMode.isGreeter)
+ return;
+
+ if (!Main.screenShield || !Main.screenShield._dialog)
+ return;
+
+ const dialog = Main.screenShield._dialog;
+
+ if (this._authPromptAllocatedId) {
+ dialog.disconnect(this._authPromptAllocatedId);
+ this._authPromptAllocatedId = 0;
+ }
+
+ if (this._updateLoginDialogId) {
+ global.stage.disconnect(this._updateLoginDialogId);
+ this._updateLoginDialogId = 0;
+ }
+
+ if (this._loginDialogConstraint) {
+ dialog.remove_constraint(this._loginDialogConstraint);
+ this._loginDialogConstraint = null;
+ }
+ }
+
+ _adaptLoginDialogForMessage() {
+ if (!Main.sessionMode.isGreeter)
+ return;
+
+ if (!Main.screenShield || !Main.screenShield._dialog)
+ return;
+
+ if (!this._message || !this._message.visible) {
+ this._resetLoginDialog();
+ return;
+ }
+
+ const dialog = Main.screenShield._dialog;
+
+ if (this._updateLoginDialogId)
+ return;
+
+ this._updateLoginDialogId = global.stage.connect('before-update', () => {
+ let messageHeight = this._message.y + this._message.height;
+ if (dialog._logoBin.visible)
+ messageHeight -= dialog._logoBin.height;
+
+ if (!this._logindDialogConstraint) {
+ this._loginDialogConstraint = new HeadsUpConstraint({primary: true});
+ dialog.add_constraint(this._loginDialogConstraint);
+ }
+
+ this._loginDialogConstraint.offset = messageHeight;
+
+ global.stage.disconnect(this._updateLoginDialogId);
+ this._updateLoginDialogId = 0;
+ });
+ }
+
+ _adaptSessionForMessage() {
+ this._alignMessageTray();
+
+ if (Main.sessionMode.isGreeter) {
+ this._adaptLoginDialogForMessage();
+ if (!this._authPromptAllocatedId) {
+ const dialog = Main.screenShield._dialog;
+ this._authPromptAllocatedId = dialog._authPrompt.connect('notify::allocation', this._adaptLoginDialogForMessage.bind(this));
+ }
+ }
+ }
+}
diff --git a/extensions/heads-up-display/headsUpMessage.js b/extensions/heads-up-display/headsUpMessage.js
new file mode 100644
index 00000000..30298847
--- /dev/null
+++ b/extensions/heads-up-display/headsUpMessage.js
@@ -0,0 +1,166 @@
+// SPDX-FileCopyrightText: 2021 Ray Strode <rstrode@redhat.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+import Atk from 'gi://Atk';
+import Clutter from 'gi://Clutter';
+import GObject from 'gi://GObject';
+import St from 'gi://St';
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+const HeadsUpMessageBodyLabel = GObject.registerClass({
+}, class HeadsUpMessageBodyLabel extends St.Label {
+ constructor(params) {
+ super(params);
+
+ this._widthCoverage = 0.75;
+ this._heightCoverage = 0.25;
+
+ global.display.connectObject('workareas-changed',
+ () => this._getWorkAreaAndMeasureLineHeight());
+ }
+
+ _getWorkAreaAndMeasureLineHeight() {
+ if (!this.get_parent())
+ return;
+
+ this._workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+
+ this.clutter_text.single_line_mode = true;
+ this.clutter_text.line_wrap = false;
+
+ this._lineHeight = super.vfunc_get_preferred_height(-1)[0];
+
+ this.clutter_text.single_line_mode = false;
+ this.clutter_text.line_wrap = true;
+ }
+
+ vfunc_parent_set() {
+ this._getWorkAreaAndMeasureLineHeight();
+ }
+
+ vfunc_get_preferred_width(forHeight) {
+ const maxWidth = this._widthCoverage * this._workArea.width;
+
+ let [labelMinimumWidth, labelNaturalWidth] = super.vfunc_get_preferred_width(forHeight);
+
+ labelMinimumWidth = Math.min(labelMinimumWidth, maxWidth);
+ labelNaturalWidth = Math.min(labelNaturalWidth, maxWidth);
+
+ return [labelMinimumWidth, labelNaturalWidth];
+ }
+
+ vfunc_get_preferred_height(forWidth) {
+ const labelHeightUpperBound = this._heightCoverage * this._workArea.height;
+ const numberOfLines = Math.floor(labelHeightUpperBound / this._lineHeight);
+ this._numberOfLines = Math.max(numberOfLines, 1);
+
+ const maxHeight = this._lineHeight * this._numberOfLines;
+
+ let [labelMinimumHeight, labelNaturalHeight] = super.vfunc_get_preferred_height(forWidth);
+
+ labelMinimumHeight = Math.min(labelMinimumHeight, maxHeight);
+ labelNaturalHeight = Math.min(labelNaturalHeight, maxHeight);
+
+ return [labelMinimumHeight, labelNaturalHeight];
+ }
+});
+
+export const HeadsUpMessage = GObject.registerClass({
+}, class HeadsUpMessage extends St.Button {
+ constructor(heading, body) {
+ super({
+ style_class: 'message',
+ accessible_role: Atk.Role.NOTIFICATION,
+ can_focus: false,
+ opacity: 0,
+ });
+
+ Main.layoutManager.addChrome(this, {affectsInputRegion: true});
+
+ this.add_style_class_name('heads-up-display-message');
+
+ this.connect('destroy', () => this._onDestroy());
+
+ Main.layoutManager.panelBox.connectObject('notify::allocation',
+ () => this._alignWithPanel());
+ this.connect('notify::allocation',
+ () => this._alignWithPanel());
+
+ const contentsBox = new St.BoxLayout({
+ style_class: 'heads-up-message-content',
+ vertical: true,
+ x_align: Clutter.ActorAlign.CENTER,
+ });
+ this.add_child(contentsBox);
+
+ this._headingLabel = new St.Label({
+ style_class: 'heads-up-message-heading',
+ x_expand: true,
+ x_align: Clutter.ActorAlign.CENTER,
+ });
+
+ this.setHeading(heading);
+ contentsBox.add_child(this._headingLabel);
+
+ this._bodyLabel = new HeadsUpMessageBodyLabel({
+ style_class: 'heads-up-message-body',
+ x_expand: true,
+ y_expand: true,
+ });
+ contentsBox.add_child(this._bodyLabel);
+
+ this.setBody(body);
+ }
+
+ vfunc_parent_set() {
+ this._alignWithPanel();
+ }
+
+ _alignWithPanel() {
+ if (this._beforeUpdateId)
+ return;
+
+ this._beforeUpdateId = global.stage.connect('before-update', () => {
+ let x = Main.panel.x;
+ let y = Main.panel.y + Main.panel.height;
+
+ x += Main.panel.width / 2;
+ x -= this.width / 2;
+ x = Math.floor(x);
+ this.set_position(x, y);
+ this.opacity = 255;
+
+ global.stage.disconnect(this._beforeUpdateId);
+ this._beforeUpdateId = 0;
+ });
+ }
+
+ setHeading(text) {
+ if (text) {
+ const heading = text ? text.replace(/\n/g, ' ') : '';
+ this._headingLabel.text = heading;
+ this._headingLabel.visible = true;
+ } else {
+ this._headingLabel.text = text;
+ this._headingLabel.visible = false;
+ }
+ }
+
+ setBody(text) {
+ this._bodyLabel.text = text;
+
+ if (text)
+ this._bodyLabel.visible = true;
+ else
+ this._bodyLabel.visible = false;
+ }
+
+ _onDestroy() {
+ if (this._beforeUpdateId) {
+ global.stage.disconnect(this._beforeUpdateId);
+ this._beforeUpdateId = 0;
+ }
+ }
+});
diff --git a/extensions/heads-up-display/meson.build b/extensions/heads-up-display/meson.build
new file mode 100644
index 00000000..42ce222c
--- /dev/null
+++ b/extensions/heads-up-display/meson.build
@@ -0,0 +1,13 @@
+# SPDX-FileCopyrightText: 2021 Ray Strode <rstrode@redhat.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
+
+extension_data += files('stylesheet.css')
+extension_sources += files('headsUpMessage.js', 'prefs.js')
+extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/heads-up-display/metadata.json.in b/extensions/heads-up-display/metadata.json.in
new file mode 100644
index 00000000..01bcd4df
--- /dev/null
+++ b/extensions/heads-up-display/metadata.json.in
@@ -0,0 +1,12 @@
+{
+"extension-id": "@extension_id@",
+"uuid": "@uuid@",
+"settings-schema": "@gschemaname@",
+"gettext-domain": "@gettext_domain@",
+"name": "Heads-up Display Message",
+"description": "Add a message to be displayed on screen always above all windows and chrome.",
+"original-authors": [ "rstrode@redhat.com" ],
+"shell-version": [ "@shell_current@" ],
+"url": "@url@",
+"session-modes": [ "gdm", "lock-screen", "unlock-dialog", "user" ]
+}
diff --git a/extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml b/extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml
new file mode 100644
index 00000000..1e2119c8
--- /dev/null
+++ b/extensions/heads-up-display/org.gnome.shell.extensions.heads-up-display.gschema.xml
@@ -0,0 +1,60 @@
+<!--
+SPDX-FileCopyrightText: 2021 Ray Strode <rstrode@redhat.com>
+
+SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<schemalist gettext-domain="gnome-shell-extensions">
+ <schema id="org.gnome.shell.extensions.heads-up-display"
+ path="/org/gnome/shell/extensions/heads-up-display/">
+ <key name="idle-timeout" type="u">
+ <default>30</default>
+ <summary>Idle Timeout</summary>
+ <description>
+ Number of seconds until message is reshown after user goes idle.
+ </description>
+ </key>
+ <key name="message-heading" type="s">
+ <default>""</default>
+ <summary>Message to show at top of display</summary>
+ <description>
+ The top line of the heads up display message.
+ </description>
+ </key>
+ <key name="message-body" type="s">
+ <default>""</default>
+ <summary>Banner message</summary>
+ <description>
+ A message to always show at the top of the screen.
+ </description>
+ </key>
+ <key name="show-on-login-screen" type="b">
+ <default>true</default>
+ <summary>Show on login screen</summary>
+ <description>
+ Whether or not the message should display on the login screen
+ </description>
+ </key>
+ <key name="show-when-locked" type="b">
+ <default>false</default>
+ <summary>Show on screen shield</summary>
+ <description>
+ Whether or not the message should display when the screen is locked
+ </description>
+ </key>
+ <key name="show-when-unlocking" type="b">
+ <default>false</default>
+ <summary>Show on unlock screen</summary>
+ <description>
+ Whether or not the message should display on the unlock screen.
+ </description>
+ </key>
+ <key name="show-when-unlocked" type="b">
+ <default>false</default>
+ <summary>Show in user session</summary>
+ <description>
+ Whether or not the message should display when the screen is unlocked.
+ </description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/extensions/heads-up-display/prefs.js b/extensions/heads-up-display/prefs.js
new file mode 100644
index 00000000..304c8813
--- /dev/null
+++ b/extensions/heads-up-display/prefs.js
@@ -0,0 +1,92 @@
+// SPDX-FileCopyrightText: 2021 Ray Strode <rstrode@redhat.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+import Adw from 'gi://Adw';
+import Gio from 'gi://Gio';
+import GObject from 'gi://GObject';
+import Gtk from 'gi://Gtk';
+
+import {ExtensionPreferences, gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
+
+class GeneralGroup extends Adw.PreferencesGroup {
+ static {
+ GObject.registerClass(this);
+ }
+
+ constructor(settings) {
+ super();
+
+ const actionGroup = new Gio.SimpleActionGroup();
+ this.insert_action_group('options', actionGroup);
+
+ actionGroup.add_action(settings.create_action('show-when-locked'));
+ actionGroup.add_action(settings.create_action('show-when-unlocking'));
+ actionGroup.add_action(settings.create_action('show-when-unlocked'));
+
+ this.add(new Adw.SwitchRow({
+ title: _('Show message when screen is locked'),
+ action_name: 'options.show-when-locked',
+ }));
+ this.add(new Adw.SwitchRow({
+ title: _('Show message on unlock screen'),
+ action_name: 'options.show-when-unlocking',
+ }));
+ this.add(new Adw.SwitchRow({
+ title: _('Show message when screen is unlocked'),
+ action_name: 'options.show-when-unlocked',
+ }));
+
+ const spinRow = new Adw.SpinRow({
+ title: _('Seconds after user goes idle before reshowing message'),
+ adjustment: new Gtk.Adjustment({
+ lower: 0,
+ upper: 2147483647,
+ step_increment: 1,
+ page_increment: 60,
+ page_size: 60,
+ }),
+ });
+ settings.bind('idle-timeout',
+ spinRow, 'value',
+ Gio.SettingsBindFlags.DEFAULT);
+ this.add(spinRow);
+ }
+}
+
+class MessageGroup extends Adw.PreferencesGroup {
+ static {
+ GObject.registerClass(this);
+ }
+
+ constructor(settings) {
+ super({
+ title: _('Message'),
+ });
+
+ const textView = new Gtk.TextView({
+ accepts_tab: false,
+ wrap_mode: Gtk.WrapMode.WORD,
+ top_margin: 6,
+ bottom_margin: 6,
+ left_margin: 6,
+ right_margin: 6,
+ vexpand: true,
+ });
+ textView.add_css_class('card');
+
+ settings.bind('message-body',
+ textView.get_buffer(), 'text',
+ Gio.SettingsBindFlags.DEFAULT);
+ this.add(textView);
+ }
+}
+
+export default class HeadsUpDisplayPrefs extends ExtensionPreferences {
+ getPreferencesWidget() {
+ const page = new Adw.PreferencesPage();
+ page.add(new GeneralGroup(this.getSettings()));
+ page.add(new MessageGroup(this.getSettings()));
+ return page;
+ }
+}
diff --git a/extensions/heads-up-display/stylesheet.css b/extensions/heads-up-display/stylesheet.css
new file mode 100644
index 00000000..a1a34e3f
--- /dev/null
+++ b/extensions/heads-up-display/stylesheet.css
@@ -0,0 +1,38 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Ray Strode <rstrode@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+.heads-up-display-message {
+ background-color: rgba(0.24, 0.24, 0.24, 0.80);
+ border: 1px solid black;
+ border-radius: 6px;
+ color: #eeeeec;
+ font-size: 11pt;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ padding: 0.9em;
+}
+
+.heads-up-display-message:insensitive {
+ background-color: rgba(0.24, 0.24, 0.24, 0.33);
+}
+
+.heads-up-display-message:hover {
+ background-color: rgba(0.24, 0.24, 0.24, 0.2);
+ border: 1px solid rgba(0.0, 0.0, 0.0, 0.5);
+ color: #4d4d4d;
+ transition-duration: 250ms;
+}
+
+.heads-up-message-heading {
+ height: 1.75em;
+ font-size: 1.25em;
+ font-weight: bold;
+ text-align: center;
+}
+
+.heads-up-message-body {
+ text-align: center;
+}
diff --git a/meson.build b/meson.build
index 0f12b451..da36032b 100644
--- a/meson.build
+++ b/meson.build
@@ -41,6 +41,7 @@ classic_extensions = [
default_extensions = classic_extensions
default_extensions += [
'drive-menu',
+ 'heads-up-display',
'light-style',
'screenshot-window-sizer',
'status-icons',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 447465a1..b7cb8a7c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -6,6 +6,7 @@ extensions/auto-move-windows/extension.js
extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml
extensions/auto-move-windows/prefs.js
extensions/drive-menu/extension.js
+extensions/heads-up-display/prefs.js
extensions/native-window-placement/extension.js
extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml
extensions/places-menu/extension.js
--
2.47.1

View File

@ -0,0 +1,719 @@
From 9eb73513d7d31fd193e15c53f79c7e3a6aee71da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 12 Jan 2023 19:43:52 +0100
Subject: [PATCH 4/5] Add custom-menu extension
---
extensions/custom-menu/config.js | 445 ++++++++++++++++++++++++
extensions/custom-menu/extension.js | 201 +++++++++++
extensions/custom-menu/meson.build | 7 +
extensions/custom-menu/metadata.json.in | 10 +
meson.build | 1 +
5 files changed, 664 insertions(+)
create mode 100644 extensions/custom-menu/config.js
create mode 100644 extensions/custom-menu/extension.js
create mode 100644 extensions/custom-menu/meson.build
create mode 100644 extensions/custom-menu/metadata.json.in
diff --git a/extensions/custom-menu/config.js b/extensions/custom-menu/config.js
new file mode 100644
index 00000000..d08e3201
--- /dev/null
+++ b/extensions/custom-menu/config.js
@@ -0,0 +1,445 @@
+import Gio from 'gi://Gio';
+import GLib from 'gi://GLib';
+import Json from 'gi://Json';
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
+
+import {getLogger} from './extension.js';
+
+class Entry {
+ constructor(prop) {
+ this.type = prop.type;
+ this.title = prop.title || "";
+ this.__vars = prop.__vars || [];
+ this.updateEnv(prop);
+ }
+
+ setTitle(text) {
+ this.item.label.get_clutter_text().set_text(text);
+ }
+
+ updateEnv(prop) {
+ this.__env = {}
+ if (!this.__vars) return;
+ for (let i in this.__vars) {
+ let v = this.__vars[i];
+ this.__env[v] = prop[v] ? String(prop[v]) : "";
+ }
+ }
+
+ // the pulse function should be read as "a pulse arrives"
+ pulse() {
+ }
+
+ _try_destroy() {
+ try {
+ if (this.item && this.item.destroy) {
+ this.item.destroy();
+ }
+ } catch(e) { /* Ignore all errors during destory*/ }
+ }
+}
+
+class DerivedEntry {
+ constructor(prop) {
+ if (!prop.base) {
+ throw new Error("Base entry not specified in type definition.");
+ }
+ this.base = prop.base;
+ this.vars = prop.vars || [];
+ delete prop.base;
+ delete prop.vars;
+ this.prop = prop;
+ }
+
+ createInstance(addit_prop) {
+ let cls = type_map[this.base];
+ if (!cls) {
+ throw new Error("Bad base class.");
+ }
+ if (cls.createInstance) {
+ throw new Error("Not allowed to derive from dervied types");
+ }
+ for (let rp in this.prop) {
+ addit_prop[rp] = this.prop[rp];
+ }
+ addit_prop.__vars = this.vars;
+ let instance = new cls(addit_prop);
+ return instance;
+ }
+}
+
+let __pipeOpenQueue = [];
+
+/* callback: function (stdout, stderr, exit_status) { } */
+function pipeOpen(cmdline, env, callback) {
+ if (cmdline === undefined || callback === undefined) {
+ return false;
+ }
+ realPipeOpen(cmdline, env, callback);
+ return true;
+} /**/
+
+function realPipeOpen(cmdline, env, callback) {
+ let user_cb = callback;
+ let proc;
+
+ function wait_cb(_, _res) {
+ let stdout_pipe = proc.get_stdout_pipe();
+ let stderr_pipe = proc.get_stderr_pipe();
+ let stdout_content;
+ let stderr_content;
+
+ // Only the first GLib.MAXINT16 characters are fetched for optimization.
+ stdout_pipe.read_bytes_async(GLib.MAXINT16, 0, null, function(osrc, ores) {
+ const decoder = new TextDecoder();
+ stdout_content = decoder.decode(stdout_pipe.read_bytes_finish(ores).get_data());
+ stdout_pipe.close(null);
+ stderr_pipe.read_bytes_async(GLib.MAXINT16, 0, null, function(esrc, eres) {
+ stderr_content = decoder.decode(stderr_pipe.read_bytes_finish(eres).get_data());
+ stderr_pipe.close(null);
+ user_cb(stdout_content, stderr_content, proc.get_exit_status());
+ });
+ });
+ }
+
+ if (user_cb) {
+ let _pipedLauncher = new Gio.SubprocessLauncher({
+ flags:
+ Gio.SubprocessFlags.STDERR_PIPE |
+ Gio.SubprocessFlags.STDOUT_PIPE
+ });
+ for (let key in env) {
+ _pipedLauncher.setenv(key, env[key], true);
+ }
+ proc = _pipedLauncher.spawnv(['bash', '-c', cmdline]);
+ proc.wait_async(null, wait_cb);
+ } else {
+ // Detached launcher is used to spawn commands that we are not concerned about its result.
+ let _detacLauncher = new Gio.SubprocessLauncher();
+ for (let key in env) {
+ _detacLauncher.setenv(key, env[key], true);
+ }
+ proc = _detacLauncher.spawnv(['bash', '-c', cmdline]);
+ }
+ getLogger().info("Spawned " + cmdline);
+ return proc.get_identifier();
+}
+
+function _generalSpawn(command, env, title) {
+ title = title || "Process";
+ pipeOpen(command, env, function(stdout, stderr, exit_status) {
+ if (exit_status != 0) {
+ log
+ getLogger().warning(stderr);
+ getLogger().notify("proc", title + " exited with status " + exit_status, stderr);
+ }
+ });
+}
+
+// Detect menu toggle on startup
+function _toggleDetect(command, env, object) {
+ pipeOpen(command, env, function(stdout, stderr, exit_status) {
+ if (exit_status == 0) {
+ object.item.setToggleState(true);
+ }
+ });
+} /**/
+
+function quoteShellArg(arg) {
+ arg = arg.replace(/'/g, "'\"'\"'");
+ return "'" + arg + "'";
+}
+
+/**
+ * This cache is used to reduce detector cost.
+ * Each time creating an item, it check if the result of this detector is cached,
+ * which prevent the togglers from running detector on each creation.
+ * This is useful especially in search mode.
+ */
+let _toggler_state_cache = { };
+
+class TogglerEntry extends Entry {
+ constructor(prop) {
+ super(prop);
+ this.command_on = prop.command_on || "";
+ this.command_off = prop.command_off || "";
+ this.detector = prop.detector || "";
+ this.auto_on = prop.auto_on || false;
+ this.notify_when = prop.notify_when || [];
+ // if the switch is manually turned off, auto_on is disabled.
+ this._manually_switched_off = false;
+ this.pulse(); // load initial state
+ }
+
+ createItem() {
+ this._try_destroy();
+ this.item = new PopupMenu.PopupSwitchMenuItem(this.title, false);
+ this.item.label.get_clutter_text().set_use_markup(true);
+ this.item.connect('toggled', this._onManuallyToggled.bind(this));
+ this._loadState();
+ _toggleDetect(this.detector, this.__env, this);
+ return this.item;
+ }
+
+ _onManuallyToggled(_, state) {
+ // when switched on again, this flag will get cleared.
+ this._manually_switched_off = !state;
+ this._storeState(state);
+ this._onToggled(state);
+ }
+
+ _onToggled(state) {
+ if (state) {
+ _generalSpawn(this.command_on, this.__env, this.title);
+ } else {
+ _generalSpawn(this.command_off, this.__env, this.title);
+ }
+ }
+
+ _detect(callback) {
+ // abort detecting if detector is an empty string
+ if (!this.detector) {
+ return;
+ }
+ pipeOpen(this.detector, this.__env, function(out) {
+ out = String(out);
+ callback(!Boolean(out.match(/^\s*$/)));
+ });
+ }
+
+ // compare the new state with cached state notify when state is different
+ compareState(new_state) {
+ let old_state = _toggler_state_cache[this.detector];
+ if (old_state === undefined) return;
+ if (old_state == new_state) return;
+
+ if (this.notify_when.indexOf(new_state ? "on" : "off") >= 0) {
+ let not_str = this.title + (new_state ? " started." : " stopped.");
+ if (!new_state && this.auto_on) {
+ not_str += " Attempt to restart it now.";
+ }
+ getLogger().notify("state", not_str);
+ }
+ }
+
+ _storeState(state) {
+ let hash = JSON.stringify({ env: this.__env, detector: this.detector });
+ _toggler_state_cache[hash] = state;
+ }
+
+ _loadState() {
+ let hash = JSON.stringify({ env: this.__env, detector: this.detector });
+ let state = _toggler_state_cache[hash];
+ if (state !== undefined) {
+ this.item.setToggleState(state); // doesn't emit 'toggled'
+ }
+ }
+
+ pulse() {
+ this._detect(state => {
+ this.compareState(state);
+ this._storeState(state);
+ this._loadState();
+ if (!state && !this._manually_switched_off && this.auto_on) {
+ // do not call setToggleState here, because command_on may fail
+ this._onToggled(this.item, true);
+ }
+ });
+ }
+
+ perform() {
+ this.item.toggle();
+ }
+}
+
+class LauncherEntry extends Entry {
+ constructor(prop) {
+ super(prop);
+ this.command = prop.command || "";
+ }
+
+ createItem() {
+ this._try_destroy();
+ this.item = new PopupMenu.PopupMenuItem(this.title);
+ this.item.label.get_clutter_text().set_use_markup(true);
+ this.item.connect('activate', this._onClicked.bind(this));
+ return this.item;
+ }
+
+ _onClicked(_) {
+ _generalSpawn(this.command, this.__env, this.title);
+ }
+
+ perform() {
+ this.item.emit('activate');
+ }
+}
+
+class SubMenuEntry extends Entry {
+ constructor(prop) {
+ super(prop);
+
+ if (prop.entries == undefined) {
+ throw new Error("Expected entries provided in submenu entry.");
+ }
+ this.entries = [];
+ for (let i in prop.entries) {
+ let entry_prop = prop.entries[i];
+ let entry = createEntry(entry_prop);
+ this.entries.push(entry);
+ }
+ }
+
+ createItem() {
+ this._try_destroy();
+ this.item = new PopupMenu.PopupSubMenuMenuItem(this.title);
+ this.item.label.get_clutter_text().set_use_markup(true);
+ for (let i in this.entries) {
+ let entry = this.entries[i];
+ this.item.menu.addMenuItem(entry.createItem());
+ }
+ return this.item;
+ }
+
+ pulse() {
+ for (let i in this.entries) {
+ let entry = this.entries[i];
+ entry.pulse();
+ }
+ }
+}
+
+class SeparatorEntry extends Entry {
+ createItem() {
+ this._try_destroy();
+ this.item = new PopupMenu.PopupSeparatorMenuItem(this.title);
+ this.item.label.get_clutter_text().set_use_markup(true);
+ return this.item;
+ }
+}
+
+let type_map = {};
+
+////////////////////////////////////////////////////////////////////////////////
+// Config Loader loads config from JSON file.
+
+// convert Json Nodes (GLib based) to native javascript value.
+function convertJson(node) {
+ if (node.get_node_type() == Json.NodeType.VALUE) {
+ return node.get_value();
+ }
+ if (node.get_node_type() == Json.NodeType.OBJECT) {
+ let obj = {}
+ node.get_object().foreach_member(function(_, k, v_n) {
+ obj[k] = convertJson(v_n);
+ });
+ return obj;
+ }
+ if (node.get_node_type() == Json.NodeType.ARRAY) {
+ let arr = []
+ node.get_array().foreach_element(function(_, i, elem) {
+ arr.push(convertJson(elem));
+ });
+ return arr;
+ }
+ return null;
+}
+
+//
+function createEntry(entry_prop) {
+ if (!entry_prop.type) {
+ throw new Error("No type specified in entry.");
+ }
+ let cls = type_map[entry_prop.type];
+ if (!cls) {
+ throw new Error("Incorrect type '" + entry_prop.type + "'");
+ } else if (cls.createInstance) {
+ return cls.createInstance(entry_prop);
+ }
+ return new cls(entry_prop);
+}
+
+export class Loader {
+ constructor(filename) {
+ if (filename) {
+ this.loadConfig(filename);
+ }
+ }
+
+ loadConfig(filename) {
+ // reset type_map everytime load the config
+ type_map = {
+ launcher: LauncherEntry,
+ toggler: TogglerEntry,
+ submenu: SubMenuEntry,
+ separator: SeparatorEntry
+ };
+
+ type_map.systemd = new DerivedEntry({
+ base: 'toggler',
+ vars: ['unit'],
+ command_on: "pkexec systemctl start ${unit}",
+ command_off: "pkexec systemctl stop ${unit}",
+ detector: "systemctl status ${unit} | grep Active:\\\\s\\*activ[ei]",
+ });
+
+ type_map.tmux = new DerivedEntry({
+ base: 'toggler',
+ vars: ['command', 'session'],
+ command_on: 'tmux new -d -s ${session} bash -c "${command}"',
+ command_off: 'tmux kill-session -t ${session}',
+ detector: 'tmux has -t "${session}" 2>/dev/null && echo yes',
+ });
+
+ /*
+ * Refer to README file for detailed config file format.
+ */
+ this.entries = []; // CAUTION: remove all entries.
+
+ let config_parser = new Json.Parser();
+ config_parser.load_from_file(filename);
+ let conf = convertJson(config_parser.get_root());
+ if (conf.entries == undefined) {
+ throw new Error("Key 'entries' not found.");
+ }
+ if (conf.deftype) {
+ for (let tname in conf.deftype) {
+ if (type_map[tname]) {
+ throw new Error("Type \""+tname+"\" duplicated.");
+ }
+ type_map[tname] = new DerivedEntry(conf.deftype[tname]);
+ }
+ }
+
+ for (let conf_i in conf.entries) {
+ let entry_prop = conf.entries[conf_i];
+ this.entries.push(createEntry(entry_prop));
+ }
+ }
+
+ saveDefaultConfig(filename) {
+ // Write default config
+ const PERMISSIONS_MODE = 0o640;
+ const jsonString = JSON.stringify({
+ "_homepage_": "https://github.com/andreabenini/gnome-plugin.custom-menu-panel",
+ "_examples_": "https://github.com/andreabenini/gnome-plugin.custom-menu-panel/tree/main/examples",
+ "entries": [ {
+ "type": "launcher",
+ "title": "Edit menu",
+ "command": "gedit $HOME/.entries.json"
+ } ]
+ }, null, 4);
+ let fileConfig = Gio.File.new_for_path(filename);
+ if (GLib.mkdir_with_parents(fileConfig.get_parent().get_path(), PERMISSIONS_MODE) === 0) {
+ fileConfig.replace_contents(jsonString, null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, null);
+ }
+ // Try to load newly saved file
+ try {
+ this.loadConfig(filename);
+ } catch(e) {
+ Main.notify(_('Cannot create and load file: '+filename));
+ }
+ }
+}
diff --git a/extensions/custom-menu/extension.js b/extensions/custom-menu/extension.js
new file mode 100644
index 00000000..9edbc548
--- /dev/null
+++ b/extensions/custom-menu/extension.js
@@ -0,0 +1,201 @@
+/* extension.js
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * @author Ben
+ * @see https://github.com/andreabenini/gnome-plugin.custom-menu-panel
+ */
+
+const CONFIGURATION_FILE = '/.entries.json';
+
+import Gio from 'gi://Gio';
+import GLib from 'gi://GLib';
+import GObject from 'gi://GObject';
+import St from 'gi://St';
+
+import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+import * as BackgroundMenu from 'resource:///org/gnome/shell/ui/backgroundMenu.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 Config from './config.js';
+
+const LOGGER_INFO = 0;
+const LOGGER_WARNING = 1;
+const LOGGER_ERROR = 2;
+
+const {BackgroundMenu: OriginalBackgroundMenu} = BackgroundMenu;
+
+
+class CustomMenu extends PopupMenu.PopupMenu {
+ constructor(sourceActor) {
+ super(sourceActor, 0.0, St.Side.TOP, 0);
+
+ this._loadSetup();
+ }
+
+ /**
+ * LOAD Program settings from .entries.json file
+ */
+ _loadSetup() {
+ this.removeAll();
+ // Loading configuration from file
+ this.configLoader = new Config.Loader();
+ try {
+ this.configLoader.loadConfig(GLib.get_home_dir() + CONFIGURATION_FILE); // $HOME/.entries.json
+ } catch(e) {
+ this.configLoader.saveDefaultConfig(GLib.get_home_dir() + CONFIGURATION_FILE); // create default entries
+ }
+ // Build the menu
+ let i = 0;
+ for (let i in this.configLoader.entries) {
+ let item = this.configLoader.entries[i].createItem();
+ this.addMenuItem(item);
+ }
+ } /**/
+}
+
+class CustomBackgroundMenu extends CustomMenu {
+ constructor(layoutManager) {
+ super(layoutManager.dummyCursor);
+
+ this.actor.add_style_class_name('background-menu');
+
+ layoutManager.uiGroup.add_actor(this.actor);
+ this.actor.hide();
+
+ this.connect('open-state-changed', (menu, open) => {
+ if (open)
+ this._updateMaxHeight();
+ });
+ }
+
+ _updateMaxHeight() {
+ const monitor = Main.layoutManager.findMonitorForActor(this.actor);
+ const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
+ const {scaleFactor} = St.ThemeContext.get_for_stage(global.stage);
+ const vMargins = this.actor.margin_top + this.actor.margin_bottom;
+ const {y: offsetY} = this.sourceActor;
+
+ const maxHeight = Math.round((monitor.height - offsetY - vMargins) / scaleFactor);
+ this.actor.style = `max-height: ${maxHeight}px;`;
+ }
+}
+
+const Indicator = GObject.registerClass(
+ class Indicator extends PanelMenu.Button {
+ _init() {
+ super._init(0.0, _('Custom Menu Panel Indicator'), true);
+ this.add_child(new St.Icon({
+ icon_name: 'view-list-bullet-symbolic',
+ style_class: 'system-status-icon',
+ }));
+
+ this.setMenu(new CustomMenu(this));
+ }
+ }
+); /**/
+
+
+class Logger {
+ constructor(log_file) {
+ this._log_file = log_file;
+ // initailize log_backend
+ if (!log_file) {
+ this._initEmptyLog();
+ } else if(log_file == "gnome-shell") {
+ this._initGnomeLog();
+ } else {
+ this._initFileLog();
+ }
+ this.level = LOGGER_WARNING;
+ this.info = function(t) {
+ if (this.level <= LOGGER_INFO) {
+ this.log(t);
+ }
+ };
+ this.warning = function(t) {
+ if (this.level <= LOGGER_WARNING) {
+ this.log(t);
+ }
+ };
+ this.error = function(t) {
+ if (this.level <= LOGGER_ERROR) {
+ this.log(t);
+ }
+ };
+ }
+
+ _initEmptyLog() {
+ this.log = function(_) { };
+ }
+
+ _initGnomeLog() {
+ this.log = function(s) {
+ global.log("custom-menu-panel> " + s);
+ };
+ }
+
+ _initFileLog() {
+ this.log = function(s) {
+ // all operations are synchronous: any needs to optimize?
+ if (!this._output_file || !this._output_file.query_exists(null) || !this._fstream || this._fstream.is_closed()) {
+ this._output_file = Gio.File.new_for_path(this._log_file);
+ this._fstream = this._output_file.append_to(Gio.FileCreateFlags.NONE, null);
+ if (!this._fstream instanceof Gio.FileIOStream) {
+ this._initGnomeLog();
+ this.log("IOError: Failed to append to " + this._log_file + " [Gio.IOErrorEnum:" + this._fstream + "]");
+ return;
+ }
+ }
+ this._fstream.write(String(new Date())+" "+s+"\n", null);
+ this._fstream.flush(null);
+ }
+ }
+
+ notify(t, str, details) {
+ this.ncond = this.ncond || ['proc', 'ext', 'state'];
+ if (this.ncond.indexOf(t) < 0) {
+ return;
+ }
+ Main.notify(str, details || "");
+ }
+}
+
+// lazy-evaluation
+let logger = null;
+export function getLogger() {
+ if (logger === null) {
+ logger = new Logger("gnome-shell");
+ }
+ return logger;
+} /**/
+
+export default class CustomMenuExtension extends Extension {
+ enable() {
+ BackgroundMenu.BackgroundMenu = CustomBackgroundMenu;
+ Main.layoutManager._updateBackgrounds();
+ }
+
+ disable() {
+ BackgroundMenu.BackgroundMenu = OriginalBackgroundMenu;
+ Main.layoutManager._updateBackgrounds();
+ }
+} /**/
diff --git a/extensions/custom-menu/meson.build b/extensions/custom-menu/meson.build
new file mode 100644
index 00000000..92450963
--- /dev/null
+++ b/extensions/custom-menu/meson.build
@@ -0,0 +1,7 @@
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
+
+extension_sources += files('config.js')
diff --git a/extensions/custom-menu/metadata.json.in b/extensions/custom-menu/metadata.json.in
new file mode 100644
index 00000000..054f639b
--- /dev/null
+++ b/extensions/custom-menu/metadata.json.in
@@ -0,0 +1,10 @@
+{
+"extension-id": "@extension_id@",
+"uuid": "@uuid@",
+"settings-schema": "@gschemaname@",
+"gettext-domain": "@gettext_domain@",
+"name": "Custom menu",
+"description": "Quick custom menu for launching your favorite applications",
+"shell-version": [ "@shell_current@" ],
+"url": "@url@"
+}
diff --git a/meson.build b/meson.build
index da36032b..175cc73f 100644
--- a/meson.build
+++ b/meson.build
@@ -54,6 +54,7 @@ all_extensions = default_extensions
all_extensions += [
'auto-move-windows',
'classification-banner',
+ 'custom-menu',
'gesture-inhibitor',
'native-window-placement',
'user-theme',
--
2.47.1

View File

@ -0,0 +1,72 @@
From d0f2273765ab61e55c5cf10e7283a545fcafa947 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 22 Aug 2024 13:24:20 +0200
Subject: [PATCH] Add stub desktop-icons extension
---
extensions/desktop-icons/extension.js | 5 +++++
extensions/desktop-icons/meson.build | 9 +++++++++
extensions/desktop-icons/metadata.json.in | 10 ++++++++++
meson.build | 1 +
4 files changed, 25 insertions(+)
create mode 100644 extensions/desktop-icons/extension.js
create mode 100644 extensions/desktop-icons/meson.build
create mode 100644 extensions/desktop-icons/metadata.json.in
diff --git a/extensions/desktop-icons/extension.js b/extensions/desktop-icons/extension.js
new file mode 100644
index 00000000..bbc96ef2
--- /dev/null
+++ b/extensions/desktop-icons/extension.js
@@ -0,0 +1,5 @@
+// SPDX-FileCopyrightText: 2024 Florian Müllner <fmuellner@gnome.org>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+export {Extension as default} from 'resource:///org/gnome/shell/extensions/extension.js';
diff --git a/extensions/desktop-icons/meson.build b/extensions/desktop-icons/meson.build
new file mode 100644
index 00000000..7b28a2ef
--- /dev/null
+++ b/extensions/desktop-icons/meson.build
@@ -0,0 +1,9 @@
+# SPDX-FileCopyrightText: 2017 Florian Müllner <fmuellner@gnome.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+extension_data += configure_file(
+ input: metadata_name + '.in',
+ output: metadata_name,
+ configuration: metadata_conf
+)
diff --git a/extensions/desktop-icons/metadata.json.in b/extensions/desktop-icons/metadata.json.in
new file mode 100644
index 00000000..78a55abb
--- /dev/null
+++ b/extensions/desktop-icons/metadata.json.in
@@ -0,0 +1,10 @@
+{
+"extension-id": "@extension_id@",
+"uuid": "@uuid@",
+"settings-schema": "@gschemaname@",
+"gettext-domain": "@gettext_domain@",
+"name": "Desktop Icons",
+"description": "Show icons on the desktop",
+"shell-version": [ "@shell_current@" ],
+"url": "@url@"
+}
diff --git a/meson.build b/meson.build
index b915b68c..63a7432e 100644
--- a/meson.build
+++ b/meson.build
@@ -40,6 +40,7 @@ classic_extensions = [
default_extensions = classic_extensions
default_extensions += [
+ 'desktop-icons',
'drive-menu',
'heads-up-display',
'light-style',
--
2.45.2

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: desktop-qe.desktop-ci.tier1-gating.functional}

422
gnome-shell-extensions.spec Normal file
View File

@ -0,0 +1,422 @@
# Minimum GNOME Shell version supported
%global min_gs_version %%(cut -d "." -f 1 <<<%{version})
%global pkg_prefix gnome-shell-extension
%global tarball_version %%(echo %{version} | tr '~' '.')
%global major_version %%(cut -d "." -f 1 <<<%{tarball_version})
%if 0%{?rhel}
%global xsession 0
%else
%global xsession 1
%endif
Name: gnome-shell-extensions
Version: 47.2
Release: %autorelease
Summary: Modify and extend GNOME Shell functionality and behavior
License: GPL-2.0-or-later
URL: http://wiki.gnome.org/Projects/GnomeShell/Extensions
Source0: http://ftp.gnome.org/pub/GNOME/sources/%{name}/%{major_version}/%{name}-%{tarball_version}.tar.xz
BuildRequires: meson
BuildRequires: git
BuildRequires: gettext >= 0.19.6
BuildRequires: glib2%{?_isa}
Requires: gnome-shell >= %{min_gs_version}
BuildArch: noarch
Patch: extra-extensions-0001-Add-gesture-inhibitor-extension.patch
Patch: extra-extensions-0002-Add-classification-banner.patch
Patch: extra-extensions-0003-Add-heads-up-display.patch
Patch: extra-extensions-0004-Add-custom-menu-extension.patch
Patch: extra-extensions-0005-Add-desktop-icons-extension.patch
Patch: 0001-Include-status-icons-in-classic-session.patch
Patch: window-list-reordering.patch
%description
GNOME Shell Extensions is a collection of extensions providing additional and
optional functionality to GNOME Shell.
Enabled extensions:
* apps-menu
* auto-move-windows
* classification-banner
* custom-menu
* desktop-icons
* drive-menu
* gesture-inhibitor
* heads-up-display
* launch-new-instance
* light-style
* native-window-placement
* places-menu
* screenshot-window-sizer
* status-icons
* system-monitor
* user-theme
* window-list
* windowsNavigator
* workspace-indicator
%package -n %{pkg_prefix}-common
Summary: Files common to GNOME Shell Extensions
License: GPL-2.0-or-later
Requires: gnome-shell >= %{min_gs_version}
Obsoletes: %{pkg_prefix}-horizontal-workspaces < 40.0~alpha.1-3
%description -n %{pkg_prefix}-common
GNOME Shell Extensions is a collection of extensions providing additional and
optional functionality to GNOME Shell.
This package provides common data files shared by various extensions.
%package -n gnome-classic-session
Summary: GNOME "classic" mode session
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-apps-menu = %{version}-%{release}
Requires: %{pkg_prefix}-launch-new-instance = %{version}-%{release}
Requires: %{pkg_prefix}-places-menu = %{version}-%{release}
Requires: %{pkg_prefix}-window-list = %{version}-%{release}
Requires: nautilus
%description -n gnome-classic-session
This package contains the required components for the GNOME Shell "classic"
mode, which aims to provide a GNOME 2-like user interface.
%if %{xsession}
%package -n gnome-classic-session-xsession
Summary: GNOME "classic" mode session on X11
License: GPL-2.0-or-later
Requires: gnome-classic-session = %{version}-%{release}
# The X11 session is deprecated and eventually will be removed
Provides: deprecated()
%description -n gnome-classic-session-xsession
This package contains the required components for the GNOME Shell "classic"
mode on X11, which aims to provide a GNOME 2-like user interface.
%endif
%package -n %{pkg_prefix}-apps-menu
Summary: Application menu for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
Requires: gnome-menus
%description -n %{pkg_prefix}-apps-menu
This GNOME Shell extension adds a GNOME 2.x style menu for applications.
%package -n %{pkg_prefix}-auto-move-windows
Summary: Assign specific workspaces to applications in GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-auto-move-windows
This GNOME Shell extension enables easy workspace management. A specific
workspace can be assigned to each application as soon as it creates a window, in
a manner configurable with a GSettings key.
%package -n %{pkg_prefix}-classification-banner
Summary: Display classification level banner in GNOME Shell
Group: User Interface/Desktops
License: GPLv2+
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-classification-banner
This GNOME Shell extension adds a banner that displays the classification level.
%package -n %{pkg_prefix}-custom-menu
Summary: Add a custom menu to the desktop
Group: User Interface/Desktops
License: GPLv2+
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-custom-menu
This GNOME Shell extension adds a custom menu to the desktop background.
%package -n %{pkg_prefix}-desktop-icons
Summary: Desktop icons support for GNOME Shell (stub)
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-desktop-icons
This GNOME Shell extension provides support for icons on the desktop.
%package -n %{pkg_prefix}-drive-menu
Summary: Drive status menu for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-drive-menu
This GNOME Shell extension provides a panel status menu for accessing and
unmounting removable devices.
%package -n %{pkg_prefix}-gesture-inhibitor
Summary: Gesture inhibitor
Group: User Interface/Desktops
License: GPLv2+
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-gesture-inhibitor
This GNOME Shell extension allows disabling the default desktop gestures.
%package -n %{pkg_prefix}-heads-up-display
Summary: Display persistent on-screen message
Group: User Interface/Desktops
License: GPLv3+
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-heads-up-display
This GNOME Shell extension displays a persistent message in the top middle of the screen.
This message can appear on the login screen, lock screen, or regular user session.
%package -n %{pkg_prefix}-launch-new-instance
Summary: Always launch a new application instance for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-launch-new-instance
This GNOME Shell extension modifies the behavior of clicking in the dash and app
launcher to always launch a new application instance.
%package -n %{pkg_prefix}-light-style
Summary: Use light style in GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-light-style
This GNOME Shell extension changes the default style to light.
%package -n %{pkg_prefix}-native-window-placement
Summary: Native window placement for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-native-window-placement
This GNOME Shell extension provides additional configurability for the window
layout in the overview, including a mechanism similar to KDE4.
%package -n %{pkg_prefix}-places-menu
Summary: Places status menu for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-places-menu
This GNOME Shell extension add a system status menu for quickly navigating
places in the system.
%package -n %{pkg_prefix}-screenshot-window-sizer
Summary: Screenshot window sizer for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-screenshot-window-sizer
This GNOME Shell extension allows to easily resize windows for GNOME Software
screenshots.
%package -n %{pkg_prefix}-status-icons
Summary: Status icon support for GNOME Shell
License: GPLv2+
Requires: %{pkg_prefix}-common = %{version}-%{release}
Provides: %{pkg_prefix}-top-icons = %{version}-%{release}
Obsoletes: %{pkg_prefix}-top-icons < 47~beta-1
%description -n %{pkg_prefix}-status-icons
This GNOME Shell extension displays status icons in the top bar.
%package -n %{pkg_prefix}-system-monitor
Summary: System monitor for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-system-monitor
This GNOME Shell extension displays system usage information in the top bar.
%package -n %{pkg_prefix}-user-theme
Summary: Support for custom themes in GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-user-theme
This GNOME Shell extension enables loading a GNOME Shell theme from
~/.themes/<name>/gnome-shell/.
%package -n %{pkg_prefix}-window-list
Summary: Display a window list at the bottom of the screen in GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-window-list
This GNOME Shell extension displays a window list at the bottom of the screen.
%package -n %{pkg_prefix}-windowsNavigator
Summary: Support for keyboard selection of windows and workspaces in GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-windowsNavigator
This GNOME Shell extension enables keyboard selection of windows and workspaces
in overlay mode, by pressing the Alt and Ctrl key respectively.
%package -n %{pkg_prefix}-workspace-indicator
Summary: Workspace indicator for GNOME Shell
License: GPL-2.0-or-later
Requires: %{pkg_prefix}-common = %{version}-%{release}
%description -n %{pkg_prefix}-workspace-indicator
This GNOME Shell extension add a system status menu for quickly changing
workspaces.
%prep
%autosetup -S git -n %{name}-%{tarball_version}
%build
%meson -Dextension_set="all" -Dclassic_mode=true
%meson_build
%install
%meson_install
%find_lang %{name}
%if !%{xsession}
rm -rf %{buildroot}/%{_datadir}/xsessions
%endif
%files -n %{pkg_prefix}-common -f %{name}.lang
%doc NEWS README.md
%license COPYING
%files -n gnome-classic-session
%{_datadir}/gnome-shell/modes/classic.json
%{_datadir}/wayland-sessions/gnome-classic.desktop
%{_datadir}/wayland-sessions/gnome-classic-wayland.desktop
%{_datadir}/glib-2.0/schemas/00_org.gnome.shell.extensions.classic.gschema.override
%if %{xsession}
%files -n gnome-classic-session-xsession
%{_datadir}/xsessions/gnome-classic.desktop
%{_datadir}/xsessions/gnome-classic-xorg.desktop
%endif
%files -n %{pkg_prefix}-apps-menu
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.apps-menu.gschema.xml
%{_datadir}/gnome-shell/extensions/apps-menu*/
%files -n %{pkg_prefix}-auto-move-windows
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.auto-move-windows.gschema.xml
%{_datadir}/gnome-shell/extensions/auto-move-windows*/
%files -n %{pkg_prefix}-classification-banner
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.classification-banner.gschema.xml
%{_datadir}/gnome-shell/extensions/classification-banner*/
%files -n %{pkg_prefix}-custom-menu
%{_datadir}/gnome-shell/extensions/custom-menu*/
%files -n %{pkg_prefix}-desktop-icons
%{_datadir}/gnome-shell/extensions/desktop-icons*/
%files -n %{pkg_prefix}-drive-menu
%{_datadir}/gnome-shell/extensions/drive-menu*/
%files -n %{pkg_prefix}-gesture-inhibitor
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.gesture-inhibitor.gschema.xml
%{_datadir}/gnome-shell/extensions/gesture-inhibitor*/
%files -n %{pkg_prefix}-heads-up-display
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.heads-up-display.gschema.xml
%{_datadir}/gnome-shell/extensions/heads-up-display*/
%files -n %{pkg_prefix}-launch-new-instance
%{_datadir}/gnome-shell/extensions/launch-new-instance*/
%files -n %{pkg_prefix}-light-style
%{_datadir}/gnome-shell/extensions/light-style*/
%files -n %{pkg_prefix}-native-window-placement
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.native-window-placement.gschema.xml
%{_datadir}/gnome-shell/extensions/native-window-placement*/
%files -n %{pkg_prefix}-places-menu
%{_datadir}/gnome-shell/extensions/places-menu*/
%files -n %{pkg_prefix}-screenshot-window-sizer
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml
%{_datadir}/gnome-shell/extensions/screenshot-window-sizer*/
%files -n %{pkg_prefix}-status-icons
%{_datadir}/gnome-shell/extensions/status-icons*/
%files -n %{pkg_prefix}-system-monitor
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.system-monitor.gschema.xml
%{_datadir}/gnome-shell/extensions/system-monitor*/
%files -n %{pkg_prefix}-user-theme
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.user-theme.gschema.xml
%{_datadir}/gnome-shell/extensions/user-theme*/
%files -n %{pkg_prefix}-window-list
%{_datadir}/gnome-shell/extensions/window-list*/
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.window-list.gschema.xml
%files -n %{pkg_prefix}-windowsNavigator
%{_datadir}/gnome-shell/extensions/windowsNavigator*/
%files -n %{pkg_prefix}-workspace-indicator
%{_datadir}/gnome-shell/extensions/workspace-indicator*/
%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.workspace-indicator.gschema.xml
%changelog
%autochangelog

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (gnome-shell-extensions-47.2.tar.xz) = 5049bce8f7a90d32da9e1e3c7586a14cb23bf1b259e302002b89de48db547b51bcff3935a489db3c57b2c30e948f6897426c661043630c335c248e5883816d83

1288
window-list-reordering.patch Normal file

File diff suppressed because it is too large Load Diff