Compare commits
No commits in common. "c8" and "c10s" have entirely different histories.
185
.gitignore
vendored
185
.gitignore
vendored
@ -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
|
||||
|
@ -1 +0,0 @@
|
||||
51c1c16bcd0dc9125834b32d7c539c38fa9c4f52 SOURCES/gnome-shell-extensions-3.32.1.tar.xz
|
32
0001-Include-status-icons-in-classic-session.patch
Normal file
32
0001-Include-status-icons-in-classic-session.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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(`Couldn’t 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(`Couldn’t 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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
@ -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
700
changelog
Normal 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
|
187
extra-extensions-0001-Add-gesture-inhibitor-extension.patch
Normal file
187
extra-extensions-0001-Add-gesture-inhibitor-extension.patch
Normal 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
|
||||
|
479
extra-extensions-0002-Add-classification-banner.patch
Normal file
479
extra-extensions-0002-Add-classification-banner.patch
Normal 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
|
||||
|
878
extra-extensions-0003-Add-heads-up-display.patch
Normal file
878
extra-extensions-0003-Add-heads-up-display.patch
Normal 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
|
||||
|
719
extra-extensions-0004-Add-custom-menu-extension.patch
Normal file
719
extra-extensions-0004-Add-custom-menu-extension.patch
Normal 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
|
||||
|
72
extra-extensions-0005-Add-desktop-icons-extension.patch
Normal file
72
extra-extensions-0005-Add-desktop-icons-extension.patch
Normal 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
6
gating.yaml
Normal 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
422
gnome-shell-extensions.spec
Normal 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
1
sources
Normal file
@ -0,0 +1 @@
|
||||
SHA512 (gnome-shell-extensions-47.2.tar.xz) = 5049bce8f7a90d32da9e1e3c7586a14cb23bf1b259e302002b89de48db547b51bcff3935a489db3c57b2c30e948f6897426c661043630c335c248e5883816d83
|
1288
window-list-reordering.patch
Normal file
1288
window-list-reordering.patch
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user